Changes between Version 9 and Version 10 of IOC_T01


Ignore:
Timestamp:
Feb 1, 2022, 4:52:21 PM (3 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • IOC_T01

    v9 v10  
    236236fsi
    237237}}}
    238 
    239 
    240 = Pilotage d'un écran LCD en mode utilisateur et par un driver =
    241 
    242 
    243 L'objectifs est de comprendre le fonctionnement d'un écran LCD et ses fonctions de base
    244 
    245 Ressources:
    246 * newhaven display est le fabriquant du module LCD, c'est donc, en principe la référence.
    247   * Dans ce document ([[http://www.newhavendisplay.com/specs/NHD-0420DZ-FL-YBW.pdf | Datasheet du LCD du module]]), il est dit que le contrôleur du LCD est le ST7066U, mais, sauf preuve du contraire, la séquence
    248     d'initialisation du LCD décrite dans la documentation du [[http://www.newhavendisplay.com/app_notes/ST7066U.pdf | ST7006U]]
    249     ne fonctionne pas...
    250 * HD44780 est le contrôleur historique de la majorité des LCD de ce genre. La procédure d'initialisation fonctionne.
    251   * [[http://en.wikipedia.org/wiki/Hitachi_HD44780_LCD_controller | LCD Display HD44780]]
    252     [[https://www.sparkfun.com/datasheets/LCD/HD44780.pdf | Datasheet du HD44780]]
    253 * Le document suivant définit comment est adressé la mémoire "vidéo" du LCD.
    254   * [[http://web.alfredstate.edu/faculty/weimandn/lcd/lcd_addressing/lcd_addressing_index.html | Adressage de la mémoire interne de l'afficheur]]
    255 
    256 Prenez le temps de parcourir les documents sur les afficheurs avant de commencer à programmer.
    257 
    258 Le code à modifier se trouve en pièces jointes de cette page [htdocs:docs/lcd/lcd_user.c lcd_user.c] et [htdocs:docs/lcd/Makefile Makefile]. Vous pourrez les copier dans un répertoire `lcd_user`
    259 
    260 == 1. Configuration des GPIO pour le pilotage de l'écran ==
    261 
    262 L'écran LCD de type HD44780 dispose de plusieurs signaux de contrôle et de données. Les signaux de contrôle sont au nombre de 3: RS, RW et E. Les signaux de données sont au nombre de 4 ou 8 suivant le mode.
    263 
    264 Dans ce TP, nous utiliserons l'écran en mode 4-bit car la carte Raspberry Pi dispose d'un nombre limité de GPIO. De plus, le signal RW sera connecté directement à 0V (donc toujours en écriture) car nous n'allons gérer que les opérations d'écriture (Note: les GPIO de la carte Raspberry Pi fonctionnent en 3.3V, ils ne supportent pas les niveaux de tension 5V émis par l'afficheur, demandez-moi cela n'est pas clair).
    265 
    266 Les signaux de contrôle RS et E sont utilisés de la manière suivante:
    267 * RS vaut 1 pour l'envoi d'une donnée (e.g. un caractère) et vaut 0 pour l'envoi d'une commande (instruction).
    268 * E est un signal de validation; la valeur sur le bus de données (4 bits) est pris en compte à chaque front descendant de ce signal.
    269 
    270 Voici le mapping des GPIO pour les différents signaux:
    271 
    272 ||=   Signal LCD  =||=     GPIO     =||
    273 ||       RS        ||       7        ||
    274 ||       E         ||       27       ||
    275 || D4, D5, D6, D7  || 22, 23, 24, 25 ||
    276 
    277 Dans la documentation de l'afficheur, on peut savoir :
    278 * Comment faut-il configurer les GPIOs pour les différents signaux de l'afficheur LCD ?
    279 * Comment écrire des valeurs vers le LCD ?
    280 * Quelles valeurs doivent être envoyées vers l'afficheur pour réaliser l'initialisation ?
    281 * Comment demander l'affichage d'un caractère ?
    282 * Comment envoyer des commandes telles que : l'effacement de l'écran, le déplacement du curseur, etc. ?
    283 
    284 En particulier, page 11 de la documentation ([[http://www.newhavendisplay.com/specs/NHD-0420DZ-FL-YBW.pdf | Datasheet du LCD de la plateforme]]) se trouve du pseudo-code pour l'usage de l'afficheur.
    285 * P1 est un registre dont l'état est recopié sur les broches D0 à D7 (bit7 de P1 sur D7, bit6 sur D6, etc. jusqu'à D4).
    286 * D_I est un registre dont l'état est recopié sur RS qui indique si on envoie un caractère (D) ou une instruction (I).
    287 * R_W est un registre dont l'état est recopié sur RW
    288 * Delay() est une attente en microsecondes.
    289 
    290 {{{#!c
    291 4-bit Initialization:
    292 /**********************************************************/
    293 void command(char i)
    294 {
    295   P1 = i;                       //put data on output Port
    296   D_I =0;                       //D/I=LOW : send instruction
    297   R_W =0;                       //R/W=LOW : Write       
    298   Nybble();                     //Send lower 4 bits
    299   i = i<<4;                     //Shift over by 4 bits
    300   P1 = i;                       //put data on output Port
    301   Nybble();                     //Send upper 4 bits
    302 }
    303 /**********************************************************/
    304 void write(char i)
    305 {
    306   P1 = i;                       //put data on output Port
    307   D_I =1;                       //D/I=HIGH : send data
    308   R_W =0;                       //R/W=LOW : Write   
    309   Nybble();                     //Clock lower 4 bits
    310   i = i<<4;                     //Shift over by 4 bits
    311   P1 = i;                       //put data on output Port
    312   Nybble();                     //Clock upper 4 bits
    313 }
    314 /**********************************************************/
    315 void Nybble()
    316 {
    317   E = 1;
    318   Delay(1);                     //enable pulse width  >= 300ns
    319   E = 0;                        //Clock enable: falling edge
    320 }
    321 /**********************************************************/
    322 void init()
    323 {
    324   P1 = 0;
    325   P3 = 0;
    326   Delay(100);                   //Wait >40 msec after power is applied
    327   P1 = 0x30;                    //put 0x30 on the output port
    328   Delay(30);                    //must wait 5ms, busy flag not available
    329   Nybble();                     //command 0x30 = Wake up 
    330   Delay(10);                    //must wait 160us, busy flag not available
    331   Nybble();                     //command 0x30 = Wake up #2
    332   Delay(10);                    //must wait 160us, busy flag not available
    333   Nybble();                     //command 0x30 = Wake up #3
    334   Delay(10);                    //can check busy flag now instead of delay
    335   P1= 0x20;                     //put 0x20 on the output port
    336   Nybble();                     //Function set: 4-bit interface
    337   command(0x28);                //Function set: 4-bit/2-line
    338   command(0x10);                //Set cursor
    339   command(0x0F);                //Display ON; Blinking cursor
    340   command(0x06);                //Entry Mode set
    341 }
    342 /**********************************************************/
    343 }}}
    344 
    345 == 2. Fonctionnement de l'écran et fonctions de base ==
    346 
    347 La prise en compte de la donnée est réalisée lors d'un front descendant du signal E.
    348 Pour créer un front descendant:
    349 * on place la donnée,
    350 * puis le signal E est mis à 1 pendant 1µs.
    351 
    352 [[Image(htdocs:png/command_lcd.png, width=900px, nolink)]]
    353 
    354 Nous utilisons l'afficheur LCD en mode 4 bits. Or, les commandes et les données sont transmises sur 8 bits ou 1 octet. Ainsi, toutes les commandes et toutes les données sont transmises en deux étapes: les 4 bits de poids fort et ensuite les 4 bits de poids faible.
    355 
    356 Nous avons toutes les fonctions dont nous avons besoin. Maintenant regardons d'un peu plus près la phase d'initialisation de l'afficheur LCD. Au démarrage, l'afficheur est dans un mode non défini (8 bits ou 4 bits). Il faut donc le forcer en mode 4 bits.
    357 
    358 Vous êtes prêt à tester votre code et vérifier qu'il affiche correctement une chaine de caractère.
    359 erry Pi.
    360 
    361 Il peut être utile de manipuler la position du curseur pour choisir où placer les caractères sur l'afficheur.
    362 
    363 Pour cela, l'afficheur dispose de trois instructions: Cursor home, Display clear et Set DDRAM address. La dernière instruction est relative à la mémoire interne de l'afficheur (Display Data RAM).
    364 
    365 La mémoire DDRAM est construite de la manière suivante:
    366 ||0x00 ..... Ligne 1 ..... 0x13||
    367 ||0x40 ..... Ligne 2 ..... 0x53||
    368 ||0x14 ..... Ligne 3 ..... 0x27||
    369 ||0x54 ..... Ligne 4 ..... 0x67||
    370 
    371 On souhaites utiliser toutes les lignes
    372 
    373 || **Questions:**\\1. Répondez aux questions qui se trouve dans le code [htdocs:docs/lcd/lcd_user.c lcd_user.c] \\2. Ecrire une fonction lcd_set_cursor qui positionne le curseur aux coordonnées (x,y) avec x la colonne, y la ligne.\\3. Ecrire un programme qui affiche la chaine passée en paramètre sur chacune des lignes de l'afficheur.
    374 [[BR]]
    375 
    376 
    377 
    378238= Compte rendu
    379239