Changes between Initial Version and Version 1 of SujetTP3-2018


Ignore:
Timestamp:
Feb 22, 2018, 5:44:46 PM (7 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • SujetTP3-2018

    v1 v1  
     1{{{#!protected
     2
     3{{{#!comment
     4Ce TME a été créé par Julien Peeters et modifié par Franck Wajsbürt
     5}}}
     6
     7= TP3 : Pilotage d'un écran LCD en mode utilisateur et par un driver =
     8
     9
     10Objectifs:
     11* Configuration des GPIOs pour le pilotage d'un périphérique
     12* Fonctionnement d'un écran LCD et fonctions de base
     13* Affichage du monitoring système
     14* Ecriture d'un driver d'affichage
     15{{{#!comment
     16Ce dernier point est retiré parce trop long
     17* Usage de IOCTL
     18}}}
     19
     20Pré-requis (Raspberry Pi):
     21* Outils de compilation croisée
     22* Configuration et utilisation des GPIO
     23
     24Ressources:
     25* [[http://www.newhavendisplay.com/specs/NHD-0420DZ-FL-YBW.pdf | Datasheet du LCD de la plateforme]]
     26  * **newhaven display** est le fabriquant du module LCD, c'est donc, en principe la référence.
     27  * Dans ce document, il est dit que le contrôleur du LCD est le ST7066U, mais, sauf preuve du contraire, la séquence
     28    d'initialisation du LCD décrite dans la documentation du [[http://www.newhavendisplay.com/app_notes/ST7066U.pdf | ST7006U]]
     29    ne fonctionne pas...
     30* [[http://en.wikipedia.org/wiki/Hitachi_HD44780_LCD_controller | LCD Display HD44780]]
     31  [[https://www.sparkfun.com/datasheets/LCD/HD44780.pdf | Datasheet du HD44780]]
     32  * HD44780 est le contrôleur historique de la majorité des LCD de ce genre. La procédure d'initialisation fonctionne.
     33* [[http://web.alfredstate.edu/weimandn/lcd/lcd_addressing/lcd_addressing_index.html | Adressage de la mémoire interne de l'afficheur]]
     34  * Ce document définit comment est adressé la mémoire "vidéo" du LCD.
     35
     36Prenez le temps de parcourir les documents sur les afficheurs avant de commencer le TP.
     37
     38Le code à modifier se trouve en pièces jointes de cette page [[attachment:lcd_user.c]] et [[attachment:Makefile]]. Vous pourrez les copier dans un répertoire `TP3/lcd_user/`
     39
     40== 1. Configuration des GPIO pour le pilotage de l'écran ==
     41
     42L'é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.
     43
     44Dans 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).
     45
     46Les signaux de contrôle RS et E sont utilisés de la manière suivante:
     47* RS vaut 1 pour l'envoi d'une donnée (e.g. un caractère) et vaut 0 pour l'envoi d'une commande.
     48* 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.
     49
     50Voici le mapping des GPIO pour les différents signaux:
     51
     52||=   Signal LCD  =||=     GPIO     =||
     53||       RS        ||       7        ||
     54||       E         ||       8        ||
     55|| D4, D5, D6, D7  || 22, 23, 24, 25 ||
     56
     57
     58Pour le contrôle des GPIO, vous utiliserez ce que vous avez vu lors du précédent TP.
     59
     60Pour contrôler l'afficheur nous devons répondre aux questions suivantes:
     61Les réponses à ces questions se trouve dans la documentation de l'afficheur.
     62* Comment faut-il configurer les GPIOs pour les différents signaux de l'afficheur LCD ?
     63* Comment écrire des valeurs vers le LCD ?
     64* Quelles valeurs doivent être envoyées vers l'afficheur pour réaliser l'initialisation ?
     65* Comment demander l'affichage d'un caractère ?
     66* Comment envoyer des commandes telles que : l'effacement de l'écran, le déplacement du curseur, etc. ?
     67
     68Page 11 de la documentation : [[http://www.newhavendisplay.com/specs/NHD-0420DZ-FL-YBW.pdf | Datasheet du LCD de la plateforme]]
     69{{{#!c
     704-bit Initialization:
     71/**********************************************************/
     72void command(char i)
     73{
     74  P1 = i;                       //put data on output Port
     75  D_I =0;                       //D/I=LOW : send instruction
     76  R_W =0;                       //R/W=LOW : Write       
     77  Nybble();                     //Send lower 4 bits
     78  i = i<<4;                     //Shift over by 4 bits
     79  P1 = i;                       //put data on output Port
     80  Nybble();                     //Send upper 4 bits
     81}
     82/**********************************************************/
     83void write(char i)
     84{
     85  P1 = i;                       //put data on output Port
     86  D_I =1;                       //D/I=HIGH : send data
     87  R_W =0;                       //R/W=LOW : Write   
     88  Nybble();                     //Clock lower 4 bits
     89  i = i<<4;                     //Shift over by 4 bits
     90  P1 = i;                       //put data on output Port
     91  Nybble();                     //Clock upper 4 bits
     92}
     93/**********************************************************/
     94void Nybble()
     95{
     96  E = 1;
     97  Delay(1);                     //enable pulse width  >= 300ns
     98  E = 0;                        //Clock enable: falling edge
     99}
     100/**********************************************************/
     101void init()
     102{
     103  P1 = 0;
     104  P3 = 0;
     105  Delay(100);                   //Wait >40 msec after power is applied
     106  P1 = 0x30;                    //put 0x30 on the output port
     107  Delay(30);                    //must wait 5ms, busy flag not available
     108  Nybble();                     //command 0x30 = Wake up 
     109  Delay(10);                    //must wait 160us, busy flag not available
     110  Nybble();                     //command 0x30 = Wake up #2
     111  Delay(10);                    //must wait 160us, busy flag not available
     112  Nybble();                     //command 0x30 = Wake up #3
     113  Delay(10);                    //can check busy flag now instead of delay
     114  P1= 0x20;                     //put 0x20 on the output port
     115  Nybble();                     //Function set: 4-bit interface
     116  command(0x28);                //Function set: 4-bit/2-line
     117  command(0x10);                //Set cursor
     118  command(0x0F);                //Display ON; Blinking cursor
     119  command(0x06);                //Entry Mode set
     120}
     121/**********************************************************/
     122}}}
     123== 2. Fonctionnement de l'écran et fonctions de base ==
     124
     125Comme cela a été présenté en cours la prise en compte de la donnée est réalisée lors d'un front descendant du signal E.
     126Pour créer un front descendant:
     127* on place la donnée,
     128* puis le signal E est mis à 1 pendant 1µs puis remis à 0 pendant une 1µs supplémentaire pour garantir le délai entre deux commandes.
     129
     130||**Question:**\\Compléter la fonction lcd_strobe (nommée nybble dans le cours) qui permet de générer le signal E.
     131
     132[[Image(htdocs:png/command_lcd.png, width=900px, nolink)]]
     133
     134Nous 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.
     135
     136||**Question:**\\Compléter la fonction lcd_write4bits en vous aidant du cours.
     137
     138Nous 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.
     139
     140||**Question:**\\Compléter la fonction lcd_init qui réalise la séquence d'initialisation telle que vue en cours. Vérifiez son fonctionnement sur une carte Raspberry Pi. Vous devez être en mode 4 bits, 2 lignes, matrix5x8 ; allumer l'écran sans curseur ; demander d'écrire de gauche à droite sans déplacement des caractères.
     141
     142Vous êtes prêt à tester votre code et vérifier qu'il affiche correctement une chaine de caractère.
     143
     144||**Question:**\\Ecrivez un programme qui affiche la chaine de caractère "Hello World" sur l'afficheur. Vérifiez son fonctionnement sur une carte Raspberry Pi.
     145
     146Il peut être utile de manipuler la position du curseur pour choisir où placer les caractères sur l'afficheur.
     147
     148Pour 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).
     149
     150La mémoire DDRAM est construite de la manière suivante:
     151||0x00 ..... Ligne 1 ..... 0x13||
     152||0x40 ..... Ligne 2 ..... 0x53||
     153||0x14 ..... Ligne 3 ..... 0x27||
     154||0x54 ..... Ligne 4 ..... 0x67||
     155
     156On souhaites utiliser toutes les lignes
     157
     158|| **Question:**\\1. Ecrire une fonction lcd_set_cursor qui positionne le curseur aux coordonnées (x,y) avec x la colonne, y la ligne.\\2. Ecrire un programme qui affiche "Hello World" sur chacune des lignes de l'afficheur.
     159
     160== 3. Affichage du monitoring système ==
     161
     162Maintenant que vous disposer de tous les éléments pour contrôler l'afficheur LCD. Nous allons monitorer le système grâce au fichier /proc/loadavg dont le contenu est décrit comme:
     163{{{
     164The first three fields in this file are load average figures giving the number of jobs in the run queue (state R) or
     165waiting for disk I/O (state D) averaged over  1,  5, and 15 minutes.  They are the same as the load average numbers
     166given by uptime(1) and other programs.  The fourth field consists of two numbers separated by a slash (/). The first
     167of these is the number of currently runnable kernel scheduling entities (processes, threads).  The value after the
     168slash is the  number  of  kernel  scheduling entities that currently exist on the system.  The fifth field is the PID
     169of the process that was most recently created on the system.
     170}}}
     171
     172||**Question:**\\1. Ecrivez un programme qui lit le contenu du fichier /proc/loadavg et qui affiche son contenu sur l'afficheur avec une fréquence d'actualisation de 1 seconde\\2. Parser le contenu du fichier /proc/loadavg pour afficher des valeurs plus facilement compréhensibles.
     173
     174== 4. Driver basique pour le LCD ==
     175
     176Reprenez le pilote que vous aviez écrit pour les leds et modifiez la commande `write` de telle sorte que si vous appelez votre device /dev/lcd, vous puissiez écrire.
     177{{{#!bash
     178$ echo "Bonjour" > /dev/lcd
     179}}}
     180
     181Vous allez devoir remplacer usleep() par udelay() et ajouter un `#include <asm/delay.h>` au début du code de votre module (merci Arthur).
     182
     183}}}