Cet article traite essentiellement des modules LCD basé sur le controleur Hitachi 44780 ou equivalent.
| N° Pin | Symbole | Niveau | Fonction |
| 1 | Vss | GND | Ground |
| 2 | Vcc | +5V | Module Power |
| 3 | Vee | Contraste | Liquid Cristal Contrast |
| 4 | RS | H/L | Register select, H=data, L=instruction |
| 5 | R/W | HL | Read/Write, H=read (LCD->CPU), L=write (CPU->LCD) |
| 6 | E | Note 1 | Edge-sensitive Enable |
| 7 | DB0 | Note 2 | Data bit 0 (least significant bit) |
| 8 | DB1 | Note 2 | '' |
| 9 | DB2 | Note 2 | '' |
| 10 | DB3 | Note 2 | '' |
| 11 | DB4 | Note 2 | '' |
| 12 | DB5 | Note 2 | '' |
| 13 | DB6 | Note 2 | '' |
| 14 | DB7 | Note 2 | '' |
NOTE 1: E (Enable) latche RS et R/W sur le front montant et latche les données sur le flans descendant. Selon les specs, RS et R/W doivent être stable avant que E soit à l'état haut et doivent rester stable jusqu'à ce que E passe à l'état bas. Les données doivent être stable quand E passe à l'état bas.
NOTE 2: Les pins de données DB7-DB0 (ou DB7-DB4 quand on utilise une interface à 4-bits) sont controllées par le CPU lors de l'écriture, mais doivent être mise en état de haute impédance afin que le module puisse controller les lignes lors d'une lecture ou quand on utilise le controle par BUSY FLAG.
Quand on utilise une interface à 4-bits, Le quartet de poids fort est écrit en premier (bit7-bit4), alors que le quartet de poids faible est écrit (bit3-bit0) lors du cycle Enable suivant (Pas de délai nécessaire entre les deux instructions). les lignes DB3 à DB0 sont laissées déconnectées. Les pins ont des pullups internes donc pas de problèmes si on les laisse déconnectées.
Attention, toutes les instructions n'ont pas le même temps d'execution ! Il faut donc leur laisser le temps...
| Instruction | Temps d'execution | Remarque |
| Clear display | 1.64ms | / |
| Home cursor | 40us à 1.64ms | Dépends de la "distance" du curseur par rapport à l'origine |
| Read busy flag | 1 Enable cycle | 2 cycles si mode 4 bits |
| Character generator read/write | 120us | / |
| Toutes les autres instructions | 40 us | / |
Ces délais d'execution signifient qu'il faut, après une opération, que le CPU surveille le Busy Flag ou si la connection CPU-module LCD est du type Write only que l'on respecte les temps d'exécution avant de lancer l'instruction suivante. Si on veut améliorer la vitesse de communication, il est recommandé d'utiliser la méthode Busy Flag plutot que celle des délais.
Comment adresser la mémoire :
La RAM du Character generator se trouve aux adresses 64-127 et RAM écran se trouvent aux adresses 128-255. C'est juste un artifice, Les blocks de la RAM ne sont pas physiquement contigus.
Comment utiliser des caractères propres à l'utilisateur :
L'écran possède 64 bytes de CG RAM où on peut stocker 8 caractères définisables par l'utilisateur. Chacun de ces caractères sont définis comme des caratères 5X8 dans une matrice 8x8. La partie 5X8 est justifiée à droite dans la matrice. Notez quand même que dans le mode 5X10, on ne peut stocker que 4 caractères utilisateur utilisant 11 bytes chacun.
| Adresses CG | Données CG | ||||||||
| D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | ||
| x+0 | x | x | x | 1 | 1 | 1 | 1 | 1 | ***** |
| x+1 | x | x | x | 1 | 0 | 0 | 0 | 0 | * |
| x+2 | x | x | x | 1 | 0 | 0 | 0 | 1 | ** |
| x+3 | x | x | x | 1 | 1 | 1 | 1 | 1 | ***** |
| x+4 | x | x | x | 1 | 0 | 0 | 0 | 1 | ** |
| x+5 | x | x | x | 1 | 0 | 0 | 0 | 0 | * |
| x+6 | x | x | x | 1 | 0 | 0 | 0 | 0 | * |
| x+7 | x | x | x | 0 | 0 | 0 | 0 | 0 | ( ligne du curseur) |
Où "x" l'adresse du caractère : CG0=0, CG1=8, CG2=16, CG3=24, CG4=32, CG5=40, CG6=48, CG7=56. Comme on peut le voir dans le tableau ci-dessus, chaque byte de données CG représente 1 ligne de pixel du caractère avec D0 comme le pixel le plus à droite et D4 le plus à gauche (les 3 bits supérieurs ne sont pas affichés). La première adresse du caractère représente la ligne supérieure et la 7ième la ligne du bas. (La 8ième est "ORed" avec la ligne de curseur). Un '1' sur n'importe quelle position de pixel devient un pixel "noir" sur l'afficheur.
La CG RAM occupe un espace mémoire différent de l'espace de donnée de la (DD) RAM. On doit d'abord mettre la première adresse CG avant d'écrire une donnée CG. Chaque écriture incrémente/décrémente automatiquement le pointeur d'adresse CG RAM. N'oubliez pas de repasser en mode d'adressage de la RAM DD avant d'envoyer des caractères à afficher...
Comment adresser la mémoire écran :
Dans la liste ci-dessous, "ligne 1" est la ligne supérieure et "ligne n" est la ligne la plus basse sur l'écran. Sur chaque ligne, le caractères le plus à gauche a l'adresse la plus basse. Les adresses s'accroissent quand on va vers la droite. De plus, les adresses DD RAM sont indiquées sans le bit 80h à l'état haut. Ajoutez 80h à l'adresse du caractère pour faire la commande "Display Data RAM Address Set ".
Les modules 16x2 sont constitués de 2 lignes de 16 caractères. Les adresses de la ligne 1 sont situées de 00h à 0Fh (0 à 15). Les adresses de la ligne 2 sont situées de 40h à 4Fh (64 à 79).
|00|01|02|03|04|05|06|07|08|09|0A|0B|0C|0D|0E|0F|
|40|41|42|43|44|45|46|47|48|49|4A|4B|4C|4D|4E|4F|
La RAM écran est constituée de 80 bytes quelque soit le nombre de caractères affichable par le module. Ces extra bytes peuvent être utilisés quand le scrolling de l'écran est employé ou pour stocker des données en provenance du CPU (de la RAM externe supplémentaire !). Il n'y a pas de RAM dans les blocks 28h-3Fh et 68h-7Fh.
L'initialisation des modules :
Les modules avec un controleur Hitachi s'initiera de lui-même si Vcc s'éleve de 0 à 4.5v en une periode de .1mS à 10mS (sinon, on peut utiliser un circuit RC). Si vous utilisez l'auto-initialisation, le module era dans les modes suivants : interface 8-bits, caractères 5x7, increment du curseur vers la droite, sans glissement.
Initialisation en interface 8-bits
|
POWER ON Wait 15ms RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 1 x x x x x=don't care Set 8-bit mode Wait 4.1ms RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 1 x x x x Set 8-bit mode Wait 100us RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 1 x x x x Set 8-bit mode Wait 4.1ms Busy Flag cannot be checked before this point RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 1 1 F x x 8-bit operation 1/16 duty cycle F=font, 1 for 5x11 dot matrix 0 for 5x8 dot matrix Wait 40us RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 0 0 1 0 0 0 Display off, cursor off, blink off Wait 40us RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 0 0 1 1 C B Display on, C=1 for cursor on B=1 for blinking cursor Wait 1.64m RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 0 0 0 1 I S Set entry mode I=1 for cursor move to the right, I=0 for cursor move to the left S=1 for shift display, S=0 for no shift Wait 40us INITIALIZATION COMPLETE NOTE: Remember to turn the display back on and set up the cursor as desired with an On/Off Control command. |
|||
Initialisation pour interface 4-bits
Le module s'allume en mode 8-bits. Les instructions de démarrage sont envoyées en mode 8-bits, les 4 bits (non connectés) ne sont pas utilisés. Après la quatrième instruction, qui fait passer le module en mode 4-bit, les bytes de controle sont envoyés suivant les cycles enable consécutifs (pas de delais nécessaires entre les quartets). Le quartet de poids fort est envoyé d'abord suivi immédiatement du quartet de poids faible.
|
POWER ON Wait 15ms RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 1 n/c n/c n/c n/c n/c=not connected set 8-bit mode Wait 4.1ms RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 1 n/c n/c n/c n/c set 8-bit mode Wait 100us RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 1 n/c n/c n/c n/c set 8-bit mode Wait 4.1ms RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 0 n/c n/c n/c n/c set 4-bit operation Wait 40us Busy Flag cannot be read before this point RS R/W DB7 DB6 DB5 DB4 0 0 0 0 1 0 0 0 1 F x x 4-bit operation 1/16 duty cycle F=font, 1 for 5x11 dot matrix 0 for 5x8 dot matrix x=don't care Wait 40us RS R/W DB7 DB6 DB5 DB4 0 0 0 0 0 0 0 0 1 0 0 0 Display off, cursor off, blink off Wait 40us RS R/W DB7 DB6 DB5 DB4 0 0 0 0 0 0 0 0 1 1 C B Display on, C=1 for cursor on, B=1 for blinking cursor Wait 1.64ms RS R/W DB7 DB6 DB5 DB4 0 0 0 0 0 0 0 0 0 1 I S Set entry mode, I=1 for cursor moving right, I=0 for cursor moving left, S=1 for shift display, S=0 for no shift Wait 40us INITIALIZATION COMPLETE |
|||
Voici un exemple de code utilisé pour un module LCD à 2 lignes attaché au port P1 d'un 8051 en mode 4-bits avec un interface en write-only. D7-D4 sont reliés à P1.7-P1.4, RS à P1.3,et E à P1.2. R/W est mis à la masse.
|
LCD51.ASM --------- $MOD51 ; SIMPLE ROUTINES FOR DRIVING LCD DISPLAY WITH 8751 ; by CHRIS BURIAN LCD_PORT EQU P1 E_PIN EQU P1.2 CLS EQU 00000001b D_SET EQU 00001000b E_SET EQU 00000100b F_SET EQU 00100000b D_ON EQU 00000100b D_OFF EQU 00000000b C_ON EQU 00000010b C_OFF EQU 00000000b B_ON EQU 00000001b B_OFF EQU 00000000b S_NO EQU 00000000b S_YES EQU 00000001b C_INC EQU 00000010b C_DEC EQU 00000000b F_8BIT EQU 00010000b F_4BIT EQU 00000000b F_2LINE EQU 00001000b F_1LINE EQU 00000000b F_8FONT EQU 00000000b F_11FONT EQU 00000100b CG_ADDR EQU 01000000b DD_ADDR EQU 10000000b ORG 0h ;reset vector LJMP MAIN ORG 30h ;code starts after vector table ;transmit character in ACC to LCD CHAR_OUT: PUSH ACC ;store the byte ANL A, #11110000b ;mask out low nibble ORL A, #00001000b ;set RS=1 MOV LCD_PORT, A ;send high order nibble SETB E_PIN ;toggle Enable CLR E_PIN POP ACC ;get low order nibble SWAP A ;put in high nibble ANL A, #11110000b ;mask out nibble ORL A, #00001000b ;set RS=1 MOV LCD_PORT, A ;send low order nibble SETB E_PIN ;toggle Enable CLR E_PIN ACALL WAIT_40U ;pause for 40us RET ;transmit command in ACC to LCD COMD_OUT: PUSH ACC ;store the byte ANL A, #11110000b ;mask out low nibble ;RS=0 MOV LCD_PORT, A ;send high order nibble SETB E_PIN ;toggle Enable CLR E_PIN POP ACC ;get low order nibble SWAP A ;put in high nibble NIBBLE_OUT: ANL A, #11110000b ;mask out nibble ORL A, #00001000b ;set RS=1 MOV LCD_PORT, A ;send low order nibble SETB E_PIN ;toggle Enable CLR E_PIN ACALL WAIT_40U ;pause for 40us RET ;initialize the LCD INIT_LCD: ACALL WAIT_15M ;pause for 15ms MOV A, #(F_SET OR F_8BIT) ;set 8-bit mode ACALL NIBBLE_OUT ;send to LCD ACALL WAIT_5M ;pause for 4.1ms MOV A, #(F_SET OR F_8BIT) ;set 8-bit mode ACALL NIBBLE_OUT ;send to LCD ACALL WAIT_60U ;pause for 60us extra MOV A, #(F_SET OR F_8BIT) ;set 8-bit mode ACALL NIBBLE_OUT ;send to LCD ACALL WAIT_5M ;pause for 4.1ms MOV A, #(F_SET OR F_4BIT) ;set 4-bit mode ACALL NIBBLE_OUT ;send to LCD ;set 4-bit, 2-line, 5x8 font MOV A, #(F_SET OR F_4BIT OR F_2LINE OR F_8FONT) ACALL COMD_OUT ;send to LCD ;turn off display, cursor, blink MOV A, #(D_SET OR D_OFF OR C_OFF OR B_OFF) ACALL COMD_OUT ;send to LCD ;turn on display and cursor MOV A, #(D_SET OR D_ON OR C_ON OR B_OFF) ACALL COMD_OUT ;send to LCD ;cursor moves right, no shift MOV A, #(E_SET OR S_NO OR C_INC) ACALL COMD_OUT ;send to LCD RET ;initialization complete ; send a message string to the LCD PRINT_LCD: MOV A, #0 ;clear ACC MOVC A, @A+DPTR ;fetch letter INC DPTR CJNE A,#16,PT_1 ;strings end with 16, SJMP PT_DONE ; finished PT_1: ACALL CHAR_OUT ;send letter to LCD SJMP PRINT_LCD ;repeat loop PT_DONE: RET ; program character generator RAM PROG_LCD: PUSH 1 ;save register R1 MOV R1,#8 ;8 bytes in a character MOV B, #8 MUL AB ;multiply char# by 8 to ; get CG RAM address ORL A, #CG_ADDR ;set addr command ACALL COMD_OUT ;send to LCD PG_1: MOV A, #0 ;clear ACC MOVC A, @A+DPTR ;fetch row INC DPTR ACALL CHAR_OUT ;send row to LCD ACALL WAIT_80U ;pause extra 80us DJNZ R1, PG_1 ;send 8 rows total POP 1 ;restore register R1 MOV A, #DD_ADDR ;go back to display RAM ACALL COMD_OUT ;send to LCD RET ;40 microsecond delay, assumes 12MHz or slower clock WAIT_40U: PUSH 1 MOV R1, #40 DJNZ R1, $ POP 1 RET WAIT_60U: PUSH 1 MOV R1, #60 DJNZ R1, $ POP 1 RET WAIT_80U: PUSH 1 MOV R1, #80 DJNZ R1, $ POP 1 RET ; 1 millisecond delay WAIT_1M: PUSH 1 PUSH 2 MOV R2, #4 W1LP: MOV R1, #250 DJNZ R1, $ DJNZ R2, W1LP POP 2 POP 1 RET WAIT_2M: PUSH 1 MOV R1, #2 W2LP: ACALL WAIT_1M DJNZ R1, W2LP POP 1 RET WAIT_5M: PUSH 1 MOV R1, #5 W5LP: ACALL WAIT_1M DJNZ R1, W5LP POP 1 RET WAIT_15M: PUSH 1 MOV R1, #15 W15LP: ACALL WAIT_1M DJNZ R1, W15LP POP 1 RET ;initialize the LCD, program a custom character, and print ;out a message. MAIN: ACALL INIT_LCD MOV DPTR, #SMILEY ;load custom character addr MOV A, #1 ;put into custom char #1 ACALL PROG_LCD MOV A, #CLS ;clear display, home cursor ACALL COMD_OUT ACALL WAIT_2M ;pause 1.64ms MOV DPTR, #MSG1 ;load message address ACALL PRINT_LCD MOV A, #(DD_ADDR+40h) ;go to second line ACALL COMD_OUT MOV DPTR, #MSG2 ACALL PRINT_LCD DONE: SJMP DONE ;cheesy smiley face ; ### ; # # # ; ##### ; # # # ; # # ; ##### ; ### SMILEY: DB 00001110b DB 00010101b DB 00011111b DB 00010101b DB 00010001b DB 00011111b DB 00001110b DB 00000000b MSG1: DB 1,' Hello, World. ',1,16 MSG2: DB 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,16 ;16 was chosen as the message delimiter because it is ;not a valid character number and won't ever be sent ;to the LCD to be displayed. END ----- end ----- |
|||