Présentation du module LCD 1602
Le LCD 1602 est un afficheur alphanumérique comprenant 2 lignes de 16 caractères. Il est généralement piloté par un contrôleur HD44780 (ou compatible) qui gère une matrice de points de 5×8. La communication se fait par un bus parallèle de 8 bits, accompagné de trois signaux de contrôle : RS (sélection du regsitre), RW (lecture/écriture) et E (validation).
Raccordement au 8051
- D0–D7 du LCD vers le port P0 du 8051.
- RS vers P3.5, RW vers P3.6, E vers P3.4.
- V0 (contraste) relié à un potentiomètre.
- A et K pour le rétroéclairage.
Gestion du drapeau BUSY et commandes essentielles
Avant chaque envoi, le microcontrôleur doit lire le registre d'état du LCD et attendre que le bit BUSY (bit 7) passe à 0. Tant qu'il vaut 1, le contrôleur est occupé et ne peut recevoir de nouvelle donnée.
Les commandes les plus utilisées sont :
0x38: mode 8 bits, 2 lignes, caractères 5×8.0x0C: affichage actif, curseur invisible.0x0F: affichgae actif, curseur clignotant.0x01: effacement de l'écran.0x06: curseur incrémenté, pas de déplacement de l'affichage.0x07: curseur incrémenté, affichage décalé vers la gauche.0x80 + adresse: positionne le curseur en DDRAM.
La mémoire d'affichage DDRAM débute à l'adresse 0x00 pour la première ligne et à 0x40 pour la seconde, bien que chaque ligne puisse contenir plus de 16 octets en mémoire.
Exemple de code pour 8051
Le programme ci-dessous montre l'initialisation du LCD, l'attente du drapeau BUSY, le positionnement du curseur et l'affichage d'une chaîne de caractères à l'aide d'un pointeur.
#include <reg51.h>
typedef unsigned char uint8;
/* Signaux de contrôle */
sbit LCD_RS = P3^5;
sbit LCD_RW = P3^6;
sbit LCD_EN = P3^4;
/* Port de données */
#define LCD_DATA P0
/* Attente du drapeau BUSY */
void lcd_attendre(void)
{
uint8 statut;
LCD_DATA = 0xFF;
LCD_RS = 0;
LCD_RW = 1;
do
{
LCD_EN = 1;
statut = LCD_DATA;
LCD_EN = 0;
} while (statut & 0x80);
}
/* Envoi d'une commande */
void lcd_commande(uint8 cmd)
{
lcd_attendre();
LCD_RS = 0;
LCD_RW = 0;
LCD_DATA = cmd;
LCD_EN = 1;
LCD_EN = 0;
}
/* Envoi d'un caractère */
void lcd_caractere(uint8 car)
{
lcd_attendre();
LCD_RS = 1;
LCD_RW = 0;
LCD_DATA = car;
LCD_EN = 1;
LCD_EN = 0;
}
/* Position du curseur (ligne 1-2, colonne 1-16) */
void lcd_position(uint8 ligne, uint8 colonne)
{
uint8 adresse = (ligne == 1 ? 0x00 : 0x40) + (colonne - 1);
lcd_commande(0x80 | adresse);
}
/* Initialisation complète */
void lcd_initialiser(void)
{
lcd_commande(0x38); /* 8 bits, 2 lignes */
lcd_commande(0x0C); /* affichage on, curseur off */
lcd_commande(0x01); /* efface l'écran */
lcd_commande(0x06); /* curseur incrémenté */
lcd_position(1, 1);
}
/* Affichage d'une chaîne par pointeur */
void lcd_affiche_chaine(const uint8 *ptr)
{
while (*ptr != '\0')
lcd_caractere(*ptr++);
}
void main(void)
{
uint8 message[] = "Bonjour le 8051!";
lcd_initialiser();
lcd_affiche_chaine(message);
while (1);
}
Exemple de défilement avec un pointeur
En choisissant le mode d'entrée avec décalage de l'affichage (0x07) et en plaçant le curseur à la dernière colonne visible, chaque nouveau caractère pousse le contenu vers la gauche, créant un effet de défilement.
void temporiser(unsigned int ms)
{
unsigned int i, j;
for (i = 0; i < ms; i++)
for (j = 0; j < 120; j++);
}
void main(void)
{
uint8 texte[] = "Defilement C51 ";
uint8 *p = texte;
lcd_commande(0x38);
lcd_commande(0x0F); /* curseur clignotant */
lcd_commande(0x01); /* efface */
lcd_commande(0x07); /* curseur +, décalage gauche */
lcd_position(1, 16);
while (*p != '\0')
{
lcd_caractere(*p++);
temporiser(100);
}
while (1);
}