Debian logo [embedded-µC.LINUX]

10. Gestion d'un afficheur à cristaux liquides (LCD)

L'utilisation d'un afficheur à cristaux liquides ou LCD est assez courante sur les systèmes embarqués. C'est un écran de faible dimension employé pour informer l'utilisateur sur l'état du système ou pour afficher les mesures effectuées par différents capteurs.

Il existe un standard très populaire qui permet de gérer les communications avec la grande majorité des modèles d'afficheurs LCD quelque soit le fabricant. Ce standard est connu sous le le nom HD44780U. Ce nom correspond au contrôleur qui reçoit les données du microcontrôleur et qui les communique directement avec l'afficheur à cristaux liquides.

10.1. Caractéristiques d'un afficheur du type HD44780U

La standard HD44780U utilise 3 signaux de contrôle ainsi que 4 ou 8 lignes d'entrée-sortie pour le bus de données. L'utilisateur peut choisir si l'afficheur à cristaux liquides doit fonctionner avec un bus de données de 4 bits ou un bus de données de 8 bits. Si un bus de données de 4 bits est utilisé l'afficheur LCD utilise un total de 7 lignes (3 signaux de contrôle plus les 4 lignes pour le bus de données). Si un bus de données de 8 bits est utilisé l'afficheur LCD utilise un total de 11 lignes (3 signaux de contrôle plus les 8 lignes pour le bus de données).

Les trois signaux de contrôle sont appelés : EN, RS et RW.

EN, enable

Le signal enable est utilisé pour indiquer à l'afficheur à cristaux liquides qu'on va lui envoyer des données. Pour envoyer des données à l'afficheur, le programme doit s'assurer que le signal est au niveau bas (0) avant de faire évoluer les deux autres signaux de contrôle et de placer des données sur le bus de données. Quand l'ensemble des autres lignes sont correctement positionnées, le signal EN doit être placé au niveau haut (1) et il faut attendre un temps minimum requis par le composant (ce temps varie d'un afficheur à l'autre) avant de le placer au niveau bas (0) à nouveau.

RS, register select

Le signal register select est utilisé pour distinguer les instructions de commande des données à afficher. Si on place RS au niveau bas (0), les données sont traitées comme une commande ou instruction spéciale (effacer l'écran, positionner le curseur de position, etc.). Si on place RS au niveau haut (1), les données envoyées sont des caractères que l'écran doit afficher.

RW, read/write

Le signal read/write est utilisé pour distinguer si les informations sur le bus de données sont lues ou écrites. Si on place le signal RW au niveau haut (1), le programme interroge l'afficheur à cristaux liquides sur son état (Get LCD status). Dans tous les autres cas des commandes sont écrites. Ainsi, le signal RW sera presque toujours au niveau bas.

10.2. Utilisation d'un afficheur LCD avec SDCC sur cible MSC1210

Le premier exemple reprend le programme «Hello, World!» en utilisant l'afficheur LCD comme écran.

Exemple 13. Programme «Hello, World!» sur afficheur LCD

01: #include <stdio.h>
02: #include <msc1210.h>
03: #include "ser_msc1210.h"
04: #include "lcd_msc1210.h"
05: 
06: void putchar(char c) {
07:    if (print2lcd)
08:       lcd_putc(c);
09:    else
10:       ser_putc(c);
11: }
12: 
13: void main(void) {
14: 
15:    // Appuyer sur <Entrée> pour ajuster
16:    // automatiquement le (débit|baudrate)
17:    autobaud();
18: 
19:    // Initialisations pour SDCC
20:    EA=1;
21: 
22:    print2lcd = 0;
23: 
24:    // initialisation de l'afficheur LCD
25:    lcd_init();
26: 
27:    // effacement de l'écran
28:    lcd_clear();
29: 
30:    // positionnement du curseur dans 
31:    // le coin supérieur gauche
32:    lcd_home();
33: 
34:    print2lcd = 1;
35:    printf("Hello, World !");
36: 
37:    // Affichage du même message 
38:    // sur la console
39:    print2lcd = 0;
40:    printf("Hello, World!");
41:    putcr();
42: 
43:    while(1);
44: }

Voici le résultat de l'exécution du programme hello_lcd.c :


Le second exemple illustre le positionnement du curseur d'affichage sur l'écran à cristaux liquides.

Le modèle d'écran à cristaux liquides utilisé dans les exemples suivants dispose de 4 lignes de 20 caractères. Chaque caractère alphanumérique est accessible via une adresse définie dans le plan ci-dessous. On remarque que les adresses de chaque ligne ne sont pas consécutives ; ce qui n'est pas des plus pratique pour gérer le positionnement du curseur d'affichage.

ligne 0 : 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13
ligne 1 : 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53
ligne 2 : 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27
ligne 3 : 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67

Exemple 14. Programme de positionnement du curseur sur un afficheur LCD

01: #include <stdio.h>
02: #include <stdlib.h>
03: #include <msc1210.h>
04: #include "ser_msc1210.h"
05: #include "lcd_msc1210.h"
06: 
07: #define    MAXCHAR   10
08: #define    EOF      4
09: 
10: void putchar(char c) {
11:    if (print2lcd)
12:       lcd_putc(c);
13:    else
14:       ser_putc(c);
15: }
16: 
17: void main(void) {
18: 
19:    unsigned int x, y;
20:    unsigned char s[MAXCHAR];
21: 
22:    // Appuyer sur <Entrée> pour ajuster automatiquement le (débit|baudrate)
23:    autobaud();
24: 
25:    // Initialisations pour SDCC
26:    EA=1;
27: 
28:    print2lcd = 0;
29: 
30:    // Initialisation de l'afficheur LCD
31:    lcd_init();
32: 
33:    ser_puts("Programme de positionnement du curseur");
34:    putcr();
35:    ser_puts("L'abscisse X est comprise entre 0 et 19");
36:    putcr();
37:    ser_puts("L'ordonnee Y est comprise entre 0 et 3");
38:    putcr();
39:    ser_puts("(Sortie pour une valeur X > 19)");
40:    putcr();
41: 
42:    do {
43:            ser_puts("Saisie de x : ");
44:       ser_gets_echo(s, MAXCHAR);
45:          putcr();
46:       x = atoi(s);
47:            ser_puts("Saisie de y : ");
48:       ser_gets_echo(s, MAXCHAR);
49:          putcr();
50:       y = atoi(s);
51:       lcd_clear();
52:       lcd_set_xy(x, y);
53:       print2lcd = 1;
54:       printf("!ici");
55:       print2lcd = 0;
56:    } while (x < 20);
57: 
58:    // Affichage sur la console
59:    ser_puts("The End!");
60:    putcr();
61: 
62:    while(1);
63: }

Voici le résultat de l'exécution du programme sdcc_lcd_set_xy.c :

MSC1210 Ver:000305F10
>M0000 ok
>M8000 ok
>E
>T
>
>Programme de positionnement du curseur
L'abscisse X est comprise entre 0 et 19
L'ordonnee Y est comprise entre 0 et 3
(Sortie pour une valeur X > 19)
Saisie de x : 5
Saisie de y : 2