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.
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.
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.
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.
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.
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
Vous êtes ici :