LCD1602 (HD44780)
Synthèse finale : Aout 2014.
Cet afficheur LCD est très pratique, fiable, esthétique, dont la luminosité et le contraste sont réglable.
Vendu tel quel, il y a 16 bornes à souder, mais pour un usage « simple » seul 10 bornes suffisent.
En définitive, je ne l'utilise plus qu'avec un arduino (mini pro).
Il coûte présentement 1,48€ livré sur Ebay.
Borne |
Symbole |
Type |
Fonction |
---|---|---|---|
1 |
Vss |
Alim |
Masse 0V |
2 |
Vcc |
Alim |
Alimentation générale 5V |
3 |
Vee |
Alim |
Alimentation du panneau LCD (Contraste des caractères) VLCD = VDD – V0 V0 = VDD → VLCD = 0 → Caractères invisibles V0 = 0 → VLCD = VDD → Contraste maximum |
4 |
RS |
Entrée |
RS = 1 → Sélection du registre de données RS = 0 et R/W = 1 → Sélection du registre d’instruction RS = 0 et R/W = 0 → Sélection du drapeau BUSY et du compteur d’adresse |
5 |
R/W |
Entrée |
R/W = 0 → Mode écriture R/W = 1 → Mode lecture |
6 |
E |
Entrée |
Entrée de validation Les entrées RS et R/W sont lues sur le front montant, et le bus de données est lu sur le front descendant. |
7 |
D0 |
Entrée/Sortie |
Bus de données, bit n°0 (LSB) |
8 |
D1 |
Entrée/Sortie |
Bus de données, bit n°1 |
9 |
D2 |
Entrée/Sortie |
Bus de données, bit n°2 |
10 |
D3 |
Entrée/Sortie |
Bus de données, bit n°3 |
11 |
D4 |
Entrée/Sortie |
Bus de données, bit n°4 |
12 |
D5 |
Entrée/Sortie |
Bus de données, bit n°5 |
13 |
D6 |
Entrée/Sortie |
Bus de données, bit n°6 |
14 |
D7 |
Entrée/Sortie |
Bus de données, bit n°7 (MSB) |
15 |
A |
Alim |
Anode du système de rétro-éclairage (à alimenter en 5V à travers une résistance de 50 à 100Ω pour limiter le courant à 100mA) |
16 |
K |
Alim |
Cathode du système de rétro-éclairage (masse) |
Dans ce mode, l’octet contenant les données est envoyé à l'afficheur (ou lu par l'afficheur) directement sur les broches D0 à D7.
Dans ce mode, on n’utilise que les broches D4 à D7, les broches D0 à D3 doivent être connectées à la masse.
L’octet de données est envoyé (ou lu) en 2 fois :
d’abord les 4 bits de poids fort, par une première validation sur la broche E,
puis les 4 bits de poids faible, par une première validation sur la broche E.
Instructions |
RS |
R/W |
DB7 |
DB6 |
DB5 |
DB4 |
DB3 |
DB2 |
DB1 |
DB0 |
Description |
Durée |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Clear display |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
Efface l'écran Place le curseur dans la position d'origine (1ère position à gauche, 1ère ligne : compteur d'adresse à 00h) |
> 1.64 ms |
Return home |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
- |
Place le curseur dans la position d'origine (1ère position à gauche, 1ère ligne : compteur d'adresse à 00h) |
> 1.64 ms |
Entry set mode |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
I/D |
S |
I/D = 1 → Déplacement du curseur d'une position à droite (Incrémentation du compteur d'adresse) I/D = 0 → Déplacement du curseur d'une
position à gauche (Décrémentation du
compteur d'adresse) |
> 40 µs |
Display on/off control |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
D |
C |
B |
D = 1 → Affichage visible D = 0 → Affichage invisible |
> 40 µs |
Cursor or display shift |
0 |
0 |
0 |
0 |
0 |
1 |
S/C |
R/L |
- |
- |
S/C = 1 → Décalage de l'affichage S/C = 0 → Déplacement du curseur |
> 40 µs |
Function set |
0 |
0 |
0 |
0 |
1 |
DL |
N |
F |
- |
- |
DL = 1 → Interface 8 bits DL = 0 → Interface 4 bits |
> 40 µs |
Set CGRAM address |
0 |
0 |
0 |
1 |
ACG5 |
ACG4 |
ACG3 |
ACG2 |
ACG1 |
ACG0 |
Positionne le compteur d'adresse de la CGRAM à la valeur (ACG5 ... ACG0) |
> 40 µs |
Set DDRAM address |
0 |
0 |
1 |
ADD6 |
ADD5 |
ADD4 |
ADD3 |
ADD2 |
ADD1 |
ADD0 |
Positionne le compteur d'adresse de la DDRAM (ADD5 ... ADD0) |
> 40 µs |
Read busy & address |
0 |
1 |
BF |
AC6 |
AC5 |
AC4 |
AC3 |
AC2 |
AC1 |
AC0 |
Lit le drapeau BF (Busy Flag) et le compteur d'adresse (AC6 ... AC0) BF = 1 → Le contrôleur est occupé
et n’accepte aucune nouvelle instruction |
> 1 µs |
Write data to CGRAM or DDRAM |
1 |
0 |
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
Write data to CGRAM : écrit la donnée (D7 ... D0) à l'adresse de la CGRAM définie par l'instruction précédente Set CGRAM address Write data to DDRAM : écrit la donnée (D7 ... D0) à l'adresse de la DDRAM définie par l'instruction précédente Set DDRAM address |
> 43 µs |
Read data to CGRAM or DDRAM |
1 |
1 |
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
Read data from CGRAM : lit la donnée (D7 ... D0) à l'adresse de la CGRAM définie par l'instruction précédente Set CGRAM address Read data from DDRAM : lit la donnée (D7 ... D0) à l'adresse de la DDRAM définie par l'instruction précédente Set DDRAM address |
> 43 µs |
Attendre au moins 15ms depuis le passage à +5V de Vcc,
Envoyer l'instruction Function set avec la valeur 0011XXXX,
Attendre au moins 4.1ms,
Envoyer à nouveau l'instruction Function set avec la valeur 0011XXXX,
Attendre au moins 100µs,
Envoyer à nouveau l'instruction Function set avec la valeur 0011XXXX,
Si on veut activer le mode 4 bits, envoyer les 4 bits de poids fort de l'instruction Function set avec la valeur 0010,
Configuration du nombre de lignes et de la matrice, en envoyant l'Instruction Function set avec par exemple la valeur 00111000 (8 bits, 2 lignes, 5x8pixels),
Configuration du contrôle d'affichage, en envoyant l'instruction Display on/off control avec par exemple la valeur 00001100 (Affichage visible, curseur visible, curseur fixe),
Effacement de l'écran, en envoyant l'instruction Clear display, avec pour valeur 00000001,
Configuration du curseur, en envoyant l'instruction Entry set mode, avec par exemple pour valeur 00000110 (déplacement du curseur vers la droite, pas de décalage du compteur d'adresse).
Fin de l'initialisation, l'écran est prêt à recevoir les autres instructions permettant l'affichage.
Il s’agit la mémoire où sont stockés les caractères affichés.
L’adresse du caractère correspond à sa position à l’écran.
Pour un écran à 1 ligne (80 caractères max) :
le premier caractère de gauche est à l'adresse 0x00,
le caractère à sa droite est à l'adresse 0x01,
le caractère suivant est à l'adresse 0x02,
et ainsi de suite...
@ 0x00 |
@ 0x01 |
@ 0x02 |
@ 0x03 |
.......... |
@ 0x4C |
@ 0x4D |
@ 0x4E |
@ 0x4F |
Pour un écran à 2 lignes (40 caractères max par ligne) :
la logique d'accès au caractères est la même que pour un écran 1 ligne,
le logique d'accès au caractères est la même que pour un écran 1 ligne sauf que l'adresse du premier caractère de gauche commence à 0x40.
@ 0x00 |
@ 0x01 |
@ 0x02 |
@ 0x03 |
.......... |
@ 0x24 |
@ 0x25 |
@ 0x26 |
@ 0x27 |
@ 0x40 |
@ 0x41 |
@ 0x42 |
@ 0x43 |
.......... |
@ 0x64 |
@ 0x65 |
@ 0x66 |
@ 0x67 |
Pour l’écran à 2 lignes de 40 caractères, si on écrit un caractère à l’adresse 27h, le curseur vient se placer automatiquement à l’adresse 40h.
Pour un écran plus petit (de 2 lignes de 16 caractères par exemple), bien qu’inutile, il est possible d’accéder aux adresses mémoires des caractères inexistants.
Pour une matrice de caractères de 5x8, il y a 8 caractères personnalisables dans la CGROM, et seulement 4 lorsque la matrice est de 5x11. Pour une matrice de 5x8 :
Le 1er caractère est accessible aux adresses 00h et 08h (de la DDRAM),
Le 2ème caractère est accessible aux adresses 01h et 09h,
…
Le 8ème caractère est accessible aux adresses 07h et 0Fh.
Pour configurer les caractères personnalisables :
il faut appeler la fonction « Set CGRAM address » où les bits « ACG5 ACG4 ACG3 » correspondent à l’adresse du caractère (ex : « 010 » pour le 3ème caractère) et les bits « ACG2 ACG1 ACG0 » à la ligne dans la matrice du caractère (ex : « 011 » pour la 3ème ligne en partant du haut),
il faut ensuite appeler la fonction « Write data to CGRAM » où les bits « D7 D6 D5 » sont mis à 0 et les bits « D4 D3 D2 D1 D0 » correspondent à l’état des pixels (0 = éteint, 1 = allumé).
Pour une matrice de 5x11 , même principe sauf que :
Le 1er caractère est accessible aux adresses 00h et 08h (de la DDRAM) pour les 8 lignes du haut, et 01h et 09h pour les 3 autres lignes,
Le 2ème caractère est accessible aux adresses 02h et 0Ah pour les 8 lignes du haut, ainsi que 03h et 0Bh pour les 3 autres lignes,
…
Le 4ème caractère est accessible aux adresses 06h et 0Eh pour les 8 lignes du haut, ainsi que 07h et 0Fh pour les 3 autres lignes.
Les 128 premiers caractères sont répartis comme suit :
les 16 premiers caractères correspondent aux caractères personnalisés stockés en CGRAM,
les 16 suivants sont des caractères de contrôle (flèches, guillemets, ...),
les 96 suivants sont à peu près les caractères ASCII.
Pour les 128 derniers caractères, il existe plusieurs standards en fonction de la référence du contrôleur « HD44780Uxxx » où « xxx » est le ROM code :
Si le « ROM code = A00 », alors le contrôleur utilise le jeu de caractère japonais,
Si le « ROM code = A02 », alors le contrôleur utilise le jeu de caractère européen.
Il peut exister encore d'autres jeux de caractères notamment pour les clones KS0070B et SPLC780A1.
Il faut se référer à la datasheet pour connaître la signification exacte de chaque emplacement de la CGROM, ou alors le vérifier expérimentalement.
Analyse des mémoires internes au module et création de caractères spéciaux.
Note d'application de Microchip pour piloter un écran via un HD44780 avec un microcontrôleur PIC®
Le
cycle d'écriture |
|
Écriture d'une instruction |
La
broche RS doit être à l'état 0. |
Écriture d'une donnée |
La
broche RS doit être à l'état 1. |
Voici le code sur un Atmega8 en assembleur :
;=========================================================================
; Programme pour piloter un écran LCD 1602 (HD44780) sur un ATmega8
;=========================================================================
; pour ATMEGA8
; Créé le : 26/04/2013
; Dernière mise a jour: 26/04/2013
; Auteur: Uriel
;=======================================================================
; Fréquence : par défaut, l'Atmega8 fonctionne en 1mhz interne.
; Pour passer en 8mhz interne, mettre les fusibles de avrdude "Low Fuse : C4" et "High Fuse : D9" (attention, il démarre tout de suite)
; Pour 16mhz externe : lf:DF et hf:D9 (démarrage immédiat). Le quartz est entre PB6 et PB7 et les condenssateurs (entre 12 et 22pF inclus) sont reliés de ces pattes au 0V.
;======================
; Entrées/Sorties :
;======================
; Entrée :
; PB3 : Entrée bouton poussoir "Gauche"
; PB2 : Entrée bouton poussoir "Milieu"
; PB1 : Entrée bouton poussoir "Droite"
; Sorties :
; PD0 : Borne 4 "RS"
; PD1 : Borne 5 "R/W"
; PD2 : Borne 6 "E"
; PD3 : Borne 7 "D0"
; PD4 : Borne 8 "D1"
; PB6 : Borne 9 "D2"
; PB7 : Borne 10 "D3"
; PD5 : Borne 11 "D4"
; PD6 : Borne 12 "D5"
; PD7 : Borne 13 "D6"
; PB0 : Borne 14 "D7"
.include "m8def.inc" ; Nom du fichiers de références des registres (ATMEGA 8)
;------------------------------------------------------------------------
; Déclaration des Variables
;------------------------------------------------------------------------
.def variable1 = R1 ; Il y a 32 registres de 16 bits adressés de r0 à r31 avec de r16 à r31 pour travailler en valeur immédiates
.def variable2 = R2
.def a=R16
.def b=R17
.def c=R18
.def d=R19
.def variablepwm=R20
.DSEG ; Début de zone de la partie "taille"
nombre1: .BYTE 1 ; Nombre codé sur 1 octet en binaire
nombre2: .BYTE 3 ; Nombre codé sur 3 octets en binaire
dividende: .BYTE 3
numerateur: .BYTE 1
denominateur: .BYTE 1
;------------------------------------------------------------------------
; Constantes
.equ constante1 = 0b00000001 ; On met la constante à 1
;------------------------------------------------------------------------
;Déclaration des Vecteurs d'interruptions
;------------------------------------------------------------------------
.CSEG ; Début de la partie "données"
.ORG 0x0000 ; Début de la zone memoire programme
rjmp RESET ; RESET
rjmp EXT_INT0 ; Interruption externe INT0
rjmp EXT_INT1 ; Interruption externe INT1
rjmp TIM2_COMP ; Interruption comparaison reussie TIMER2
rjmp TIM2_OVF ; Interruption debordement compteur TIMER2
rjmp TIM1_CAPT ; Interruption entree capture TIMER1
rjmp TIM1_COMPA ; Interruption comparateurA TIMER1
rjmp TIM1_COMPB ; Interruption comparateurB TIMER1
rjmp TIM1_OVF ; Interruption debordement compteur TIMER1
rjmp TIM0_OVF ; Interruption debordement compteur TIMER0
rjmp SPI_STC ; Interruption transmissions SPI terminee
rjmp UART_RXC ; Interruption reception UART termine RX
rjmp UART_DRE ; Interruption UART vide
rjmp UART_TXC ; Interruption emission UART termine TX
rjmp ADC_ok ; Interruption Conversion A/D terminee
rjmp EE_RDY ; Interruption EEPROM prete
rjmp ANA_COMP ; Interruption comparaison analogique effectuee
;------------------------------------------------------------------------
; Routines de traitement des interruptions
;------------------------------------------------------------------------
EXT_INT0: ; Déclenchée par les signaux de BEMF sur PD2 en front montant et descendant
; Tâche à effectuer
reti ; Retour après l'interruption
;------------------------------------------------------------------------
EXT_INT1: reti
;------------------------------------------------------------------------
TIM2_COMP:reti
;------------------------------------------------------------------------
TIM2_OVF: reti
;------------------------------------------------------------------------
TIM1_CAPT:reti
;------------------------------------------------------------------------
TIM1_COMPA:reti
;------------------------------------------------------------------------
TIM1_COMPB:reti
;------------------------------------------------------------------------
TIM1_OVF: reti
;------------------------------------------------------------------------
TIM0_OVF: reti
;------------------------------------------------------------------------
SPI_STC: reti
;------------------------------------------------------------------------
UART_RXC: reti
;------------------------------------------------------------------------
UART_DRE: reti
;------------------------------------------------------------------------
EE_RDY: reti
;------------------------------------------------------------------------
ANA_COMP: reti
;------------------------------------------------------------------------
ADC_ok: reti
;------------------------------------------------------------------------
UART_TXC: reti
;------------------------------------------------------------------------
UART_RXC1:reti
;------------------------------------------------------------------------
;Programme de RESET
cli ; Désactive les vecteurs d'interruptions pendant la séquence
RESET:
ldi R16,low(RAMEND) ; Charge le BYTE faible de fin de RAM dans le registre R16
out SPL,R16 ; Initialisation de la pile a l'adresse haute de la RAM
ldi R16,high(RAMEND) ; Charge le BYTE fort de fin de RAM dans le registre R16
out SPH,R16 ; Initialisation du BYTE fort de la pile à l'adresse haute de la RAM
CLI ; Désactive les vecteurs d'interruptions pendant la séquence
;------------------------------------------------------------------------
; Initialisation des ports
; PORT B:
ldi a,0b11110001 ; PORTB en entrée (0=Entrée, 1=Sortie)
out ddrb,a ; On écrit dans le PORTB
; PORT C:
ldi a,0b00000000 ; Toutes en entrées (0=Entrée, 1=Sortie)
out ddrc,a
; PORT D:
ldi a,0b11111111 ; PORTD en sortie (0=Entrée, 1=Sortie)
out ddrd,a
CLR a
OUT PORTD,a ; On met le PORT D à 0
OUT PORTB,a ; On met le PORT B à 0
;------------------------------------------------------------------------
;TCCR0
; Définit le mode de fonctionnement du Timer0
ldi a,0b00000001 ; bits7a3 = non utilise bits2,1,0 = taux de prédivision de l'horloge pour 001, on fonctionne à la fréquence de l'horloge
out TCCR0,a
;------------------------------------------------------------------------
;PROGRAMME PRINCIPAL
;------------------------------------------------------------------------
; Initialisation
RCALL temporisation3 ; On commence par attendre 200mS pendant l'initialisation de l'afficheur
; Il faut que la tension soit stabilisée... donc avec mon alimentation, je dois mettre une longue tempo...
; Premier envois
SBI PORTD,6 ; On met D5 à 1
SBI PORTD,5 ; On met D4 à 1 : interface 8 BITS (si "0" alors 4 BITS)
RCALL validation ; On valide les données envoyées au LCD
RCALL temporisation ; On attend 16mS avant d'envoyer la suite
; Deuxième envois
RCALL validation ; On valide les données envoyées au LCD
RCALL temporisation ; On fait une pause de 16mS
; Troisième envois
RCALL validation ; On valide les données envoyées au LCD
RCALL temporisation1 ; On fait une pause de 16mS
CLR a
OUT PORTD,a ; On met le PORT D à 0
OUT PORTB,a ; On met le PORT B à 0
; Function set
SBI PORTD,6 ; On met D5 à 1
SBI PORTD,5 ; On met D4 à 1 : interface 8 BITS (si "0" alors 4 BITS)
SBI PORTB,7 ; On met D3 à 1 : Deux lignes d'affichage (si "0" alors 1 ligne)
SBI PORTB,6 ; On met D2 à 1 : Matrice 5 x 11 points (si "0" alors 5 x 8)
RCALL validation ; On valide les données envoyées au LCD
CLR a
OUT PORTD,a ; On met le PORT D à 0
OUT PORTB,a ; On met le PORT B à 0
; Clear display : efface l'écran et retourne dans la case en haut à gauche
SBI PORTD,3 ; On met D0 à 1
RCALL validation ; On valide les données envoyées au LCD
RCALL temporisation1 ; On fait une pause de 1mS
RCALL temporisation1 ; On fait une pause de 1mS
CLR a
OUT PORTD,a ; On met le PORT D à 0
OUT PORTB,a ; On met le PORT B à 0
; Entry set mode
SBI PORTB,6 ; On met D2 à 1
SBI PORTD,4 ; On met D1 à 1 : déplacement du curseur à droite (0=Gauche)
CBI PORTD,3 ; On met D0 à 0 : L'affichage n'est pas décalé (1 = l'affichage se décale avec le curseur)
RCALL validation ; On valide les données envoyées au LCD
CLR a
OUT PORTD,a ; On met le PORT D à 0
OUT PORTB,a ; On met le PORT B à 0
; Display on/off control
SBI PORTB,7 ; On met D3 à 1
SBI PORTB,6 ; On met D2 à 1 : affichage visible (0 = Invisible)
CBI PORTD,4 ; On met D1 à 0 : curseur invisible (1 = Visible)
CBI PORTD,3 ; On met D0 à 0 : curseur fixe (1 = Clignotant)
RCALL validation ; On valide les données envoyées au LCD
CLR a
OUT PORTD,a ; On met le PORT D à 0
OUT PORTB,a ; On met le PORT B à 0
;------------------------------------------------------------------------
;Progamme principal, ici, on affiche du texte
SEI ; On permet les interruptions
programme: ; Routine qui écrit du texte
; Il faut laisser RS à 1 pendant toute la séquence d'envois
RCALL temporisation2 ; On attend 50µS pour que RS précède le signal
; Ecrit "C"
LDI a,0b10011001
OUT PORTD,a ; On met D6, D1,D0 et RS à 1
RCALL validation ; On valide les données envoyées au LCD
; Ecrit "o"
LDI a,0b11011001
OUT PORTD,a ; On met D6, D5, D1, D0 et RS à 1
LDI a,0b11000000
OUT PORTB,a ; On met D3, D2 à 1
RCALL validation ; On valide les données envoyées au LCD
; Ecrit "u"
LDI a,0b11101001
OUT PORTD,a ; On met D6, D5, D4, D0 et RS à 1
LDI a,0b01000000
OUT PORTB,a ; On met D2 à 1
RCALL validation ; On valide les données envoyées au LCD
; Ecrit "c"
LDI a,0b11011001
OUT PORTD,a ; On met D6, D5, D1,D0 et RS à 1
LDI a,0b00000000
OUT PORTB,a ; On efface le port B
RCALL validation ; On valide les données envoyées au LCD
; Ecrit "o"
LDI a,0b11011001
OUT PORTD,a ; On met D6, D5, D1, D0 et RS à 1
LDI a,0b11000000
OUT PORTB,a ; On met D3, D2 à 1
RCALL validation ; On valide les données envoyées au LCD
; Ecrit "u"
LDI a,0b11101001
OUT PORTD,a ; On met D6, D5, D4, D0 et RS à 1
LDI a,0b01000000
OUT PORTB,a ; On met D2 à 1
RCALL validation ; On valide les données envoyées au LCD
; Ecrit " " "Espace"
LDI a,0b01000001
OUT PORTD,a ; On met D5 et RS à 1
LDI a,0b00000000
OUT PORTB,a ; On efface le port B
RCALL validation ; On valide les données envoyées au LCD
; Ecrit "P"
LDI a,0b10100001
OUT PORTD,a ; On met D6, D4 et RS à 1
LDI a,0b00000000
OUT PORTB,a ; On efface le port B
RCALL validation ; On valide les données envoyées au LCD
; Ecrit "a"
LDI a,0b11001001
OUT PORTD,a ; On met D6, D5, D0 et RS à 1
LDI a,0b00000000
OUT PORTB,a ; On efface le port B
RCALL validation ; On valide les données envoyées au LCD
; Ecrit "p"
LDI a,0b11100001
OUT PORTD,a ; On met D6, D5, D4 et RS à 1
LDI a,0b00000000
OUT PORTB,a ; On efface le port B
RCALL validation ; On valide les données envoyées au LCD
; Ecrit "a"
LDI a,0b11001001
OUT PORTD,a ; On met D6, D5, D0 et RS à 1
LDI a,0b00000000
OUT PORTB,a ; On efface le port B
RCALL validation ; On valide les données envoyées au LCD
; Ecrit " " "Espace"
LDI a,0b01000001
OUT PORTD,a ; On met D5 et RS à 1
LDI a,0b00000000
OUT PORTB,a ; On efface le port B
RCALL validation ; On valide les données envoyées au LCD
; Ecrit "!"
LDI a,0b01001001
OUT PORTD,a ; On met D5, D0 et RS à 1
LDI a,0b00000000
OUT PORTB,a ; On efface le port B
RCALL validation ; On valide les données envoyées au LCD
fin:
RJMP fin
; Return home
SBI PORTD,4 ; On met D1 à 1 : Place le curseur dans la position d'origine en haut à gauche
SBI PORTD,3 ; On met D0 à 1
RCALL temporisation2 ; On attend 50µS
CBI PORTD,2 ; On met E à 0 : Valide les entrées sur front descendant de cette impulsion
RCALL temporisation2 ; On attend 50µS
RCALL temporisation1 ; On fait une pause de 1mS
RCALL temporisation1 ; On fait une pause de 1mS
CBI PORTD,4 ; On met D1 à 0
CLR a
OUT PORTD,a ; On met le PORT D à 0
OUT PORTB,a ; On met le PORT B à 0
RCALL temporisation1 ; On fait une pause de 1mS
;------------------------------- Validation -------------------------------------------
validation: ; Routine qui valide les données
SBI PORTD,2 ; On met E à 1
; On effectue 100µS de temporisation
ldi d,80
soustempov1:
NOP ; Aucune opération : sert à ajuster la durée
NOP
NOP
NOP
NOP
NOP
NOP
dec d ; On décrémente
brne soustempov1 ; Si différent de "Z", on va à la routine indiqué (il faut que R31 et R30 soient à zéro)
CBI PORTD,2 ; On met E à 0 : Valide les entrées sur front descendant de cette impulsion
; On effectue 100µS de temporisation
ldi d,80
soustempov2:
NOP ; Aucune opération : sert à ajuster la durée
NOP
NOP
NOP
NOP
NOP
NOP
dec d ; On décrémente
brne soustempov2 ; Si différent de "Z", on va à la routine indiqué (il faut que R31 et R30 soient à zéro)
RET ; On retourne au "rcall" précédent
;------------------------------------- Temporisation ---------------------------------------
temporisation: ; Routine qui retarde le programme de 16mS à 8Mhz avec 7 NOP, et 1x50x255
ldi b,1 ; On met la valeur dans la variable
soustempo1:
ldi c,50
soustempo2:
ldi d,255
soustempo3:
NOP ; Aucune opération : sert à ajuster la durée
NOP
NOP
NOP
NOP
NOP
NOP
dec d ; On décrémente
brne soustempo3 ; Si différent de "Z", on va à la routine indiqué (il faut que R31 et R30 soient à zéro)
dec c
brne soustempo2 ; IDEM : multiple 2
dec b
brne soustempo1 ; IDEM : multiple 3
RET ; On retourne au "rcall" précédent
;------------------------------------- Temporisation N°1 ---------------------------------------
temporisation1: ; Routine qui retarde le programme de 1mS à 8Mhz avec 7 NOP, et 1x4x200
ldi b,1 ; On met la valeur dans la variable
soustempo11:
ldi c,4
soustempo12:
ldi d,200
soustempo13:
NOP ; Aucune opération : sert à ajuster la durée
NOP
NOP
NOP
NOP
NOP
NOP
dec d ; On décrémente
brne soustempo13 ; Si différent de "Z", on va à la routine indiqué (il faut que R31 et R30 soient à zéro)
dec c
brne soustempo12 ; IDEM : multiple 2
dec b
brne soustempo11 ; IDEM : multiple 3
RET ; On retourne au "rcall" précédent
;------------------------------------- Temporisation N°2 ---------------------------------------
temporisation2: ; Routine qui retarde le programme de 100µS à 8Mhz avec 7 NOP, et 1x1x80
ldi b,1 ; On met la valeur dans la variable
soustempo21:
ldi c,1
soustempo22:
ldi d,80
soustempo23:
NOP ; Aucune opération : sert à ajuster la durée
NOP
NOP
NOP
NOP
NOP
NOP
dec d ; On décrémente
brne soustempo23 ; Si différent de "Z", on va à la routine indiqué (il faut que R31 et R30 soient à zéro)
dec c
brne soustempo22 ; IDEM : multiple 2
dec b
brne soustempo21 ; IDEM : multiple 3
RET ; On retourne au "rcall" précédent
;------------------------------------- Temporisation N°3 ---------------------------------------
temporisation3: ; Routine qui retarde le programme de 200mS à 8Mhz avec 7 NOP, et 3x210x255
ldi b,3 ; On met la valeur dans la variable
soustempo31:
ldi c,210
soustempo32:
ldi d,255
soustempo33:
NOP ; Aucune opération : sert à ajuster la durée
NOP
NOP
NOP
NOP
NOP
NOP
dec d ; On décrémente
brne soustempo33 ; Si différent de "Z", on va à la routine indiqué (il faut que R31 et R30 soient à zéro)
dec c
brne soustempo32 ; IDEM : multiple 2
dec b
brne soustempo31 ; IDEM : multiple 3
RET ; On retourne au "rcall" précédent
;------------------------------------------------------------------------
;ROUTINES
;------------------------------------------------------------------------
portc_entier:
ldi a,0b00000001
out portc,a ; On assigne chaque patte du port à 1 ou 0
ret
patte_portc_sortie:
CBI portc,3 ; On met la patte à 0
SBI portc,3 ; On met la patte à 1
test_entree:
SBIS pind,7 ; On saute si le BIT est à 1
ret
;----------------------------------------------------------------------
; Compteur : on utilise le TMR0 qui possède 8 bits donc 256 valeurs.
Compteur: ; Tous les 256 cycles d'horloge, il déborde, exécutant la routine TIM0_OVF:
LDI R16,0b00000001 ; Prescaler à 0 (trois derniers bits déterminent la prédivision)
OUT TCCR0,R16
LDI R16,0B00000001 ; Activation avec autorisation d'interruption et de débordement
OUT TIMSK,R16
LDI R16,0B0000000 ; Compteur à 0
OUT TCNT0,R16
SEI ; Global Interrupt Enable
RET
C'est déjà beaucoup plus simple ^^
Il suffit de suivre ce shéma :
Et d'envoyer le code suivant (par exemple) :
/*
LiquidCrystal Library - par Uriel
The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD R/W pin to ground
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)
Code inspiré de l'original :
http://www.arduino.cc/en/Tutorial/LiquidCrystal
*/
// include the library code:
#include
// Pattes utilisées
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
// Définit le nombre de caractères et de lignes
lcd.begin(16, 2);
// Affiche le texte à l'écran
lcd.print("Bonjour Uriel !");
}
void loop() {
// Met le curseur à la colone 0 ligne 1 (ligne du bas)
lcd.setCursor(0, 1);
// Affiche le nombre de secondes depuis la mise sous tensions
lcd.print((millis()/1000));
}
Avec un module I2C :
08/04/2014
La librairie qui convient avec ma versions Arduino 1.0.5 est ici.
Le code :
Création le 18/08/2014
Petit module qui sert à diminuer le nombre de fils à câbler : quatre seulement, en utilisant le protocole de communication : I²C (SDA SCL).
Il se soude dirrectement sur les broches de l'écran LCD1602.
ça vaut dans les 1€ livré.
/*
Programme type d'utilisation du module LCD sur un écran 1602
Créé le 08/04/2014
*/
#include
#include
LiquidCrystal_I2C lcd(0x27,16,2); // Met à adresse 0x27 du LCD le type : 16 charactères sur 2 lignes
void setup()
{
lcd.init(); // Initialisation du LCD
lcd.backlight(); // Allume la diode de rétro-éclairage
lcd.print("Salut Uriel !"); // Affiche le message entre guillemets.
}
void loop()
{
lcd.setCursor(0, 1); // Met le curseur à la colone 0 ligne 1 (ligne du bas)
lcd.print((millis()/1000)); // Affiche le nombre de secondes écoulées
}
Dernière mise à jour :18/08/2014 par Uriel