commande d’un afficheur lcd par fpga - document …denis.rabaste.free.fr/ressources/fpga/12_tp7...

22
Denis Rabasté 1/22 IUFM Aix Marseille Commande d’un afficheur LCD par FPGA La carte de développement DE2 comprend un afficheur LCD (Liquid Crystal Display) de 2 lignes de 16 caractères. Cette afficheur, dit « intelligent » est géré par un microcontrôleur avec lequel nous allons faire communiquer le FPGA de la carte DE2, afin d’afficher le texte de notre choix. Nous procéderons en plusieurs étapes : - dans un premier temps, nous nous contenterons d’afficher un seul caractère afin de maitriser la phase d’initialisation de cette communication entre le FPGA et le microcontrôleur ; - nous afficherons ensuite un message fixe sur les deux lignes ; - puis nous créerons un chronomètre qui affichera heures, minutes et secondes ; - enfin nous transformerons notre chronomètre en horloge en permettant le réglage des heures minutes et secondes. Initialisation de l’afficheur Comme le montre la figure ci-après extraite de la documentation constructeur (version complète disponible en documents ressource), la communication avec l’afficheur se fait via un bus de 8 bits, en positionnant les signaux RS, E et R/W. Suivant les niveaux logiques de ces signaux on lit ou on écrit dans un des trois registres, d’instruction, de données ou d’état. Plusieurs solutions permettent l’affichage d’un caractère sur la matrice LCD, nous nous contenterons de celle qui consiste à placer dans la mémoire DD-RAM (Display Data Random Access Memory) de l’afficheur le code ASCII du caractère souhaité, pour les lettres, chiffres et caractères « classiques » comme le montre le tableau en annexe 1. Le motif sera affiché sur la matrice à cristaux liquide à une position dépendant de son emplacement dans la mémoire DD-RAM. Le motif associé au caractère est mémorisé dans la CG ROM (Code Generator Read Only Memory). On notera qu’il est également possible de définir des motifs personnalisés dans la mémoire CG RAM (Code Generator Random Access Memory) Avant de pouvoir afficher un caractère, il faut initialiser la connexion entre le FPGA et le module LCD, en précisant le type de liaison (dans notre cas une liaison 8 bits parallèle imposée par la carte DE2), le nombre de lignes d’affichage (une ou deux), la fonte des caractères (5x8 ou 5x11 pixels), l’affichage ou non du curseur, le clignotement ou non de l’affichage, le mode de déplacement de l’affichage ou du curseur. La connectique entre l’afficheur et le FPGA est détaillée dans la documentation de la carte DE2 dont une partie est reproduite en annexe 3. La phase d’initialisation est décrite par l’ordinogramme suivant, la table d’instruction étant donnée en annexe 2.

Upload: phamlien

Post on 12-Sep-2018

365 views

Category:

Documents


13 download

TRANSCRIPT

Page 1: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Denis Rabasté 1/22 IUFM Aix Marseille

Commande d’un afficheur LCD par FPGA

La carte de développement DE2 comprend un afficheur LCD (Liquid Crystal Display) de 2 lignes de 16 caractères. Cette afficheur, dit « intelligent » est géré par un microcontrôleur avec lequel nous allons faire communiquer le FPGA de la carte DE2, afin d’afficher le texte de notre choix. Nous procéderons en plusieurs étapes :

- dans un premier temps, nous nous contenterons d’afficher un seul caractère afin de maitriser la phase d’initialisation de cette communication entre le FPGA et le microcontrôleur ;

- nous afficherons ensuite un message fixe sur les deux lignes ; - puis nous créerons un chronomètre qui affichera heures, minutes et secondes ; - enfin nous transformerons notre chronomètre en horloge en permettant le réglage des heures

minutes et secondes.

Initialisation de l’afficheur

Comme le montre la figure ci-après extraite de la documentation constructeur (version complète disponible en documents ressource), la communication avec l’afficheur se fait via un bus de 8 bits, en positionnant les signaux RS, E et R/W. Suivant les niveaux logiques de ces signaux on lit ou on écrit dans un des trois registres, d’instruction, de données ou d’état.

Plusieurs solutions permettent l’affichage d’un caractère sur la matrice LCD, nous nous contenterons de celle qui consiste à placer dans la mémoire DD-RAM (Display Data Random Access Memory) de l’afficheur le code ASCII du caractère souhaité, pour les lettres, chiffres et caractères « classiques » comme le montre le tableau en annexe 1. Le motif sera affiché sur la matrice à cristaux liquide à une position dépendant de son emplacement dans la mémoire DD-RAM. Le motif associé au caractère est mémorisé dans la CG ROM (Code Generator Read Only Memory). On notera qu’il est également possible de définir des motifs personnalisés dans la mémoire CG RAM (Code Generator Random Access Memory) Avant de pouvoir afficher un caractère, il faut initialiser la connexion entre le FPGA et le module LCD, en précisant le type de liaison (dans notre cas une liaison 8 bits parallèle imposée par la carte DE2), le nombre de lignes d’affichage (une ou deux), la fonte des caractères (5x8 ou 5x11 pixels), l’affichage ou non du curseur, le clignotement ou non de l’affichage, le mode de déplacement de l’affichage ou du curseur. La connectique entre l’afficheur et le FPGA est détaillée dans la documentation de la carte DE2 dont une partie est reproduite en annexe 3. La phase d’initialisation est décrite par l’ordinogramme suivant, la table d’instruction étant donnée en annexe 2.

Page 2: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 2/22 IUFM Aix Marseille

A la fin de la phase d’initialisation, l’afficheur est éteint (instruction « Display off ») ; il faudra donc le rallumer avant de pouvoir afficher quoi que ce soit.

Chaque opération de communication en mode écriture doit respecter le chronogramme suivant :

On peut donc remarquer que cette phase d’initialisation nous impose à la fois des temps longs (15 ms en début de phase) et courts (tH=10 ns) par exemple. Se pose alors le choix de la fréquence d’horloge associée à notre communication, sachant que nous disposons sur la carte DE2 d’une horloge de fréquence 50 MHz (soit une période de 20 ns) ; plusieurs solutions sont envisageables :

Page 3: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 3/22 IUFM Aix Marseille

- fonctionner avec l’horloge à 50 MHz, c’est la solution la plus simple au niveau de l’écriture du programme, mais elle présente les inconvénients d’être plus gourmande en ressources (comparateur pour déterminer la position de E par exemple), mais surtout de demander des temps de simulation importants lors de la mise au point (compteurs de modulo important).

- adapter l’horloge aux temps du cycle d’écriture, en particulier la durée de l’impulsion E

(PWEH=230 ns) ; on pourrait prendre une période d’horloge de 240 ns, ce qui conduirait à une division par 12 de l’horloge à 50 MHz ; cette solution permet de générer facilement l’impulsion E et conduit à des temps de simulation acceptables.

- notre objectif étant par la suite d’afficher le défilement des secondes, autant choisir tout de

suite un rapport de division qui nous permettra facilement de passer une période de la seconde par la suite (soit une division par 50 000 000 de l’horloge à 50 MHz). Choisissons alors une première division par 20 de l’horloge à 50 MHz (soit une fréquence de 2,5 MHz et une période de 400 ns), il suffira par la suite de diviser par 2 500 000 pour avoir notre fréquence de 1 Hz.

Le schéma général sera le suivant :

PIN_N2VCCH INPUT

PIN_G26VCCRAZ INPUT

PIN_L4LCD_ONOUTPUT

PIN_K2LCD_BLONOUTPUT

PIN_AE22DEL_RAZOUTPUT

PIN_J1PIN_J2PIN_H1PIN_H2PIN_J4PIN_J3PIN_H4PIN_H3

BUS_LCD[7..0]OUTPUT

PIN_K1RSOUTPUT

PIN_K4RWOUTPUT

VLDH VLD

divh

inst

modulo 20 Signed IntegerParameter Value Type

HVLDRAZ

ERSRW

LCD_ONLCD_BLON

DEL_RAZBUS_LCD[7..0]

cmd_lcd

inst1

HVLD

EOUTPUT PIN_K3

Le bloc « divh » divise la fréquence d’horloge par 20, tandis que le bloc séquenceur « cmd_lcd » permet d’envoyer les signaux vers l’afficheur. Le programme VHDL associé au bloc séquenceur est donné dans le dossier ressources (dossier ressources\tp_Quartus\TP7_aff_lcd_de2\1_init ) ; le séquenceur est organisé autour d’une machine d’état, définissant tous les états de l’initialisation et de l’écriture : -- définition des différents états type TYPE_ETAT is (ATT_15ms, FS1, FS2, FS3, FS4, DspOff, DspC, DspOn, EMS, W_DRAM, ATTENTE); signal ETAT:TYPE_ETAT;

Les états s’enchaînent alors comme décrit dans la phase d’initialisation, le passage d’un état au suivant est conditionné par une variable « tempo » qui passe au niveau logique 1 à la fin d’un comptage : process (H, RAZ) begin if RAZ='0' then ETAT<= ATT_15ms; elsif H'event and H = '1' then if VLD='1' then case ETAT is when ATT_15ms => -- phase d'initialisation if tempo='1' then ETAT <= FS1; else ETAT <=ATT_15ms; end if; when FS1 => -- phase d'initialisation if tempo='1' then ETAT <= FS2; else ETAT <=FS1; end if; when FS2 => -- phase d'initialisation if tempo='1' then ETAT <= FS3;

Page 4: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 4/22 IUFM Aix Marseille

else ETAT <=FS2; end if; when FS3 => -- phase d'initialisation if tempo='1' then ETAT <= FS4; else ETAT <=FS3; end if; when FS4 => -- phase d'initialisation if tempo='1' then ETAT <= DspOff; else ETAT <=FS4; end if; when DspOff => -- phase d'initialisation if tempo='1' then ETAT <= DspC; else ETAT <=DspOff; end if; when DspC => -- phase d'initialisation if tempo='1' then ETAT <= EMS; else ETAT <=DspC; end if; when EMS => -- allumage de l'afficheur if tempo='1' then ETAT <= DspOn; else ETAT <=EMS; end if; when DspOn => -- phase d'initialisation if tempo='1' then ETAT <= W_DRAM; else ETAT <=DspOn; end if; when W_DRAM => -- écriture d'un caractère if tempo='1' then ETAT <= ATTENTE ; else ETAT <=W_DRAM; end if; when ATTENTE => -- état d'attente if tempo='1' then ETAT <= ATTENTE ; else ETAT <=ATTENTE; end if; when others => ETAT <= ATT_15ms;-- en cas d'état non prévu, réinitialisation end case; end if ; end if; end process;

La durée du comptage dépend d’un entier « modulo » fonction de chaque état : process (H, RAZ) begin if RAZ='0' then compt <= (others => '0'); elsif (H 'event and H = '1') then if VLD='1' then if compt >= modulo-1 then compt <= (others => '0') ; else compt <= compt + 1 ; end if ; end if; end if; end process; -- génération du signal de temporisation définissant la durée du cycle tempo<='1' when compt=modulo-1 else '0'; -- génération du signal d'autorisation d'écriture permettant de respecter les temps E<='1' when compt=1 else '0';

Ce comptage permet également de positionner le signal E de validation des signaux envoyés vers l’afficheur. E est au niveau logique 1 uniquement lors du second état du compteur (compt=1).

Page 5: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 5/22 IUFM Aix Marseille

Les signaux envoyés sur le bus LCD (revoir annexe 2) sont défini pour chaque état par les instructions suivantes :

with ETAT select BUS_LCD <= X"00" when ATT_15ms, X"38" when FS1, -- conformément à l’initialisation préconisée par le constructeur X"38" when FS2, X"38" when FS3, X"38" when FS4, -- 8 bits, 2 lignes d'affichage, caractères en 5x8 points X"08" when DspOff, -- extinction de l'affichage, pas de curseur, pas de clignotement X"01" when DspC, -- rempli la DDRAM par 00h et place le compteur AC à 00h X"0C" when DspOn, -- allumage de l'affichage, pas de curseur, pas de clignotement X"06" when EMS, -- déplacement vers la droite, pas de décalage de l'affichage X"41" when W_DRAM,-- affichage de A X"00" when ATTENTE;

La durée du comptage dépend d’un entier « modulo » propre à chaque état, suivant la même méthode. Une simulation fonctionnelle donne les chronogrammes suivants (afin de simplifier, le signal de validation VLD est toujours au NL1 et l’horloge H à 2,5 MHz). Le premier chronogramme propose une vue générale :

Le chronogramme suivant détaille les premiers états d’initialisation :

Enfin voici le détail de l’écriture et du signal E :

Remarque : pour visualiser les signaux du bus LCD, il est plus simple de demander un affichage en hexadécimal (sélectionner le bus, puis « Properties »)

Page 6: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 6/22 IUFM Aix Marseille

A réaliser Ouvrir un nouveau projet dans Quartus, associer le fichier « cmd_lcd.vhd » du répertoire ressource (dossier ressources\tp_Quartus\TP7_aff_lcd_de2\1_init ) et compléter les parties manquantes ; effectuer une analyse et synthèse, puis réaliser une simulation fonctionnelle et vérifier que les temps nécessaires à chaque état sont respectés. Proposer une description pour le diviseur et tester votre solution. Assembler les deux descriptions dans un schéma général, compiler et programmer de FPGA. En cas de problème, les solutions sont disponibles en annexe et dans le répertoire ressource.

Affichage d’un message

Notre afficheur étant initialisé, nous allons maintenant pouvoir afficher un message. Au chapitre précédent, l’état W_DRAM envoyait sur le bus LCD le code ASCII correspondant au caractère « A » ; cette fois, à chaque appel de cet état, nous allons envoyer un octet, contenu dans une mémoire MSG (pour MeSsaGe), octet pointé par l’entier « i » : with ETAT select BUS_LCD <= X"00" when ATT_15ms, …………………………………….. MSG(i) when W_DRAM, -- affichage du contenu de la mémoire …………………………………….

L’entier « i » devra donc être déclaré, ainsi que sa valeur maximale 31, ce qui correspond à 32 emplacements mémoire, le nombre de caractères affichables, la première valeur de i étant 0. Il sera également nécessaire de :

- déclarer un type mémoire, comme un tableau, avec l’instruction VHDL « array », de 32 octets (voir l’aide mémoire VHDL) ;

- de définir un signal MSG de type mémoire ; - de définir les 32 octets contenu de cette mémoire, afin d’afficher le texte de votre choix.

Dans le chapitre précédent, l’initialisation a configuré l’afficheur de telle sorte qu’à chaque écriture en DDRAM, le compteur d’adresse (AC) soit incrémenté. La figure suivante montre la relation entre les adresses DDRAM et la position du motif sur l’afficheur :

Comme nous pouvons le constater le passage de la première ligne à la seconde nécessite un saut d’adresse de 0F à 40 (en hexadécimal), qui peut être réalisé avec l’instruction « Set DDRAM Adress » de l’afficheur. Nous définirons pour cela un nouvel état de passage en ligne 2 « Set_L2 » qui sera imbriqué dans la séquence à chaque fois que le pointeur « i »de mémoire arrive à la valeur 15 (la première valeur de i est 0) :

Page 7: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 7/22 IUFM Aix Marseille

when W_DRAM => -- écriture des caractères if tempo='1' then if i=imax/2 then ETAT <= SET_L2 ; i<=i+1 elsif i=imax then ETAT <= ATTENTE ; else i<=i+1; end if; else ETAT <=W_DRAM; end if; when SET_L2 => -- passage à la ligne if tempo='1' then ETAT <= W_DRAM ; else ETAT <=SET_L2; end if;

Il sera alors nécessaire de :

- définir le nouvel état créé dans la liste des états ; - définir la valeur de l’octet qu’il va envoyer sur le bus LCD (annexe 2) ; - définir la valeur du modulo associé à ce nouvel état afin de déterminer la durée de la

temporisation (annexe 2). A réaliser A partir de l’explorateur Windows, créer un nouveau dossier et y copier tout les fichiers du projet du chapitre précédent. Dans Quartus, ouvrir le projet contenu dans ce nouveau dossier et modifier le programme VHDL du séquenceur en fonction des consignes précédentes. Faire une analyse et synthèse de ce programme, le simuler, puis lorsqu’il est au point, programmer l’ensemble du projet (diviseur et séquenceur du schéma général) dans le FPGA. En cas de problème, vous trouverez les solutions en annexe, ainsi que la correction dans le répertoire ressource (dossier ressources\tp_Quartus\TP7_aff_lcd_de2\2_msg_fixe ).

Synthèse d’un chronomètre

Affichons maintenant des caractères évolutifs, par le projet d’un chronomètre rudimentaire (pour l’instant sans bouton d’arrêt). Le schéma d’implantation général sera le suivant :

PIN_N2

VCCH INPUTPIN_L4LCD_ONOUTPUT

PIN_K2LCD_BLONOUTPUT

PIN_AE22DEL_RAZOUTPUT

PIN_J1PIN_J2PIN_H1PIN_H2PIN_J4PIN_J3PIN_H4PIN_H3

BUS_LCD[7..0]OUTPUT

PIN_K1RSOUTPUT

PIN_K4RWOUTPUTHMOD_S[21..0]

VLD_LCDVLD_S

divh

inst

HVLD_SRAZ

HU[3..0]MNU[3..0]MND[3..0]

SU[3..0]SD[3..0]HD[1..0]

compt

inst5

250000022

lpm_constant0inst2

H

HVLD_S

VLD_S

RAZVCCRAZ INPUT

PIN_G26

EOUTPUT PIN_K3

HVLDRAZHU[3..0]MNU[3..0]MND[3..0]SU[3..0]SD[3..0]HD[1..0]

ERSRW

LCD_ONLCD_BLON

DEL_RAZBUS_LCD[7..0]

cmd_lcd

inst6

RAZ

Le diviseur a été modifié afin de générer un signal de validation VLD_S qui fournira au compteur une fréquence de 1 Hz , par division par 2 500 000 du signal de VLD_LCD, correspondant au signal de validation des chapitres précédents à 2,5 MHz. Afin d’avoir un système synchrone, et éviter ainsi des aléas dus aux temps de propagation, le signal VLD_S ne sera utilisé que comme signal de validation, pour l’horloge H à 50 MHz du compteur. Son temps à l’état haut ne correspondra donc qu’à une seule période de l’horloge générale, toute les secondes. Le modulo du diviseur sera externe à la description du diviseur, afin de permettre une éventuelle augmentation de la fréquence de VLD_S, ce qui autorisera une vérification facile du défilement des minutes et des heures (régler alors le modulo à 250). Nous utiliserons la « megafonction « lpm_constant » obtenue via le menu contextuel (clic droit au milieu de la page) puis « Insert », « Symbol » :

Page 8: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 8/22 IUFM Aix Marseille

Le compteur génère en BCD les signaux correspondant aux dizaines et unités pour les heures, minutes et secondes. Ces signaux sont envoyés au séquenceur d’affichage « cmd_LCD » qui intègre le code ASCII correspondant à la mémoire d’affichage. L’obtention du code ASCII se fait simplement en plaçant « 0011 » comme bit de poids fort devant le nombre BCD, grâce à l’opérateur de concaténation « & » par exemple. A réaliser Par la même méthode que pour les paragraphes précédents, créer un nouveau projet intégrant les fichiers de l’affichage d’un message. Modifier le diviseur pour obtenir le fonctionnement souhaité et le simuler. A partir du programme du compteur dans les documents ressources (ressources\tp_Quartus\TP7_dossier aff_lcd_de2\3_chr ono ), compléter et simuler jusqu’à obtenir le fonctionnement désiré. Modifier le séquenceur d’affichage et tester l’ensemble du projet. En cas de problème, vous trouverez les solutions en annexe, ainsi que la correction dans le répertoire ressource.

Synthèse d’une horloge

Nous allons maintenant modifier le projet précédent afin de pouvoir régler l’heure affichée par notre horloge. Nous implanterons les points suivants :

- l’appui sur le bouton poussoir KEY3 de la carte DE2 permet de passer du mode fonctionnement au mode réglage, avec la chronologie suivante :

o Premier appui, réglage des heures (mode 1) ; o Second appui, réglage des minutes (mode 2) ; o Troisième appui, réglage des secondes (mode 3) ; o Quatrième appui, retour au mode de fonctionnement normal (mode 0).

- l’appui sur le bouton poussoir KEY2 permet d’incrémenter le paramètre en cours de réglage, avec une vitesse d’incrémentation fonction de la durée de l’appui :

o Appui inférieur à 3 s, incrémentation au rythme d’un par seconde ; o Appui entre 3 et 6 s, incrémentation au rythme de deux par seconde ; o Appui supérieur à 6 s, incrémentation au rythme de quatre par seconde.

- l’appui sur KEY1 permet de décrémenter le paramètre en cours de réglage, avec la même logique que pour KEY2 ;

- l’appui sur KEY0 réinitialise l’horloge comme lors de projets précédents. Le schéma général retenu est le suivant :

Page 9: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 9/22 IUFM Aix Marseille

PIN_N2VCCH INPUT

PIN_G26VCCKEY0 INPUT

PIN_W26 VCCKEY3 INPUT

PIN_P23 VCCKEY2 INPUT

PIN_N23 VCCKEY1 INPUT

PIN_L4LCD_ONOUTPUT

PIN_K2LCD_BLONOUTPUT

PIN_AE22DEL_RAZOUTPUT

PIN_J1PIN_J2PIN_H1PIN_H2PIN_J4PIN_J3PIN_H4PIN_H3

BUS_LCD[7..0]OUTPUT

PIN_K1RSOUTPUT

PIN_K4RWOUTPUT

PIN_V18LED3OUTPUT

PIN_W19LED2OUTPUT

PIN_AF22LED1OUTPUT

250000022

lpm_constant0inst2

HVTSS[1..0]MOD_S[21..0]

VLD_LCDVLD_S

divh

inst

HVLD_SRAZMODE[1..0]I_D[1..0]

HU[3..0]MNU[3..0]MND[3..0]

SU[3..0]SD[3..0]HD[1..0]

compt

inst5

HVLD_SVLD_LCDBP3BP2BP1RAZ

LED3LED2LED1

VTSS[1..0]MODE[1..0]

I_D[1..0]

BP

inst1

VLD_SVTSS[1..0]

HVLD_S

MODE[1..0]RAZ

I_D[1..0]

VLD_LCD

MODE[1..0]

H

RAZ

H

VLD_LCDVLD_S

RAZ

VTSS[1..0]MODE[1..0]

I_D[1..0]

HVLDRAZHU[3..0]MNU[3..0]MND[3..0]SU[3..0]SD[3..0]HD[1..0]MODE[1..0]

ERSRW

LCD_ONLCD_BLON

DEL_RAZBUS_LCD[7..0]

cmd_lcd

inst6

EOUTPUT PIN_K3

La fonction anti-rebonds des boutons poussoirs est déjà implantée sur la carte DE2 Le bloc BP génère un signal MODE permettant de configurer le compteur et l’afficheur dans un des 4 modes décrits ci-dessus. Il génère également le signal VTSS permettant de modifier le rapport de division du diviseur (pour les modes autres que 0). Enfin, il fournit le signal I_D permettant dans les modes 1, 2 et 3, d’incrémenter, de décrémenter, ou de laisser en l’état (pas d’appui sur KEY1 ni KEY2) le paramètre à régler, par action sur le compteur. En mode 0, la machine d’état du séquenceur, balaye en permanence tout l’affichage, mettant à jour les valeurs des heures, minutes et secondes. Dans les autres modes, le comptage est arrêté et seuls les deux chiffres en cours de réglages sont susceptibles d’être modifiés sur l’affichage. La machine d’état se content alors de produire un balayage sur les deux chiffres en cours de réglage en ayant paramétré auparavant la configuration de l’afficheur pour faire clignoter l’affichage. Seul ces deux chiffres clignotent alors, et le reste de l’affichage est figé. Lors du retour au mode 0, on stoppe ce clignotement et on retourne dans la boucle principale où tout l’écran est balayé. A réaliser Par la même méthode que pour les paragraphes précédents, créer un nouveau projet intégrant les fichiers de synthèse du chronomètre. Remplacer les différentes descriptions VHDL par celles du dossier ressource (dossier ressources\tp_Quartus\TP7_aff_lcd_de2\4_horloge ), et ajouter le fichier « BP.vhd ». Compléter et tester chaque description, jusqu’à obtenir un ensemble fonctionnel. En cas de problème, vous trouverez les solutions en annexe, ainsi que la correction dans le répertoire ressource.

Page 10: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 10/22 IUFM Aix Marseille

Annexe 1 : contenu de la CG ROM de l’afficheur LCD

Annexe 2 : connexion de l’afficheur LCD sur la cart e DE2, boutons poussoirs et LED

Page 11: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 11/22 IUFM Aix Marseille

Annexe 2 : table d’instruction

Page 12: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 12/22 IUFM Aix Marseille

Annexe 4 : Initialisation de l’afficheur

Programme du diviseur library ieee; use ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; -- ce programme génère un signal VLD_LCD résultant -- de la division par 20 de l'horloge H à 50 MHz entity divh is generic (modulo : integer range 0 to 31 :=20); port( H : in std_logic; VLD : out std_logic) ; end divh; architecture arch OF divh is signal compt : std_logic_vector (4 downto 0); begin process (H) begin if (H 'event and H = '1') then if compt >= modulo-1 then compt <= (others => '0'); else compt <= compt + 1 ; end if ; end if; end process; VLD<='1' when compt=0 else '0'; end arch;

Programme du séquenceur library ieee; use ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; entity cmd_lcd is port( H, VLD, RAZ : in std_logic; E, RS, RW, LCD_ON, LCD_BLON, DEL_RAZ : out std_logic ; BUS_LCD : OUT std_logic_vector (7 downto 0)); end cmd_lcd; architecture arch OF cmd_lcd is -- définition des différents état type TYPE_ETAT is (ATT_15ms, FS1, FS2, FS3, FS4, DspOff, DspC, DspOn, EMS, W_DRAM, ATTENTE); signal ETAT:TYPE_ETAT; -- compteur nécessaire pour les différentes temporisations signal compt : std_logic_vector (15 downto 0); -- le modulo du compteur est variable suivant les instructions, tempo valide le passage à l'état suivant signal tempo : std_logic ; signal modulo : integer ; begin LCD_ON <='1' ; -- mise sous tension de l'afficheur LCD_BLON <='1' ; -- validation du retro-éclairage DEL_RAZ<=RAZ ; --visualisation de la réinitialisation par bouton poussoir -- description du fonctionnement de la machine d'état process (H, RAZ) begin if RAZ='0' then ETAT<= ATT_15ms; elsif H'event and H = '1' then if VLD='1' then case ETAT is when ATT_15ms => -- phase d'initialisation if tempo='1' then ETAT <= FS1;

Page 13: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 13/22 IUFM Aix Marseille

else ETAT <=ATT_15ms; end if; when FS1 => -- phase d'initialisation if tempo='1' then ETAT <= FS2; else ETAT <=FS1; end if; when FS2 => -- phase d'initialisation if tempo='1' then ETAT <= FS3; else ETAT <=FS2; end if; when FS3 => -- phase d'initialisation if tempo='1' then ETAT <= FS4; else ETAT <=FS3; end if; when FS4 => -- phase d'initialisation if tempo='1' then ETAT <= DspOff; else ETAT <=FS4; end if; when DspOff => -- phase d'initialisation if tempo='1' then ETAT <= DspC; else ETAT <=DspOff; end if; when DspC => -- phase d'initialisation if tempo='1' then ETAT <= EMS; else ETAT <=DspC; end if; when EMS => -- phase d'initialisation if tempo='1' then ETAT <= DspOn; else ETAT <=EMS; end if; when DspOn => -- allumage de l'afficheur if tempo='1' then ETAT <= W_DRAM; else ETAT <=DspOn; end if; when W_DRAM => -- écriture d'un caractère if tempo='1' then ETAT <= ATTENTE ; else ETAT <=W_DRAM; end if; when ATTENTE => -- état d'attente if tempo='1' then ETAT <= ATTENTE ; else ETAT <=ATTENTE; end if; when others => ETAT <= ATT_15ms;-- en cas d'état non prévu, réinitialisation end case; end if ; end if; end process; -- description du compteur de temporisation process (H, RAZ) begin if RAZ='0' then compt <= (others => '0'); elsif (H 'event and H = '1') then if VLD='1' then if compt >= modulo-1 then compt <= (others => '0') ; else compt <= compt + 1 ; end if ; end if; end if; end process; -- génération du signal de temporisation définissant la durée du cycle

Page 14: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 14/22 IUFM Aix Marseille

tempo<='1' when compt=modulo-1 else '0'; -- génération du signal d'autorisation d'écriture permettant de respecter les temps E<='1' when compt=1 else '0'; -- description des sorties de la machine d'état

with ETAT select BUS_LCD <= X"00" when ATT_15ms, X"38" when FS1, X"38" when FS2, X"38" when FS3, X"38" when FS4, -- 8 bits, 2 lignes d'affichage, caractères en 5x8 points X"08" when DspOff, -- extinction de l'affichage, pas de curseur, pas de clignotement X"01" when DspC, -- rempli la DDRAM par 00h et place le compteur AC à 00h X"0C" when DspOn, -- allumage de l'affichage, pas de curseur, pas de clignotement X"06" when EMS, -- déplacement vers la droite, pas de décalage de l'affichage X"41" when W_DRAM,-- affichage de A X"00" when ATTENTE; -- la commande RS n'est au NL1 que lors de la phase d'écriture with ETAT select RS <= '1' when W_DRAM , '0' when others; RW<='0'; -- la lecture n'est pas utilisée -- valeur des différentes temporisation

with ETAT select modulo <= 65000 when ATT_15ms, -- valeur de 37500 mis à 65000 par sécurité 12000 when FS1, --4,1ms =>10 250 mis à 12 000 par sécurité 300 when FS2, --100µs => 250 mis à 300 par sécurité 120 when FS3, --39µs => 98 mis à 120 par sécurité 120 when FS4, 120 when DspOff, 4000 when DspC, --1,53ms =>3 825 mis à 4000 par sécurité 120 when DspOn, 120 when EMS, 130 when W_DRAM, --43µs => 108 mis à 130 par sécurité 1 when ATTENTE; -- évite le passage à 1 de E end arch;

Page 15: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 15/22 IUFM Aix Marseille

Annexe 5 : Affichage d’un message

Seule la description du séquenceur est à modifier : - ajouter l’état SET_L2 dans la définition des états : -- définition des différents états type TYPE_ETAT is (ATT_15ms, FS1, FS2, FS3, FS4, DspOff, DspC, DspOn, EMS, W_DRAM, ATTENTE, SET_L2);

- ajouter la déclaration d’une mémoire de 32 mots de 8 bits et d’un pointeur : -- définition d'un tableau et de l'indice de lecture où sera stocké un message à afficher constant imax : integer:=31; signal i : integer range 0 to 31; type MESSAGE is array (0 to imax) of std_logic_vector(7 downto 0); signal MSG : MESSAGE;

- définir le contenu de la mémoire : -- définition du contenu de la mémoire MSG(0)<=x"10"; MSG(1)<=x"10"; MSG(2)<=x"10"; MSG(3)<=x"10"; MSG(4)<=x"44"; MSG(5)<=x"65"; MSG(6)<=x"76"; MSG(7)<=x"69"; MSG(8)<=x"65"; MSG(9)<=x"6E"; MSG(10)<=x"73"; MSG(11)<=x"10"; MSG(12)<=x"10"; MSG(13)<=x"10"; MSG(14)<=x"10"; MSG(15)<=x"10"; MSG(16)<=x"10"; MSG(17)<=x"10"; MSG(18)<=x"71"; MSG(19)<=x"75"; MSG(20)<=x"69"; MSG(21)<=x"10"; MSG(22)<=x"74"; MSG(23)<=x"75"; MSG(24)<=x"10"; MSG(25)<=x"65"; MSG(26)<=x"73"; MSG(27)<=x"10"; MSG(28)<=x"21"; MSG(29)<=x"10"; MSG(30)<=x"10"; MSG(31)<=x"10";

- le pointeur i doit être remis à 0 lors d’un appui sur RAZ, faute de quoi, l’affichage ne se fera plus après une réinialisation : process (H, RAZ) begin if RAZ='0' then ETAT<= ATT_15ms; i<=0; elsif H'event and H = '1' then

- insérer la gestion du passage à la ligne dans la machine d’état : when W_DRAM => -- écriture des caractères if tempo='1' then if i=imax/2 then ETAT <= SET_L2 ; i<=i+1 elsif i=imax then ETAT <= ATTENTE ; else i<=i+1; end if; else ETAT <=W_DRAM; end if; when SET_L2 => -- passage à la ligne if tempo='1' then ETAT <= W_DRAM ; else ETAT <=SET_L2; end if;

- définir les caractéristiques de l’état SET_L2 et la nouvelle valeur du bus LCD lors de l’état W_DRAM : with ETAT select BUS_LCD <= X"00" when ATT_15ms, …………………………………….. MSG(i) when W_DRAM, -- affichage du contenu de la mémoire X"C0" when SET_L2, -- passage à la ligne 2 …………………………………….

with ETAT select modulo <= 65000 when ATT_15ms, -- valeur de 37500 mis à 65000 par sécurité …………………………………. 120 when SET_L2, ………………………………

Page 16: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 16/22 IUFM Aix Marseille

Annexe 6 : synthèse d’un chronomètre

Le diviseur : library ieee; use ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; -- ce programme fournit des signaux de validation à 2,5 MHz pour VLD_LCD -- et 1 Hz pour VLD_S si le paramètre d'entrée MOD_S est réglé à 2 500 000 entity divh is port( H : in std_logic; MOD_S : in std_logic_vector (21 downto 0); VLD_LCD, VLD_S : out std_logic) ; end divh; architecture arch OF divh is constant modulo : integer:=20; signal compt_LCD : std_logic_vector (4 downto 0); signal compt_s : std_logic_vector (21 downto 0); signal VALID_LCD : std_logic ; begin process (H) begin if (H 'event and H = '1') then if compt_LCD >= modulo-1 then compt_LCD <= (others => '0'); else compt_LCD <= compt_LCD + 1 ; end if ; end if; end process; VALID_LCD<='1' when compt_LCD=0 else '0'; process (H) begin if (H 'event and H = '1') then if VALID_LCD='1' then if compt_s >= MOD_S-1 then compt_s <= (others => '0'); else compt_s <= compt_s + 1 ; end if; end if ; end if; end process; VLD_S<='1'when (compt_LCD=0 and compt_s=0) else '0'; VLD_LCD<=VALID_LCD; end arch;

Le compteur : library ieee; use ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; -- ce programme permet de compteur les secondes (SD et SU), les minutes (MD et MU) -- les heures (HD et HU) à partir d'un horloge H à 50 MHz -- et d'un signal de validatin VLD_S à 1 Hz entity compt is port( H, VLD_S, RAZ : in std_logic; HU, MNU, MND, SU, SD : out std_logic_vector (3 downto 0); HD : out std_logic_vector (1 downto 0)); end compt; architecture arch OF compt is

Page 17: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 17/22 IUFM Aix Marseille

signal SHU, SMU, SMD, SSU, SSD : std_logic_vector (3 downto 0); signal SHD : std_logic_vector (1 downto 0); begin process (H,RAZ) begin if RAZ='0' then SSU <= X"0"; SSD <= X"0"; -- remise à 0 SMU <= X"0"; SMD <= X"0"; SHU <= X"0"; SHD <= "00"; -- dizaines d'heure sur 2 bits elsif (H 'event and H = '1')and VLD_S='1' then if SSU<9 then SSU<=SSU+1 ; else SSU <= X"0"; -- débordement des unités de secondes if SSD<5 then SSD<=SSD+1 ; else SSD <= X"0"; -- débordement des dizaines de secondes if SMU<9 then SMU<=SMU+1 ; else SMU <= X"0";-- débordement unité mn if SMD<5 then SMD<=SMD+1 ; else SMD <= X"0";-- débordement dizaines mn if (SHU<9 and not (SHD=2 and SHU=3)) then SHU<=SHU+1 ; else SHU <= X"0"; --dbdmt unité h if (not (SHD=2 and SHU=3)) then SHD<=SHD+1 ; else SHD <= "00"; SHU <= X"0";--dbdmt dzn h end if ; end if ; end if; end if; end if ; end if ; end if ; end process ; SU<=SSU; SD<=SSD; MNU<=SMU; MND<=SMD; HU<=SHU; HD<=SHD; end arch;

Modification du séquenceur d’affichage : - modification de l’entité : entity cmd_lcd is port( H, VLD, RAZ : in std_logic; E, RS, RW, LCD_ON, LCD_BLON, DEL_RAZ : out std_logic ; HU, MNU, MND, SU, SD : in std_logic_vector (3 downto 0); HD : in std_logic_vector (1 downto 0); BUS_LCD : OUT std_logic_vector (7 downto 0)); end cmd_lcd;

- modification de la mémoire : -- définition du contenu de la mémoire -- affichage de "Bonjour, il est " sur la première ligne

MSG(0)<=x"42"; MSG(1)<=x"6F"; MSG(2)<=x"6E"; MSG(3)<=x"6A"; MSG(4)<=x"6F"; MSG(5)<=x"75"; MSG(6)<=x"72"; MSG(7)<=x"2C"; MSG(8)<=x"10"; MSG(9)<=x"69"; MSG(10)<=x"6C"; MSG(11)<=x"10"; MSG(12)<=x"65"; MSG(13)<=x"73"; MSG(14)<=x"74"; MSG(15)<=x"10"; MSG(16)<=x"3"& "00" & HD ; -- code ASCII des dizaines d'heures (2 bits) MSG(17)<=x"3" & HU ; -- code ASCII des unités d'heures (4 bits) MSG(18)<=x"68"; -- "h" MSG(19)<=x"10"; MSG(20)<=x"10"; MSG(21)<=x"3" & MND ; -- code ASCII des dizaines de minutes (4 bits) MSG(22)<=x"3" & MNU ; -- code ASCII des unités de minutes (4 bits) MSG(23)<=x"6D"; -- "m" MSG(24)<=x"6E"; --"n" MSG(25)<=x"10"; MSG(26)<=x"10"; MSG(27)<=x"3" & SD ; -- code ASCII des dizaines de secondes (4 bits) MSG(28)<=x"3" & SU ; -- code ASCII des unités de secondes (4 bits) MSG(29)<=x"73"; --"s" MSG(30)<=x"10"; MSG(31)<=x"10";

Page 18: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 18/22 IUFM Aix Marseille

Annexe 7 : synthèse d’une horloge

Programme de gestion des boutons poussoirs : library ieee; use ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; -- ce programme permet de compter les appuis sur BP3 -- et incrémenter la sortie MODE (4 possibilité : fonctionnement ou 3 réglages) -- il permet également de déterminer la durée d'appui sur BP2 et BP3 -- ce qui permettra de modifier la valeur de VTSS (modification du modulo du diviseur) -- suivant que BP2 ou BP3 sont appuyé, on agit sur I_D -- pour passer en mode incrémentation, décrémentation ou attente -- les anti-rebons sont réalisé par la carte DE2 entity BP is port( H, VLD_S, VLD_LCD, BP3, BP2, BP1, RAZ : in std_logic; LED3, LED2, LED1 : out std_logic; VTSS, MODE, I_D : out std_logic_vector(1 downto 0)) ; end BP; architecture arch OF BP is signal S1, S2, SBP3 : std_logic ; signal cmpt_md : std_logic_vector(1 downto 0); signal vitesse : std_logic_vector(3 downto 0); begin -- détection de front descendant (appui) sur BP3 -- SBP3 présentera un NL1 pendant une période de H à chaque appui -- l'utilisation du signal de validation VLD_LCD permet une bonne réactivité lors d'un appui process (H) begin if (H'event and H = '1') then if VLD_LCD='1' then S1 <= not BP3; S2<= S1; end if; end if; end process; SBP3<= S1 AND NOT S2; -- comptage du nombre d'appuis sur BP3, détermination du mode de fonctionnement : -- normal (comptage, MODE=0), réglage des heures (MODE=1), -- réglage de minutes (MODE=2) ou réglages des secondes (MODE=3) process (H) begin if (H'event and H = '1') then if RAZ='0' then cmpt_md <= (others=> '0'); elsif (VLD_LCD='1' and SBP3='1') then cmpt_md<=cmpt_md+1; end if; end if; end process; MODE<=cmpt_md; -- incrémetation ou décrémentation des variables lors des réglages, I_D<= "01" when BP1='0' else -- incrémentation "10" when BP2='0' else -- décrémentation "00"; -- attente -- modification de la fréquence de VDL_S du diviseur par VTSS en fonction du temps d'appui sur PB1 ou PB2 -- l'utilisation du signal de validation VLD_S permet un réglage convivial des paramètres process (H, RAZ, BP1, BP2, VLD_S) begin if (RAZ='0'or (BP1='1' and BP2='1')) then vitesse<=(others=> '0'); elsif (H'event and H = '1') and VLD_S='1' and (BP1='0' or BP2='0') then if vitesse=15 then vitesse<=(others=>'1'); else vitesse<=vitesse+1; end if; end if; end process; -- il faut tenir compte de la variation de vitesse de l'horloge imposée par VTSS

Page 19: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 19/22 IUFM Aix Marseille

VTSS<= "00" when vitesse<4 else "01" when (vitesse>=4 and vitesse<9) else "10"; -- visualisation de l'appui sur les boutons poussoirs LED1<= BP1; LED2<= BP2; LED3<= BP3; end arch;

Diviseur : library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; -- ce programme divise l'horloge à 50 MHz pour obtenir un signal VLD_LCD à 2,5 MHz -- et un signal VLD_S de fréquence 1 Hz si VTSS=0, 2 Hz si VTSS=1, 4 Hz si VTSS=2 -- (dans le cas où l'entrée MOD_S vaut 2 500 000) entity divh is port( H : in std_logic; VTSS : in std_logic_vector (1 downto 0); MOD_S : in std_logic_vector (21 downto 0); VLD_LCD, VLD_S : out std_logic) ; end divh; architecture arch OF divh is constant modulo : integer:=20; signal modulo_s : std_logic_vector (21 downto 0); signal compt_LCD : std_logic_vector (4 downto 0); signal compt_s : std_logic_vector (21 downto 0); signal VALID_LCD : std_logic ; begin -- génération du signal de validation d'horloge de la gestion de l'affichage LCD -- division par modulo (20) de l'horloge à 50 MHz, soit 2,5 MHz process (H) begin if (H 'event and H = '1') then if compt_LCD >= modulo-1 then compt_LCD <= (others => '0'); else compt_LCD <= compt_LCD + 1 ; end if ; end if; end process; VALID_LCD<='1' when compt_LCD=0 else '0'; -- génération du signal d'horloge à 1 s si VTSS=0, 1/2 s si VTSS=1, 1/4 s si VTSS=2 modulo_s <= MOD_S when VTSS=0 else -- modulo pour 1s "0" & MOD_S(21 downto 1) when VTSS=1 else -- division par 2 du modulo pour 1/2s "00" & MOD_S(21 downto 2) ; -- division par 4 du modulo pour 1/4s process (H) begin if (H 'event and H = '1') then if VALID_LCD='1' then

if compt_s >= modulo_s -1 then compt_s <= (others => '0'); else compt_s <= compt_s + 1 ; end if; end if ; end if; end process; VLD_S<='1'when (compt_LCD=0 and compt_s=0) else '0'; VLD_LCD<=VALID_LCD; end arch;

Page 20: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 20/22 IUFM Aix Marseille

Compteur : library ieee; use ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; -- ce programme permet de compteur les secondes (SD et SU), les minutes (MD et MU) -- les heures (HD et HU) à partir d'un horloge H à 50 MHz -- et d'un signal de validatin VLD_S à 1 Hz -- l'entrée MODE permet soit de compter, soit de configurer heures, minutes et secondes -- l'entrée I_D permet d'incrémenter ou décrémenter l'affichage entity compt is port( H, VLD_S, RAZ : in std_logic; MODE, I_D : in std_logic_vector(1 downto 0); HU, MNU, MND, SU, SD : out std_logic_vector (3 downto 0); HD : out std_logic_vector (1 downto 0)); end compt; architecture arch OF compt is -- signaux nécessaires au comptage signal SHU, SMU, SMD, SSU, SSD : std_logic_vector (3 downto 0); signal SHD : std_logic_vector (1 downto 0); -- comptage synchrone begin process (H,RAZ,VLD_S) begin if RAZ='0' then SSU <= X"0"; SSD <= X"0"; SMU <= X"0"; SMD <= X"0"; SHU <= X"0"; SHD <= "00"; elsif (H 'event and H = '1')and VLD_S='1' then -- mode 0 d'affichage des heures minutes et secondes if MODE=0 then if SSU<9 then SSU<=SSU+1 ; else SSU <= X"0"; if SSD<5 then SSD<=SSD+1 ; else SSD <= X"0"; if SMU<9 then SMU<=SMU+1 ; else SMU <= X"0"; if SMD<5 then SMD<=SMD+1 ; else SMD <= (others => '0'); if (SHU<9 and not (SHD=2 and SHU=3)) then SHU<=SHU+1 ; else SHU <= X"0"; if (not (SHD=2 and SHU=3))

then SHD<=SHD+1 ; else SHD <= "00"; SHU <= X"0"; end if ; end if ; end if; end if; end if ; end if ; -- mode 1 et réglage par incrémentation des heures elsif MODE=1 and I_D=1 then if (SHU<9 and not (SHD=2 and SHU=3))

then SHU<=SHU+1 ; else SHU <= X"0"; if (not (SHD=2 and SHU=3)) then SHD<=SHD+1 ; else SHD <= "00"; SHU <= X"0"; end if ; end if ; -- mode 2 et réglage par incrémentation des minutes elsif MODE=2 and I_D=1 then if SMU<9 then SMU<=SMU+1 ; else SMU <= X"0"; if SMD<5 then SMD<=SMD+1 ; else SMD <= X"0"; end if ; end if ; -- mode 3 et réglage par incrémentation des secondes elsif MODE=3 and I_D=1 then if SSU<9 then SSU<=SSU+1 ; else SSU <= X"0"; if SSD<5 then SSD<=SSD+1 ; else SSD <= X"0"; end if ; end if ; -- mode 1 et réglage par décrémentation des heures

Page 21: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 21/22 IUFM Aix Marseille

elsif MODE=1 and I_D=2 then if SHU>0 then SHU<=SHU-1 ; else SHU <= X"9"; if SHD>0 then SHD<=SHD-1 ; else SHD <= "10"; SHU<=X"3"; end if ; end if ; -- mode 2 et réglage par décrémentation des minutes elsif MODE=2 and I_D=2 then if SMU>0 then SMU<=SMU-1 ; else SMU <= X"9"; if SMD>0 then SMD<=SMD-1 ; else SMD <= X"5"; end if ; end if ; -- mode 3 et réglage par décrémentation des secondes elsif MODE=3 and I_D=2 then if SSU>0 then SSU<=SSU-1 ; else SSU <= X"9"; if SSD>0 then SSD<=SSD-1 ; else SSD <= X"5"; end if ; end if ; end if; end if ; end process ; -- envoi vers l'affichage SU<=SSU; SD<=SSD; MNU<=SMU; MND<=SMD; HU<=SHU; HD<=SHD; end arch;

Modification du séquenceur : - modification de l’entité : entity cmd_lcd is port( H, VLD, RAZ : in std_logic; E, RS, RW, LCD_ON, LCD_BLON, DEL_RAZ : out std_logic ; HU, MNU, MND, SU, SD : in std_logic_vector (3 downto 0); HD, MODE : in std_logic_vector (1 downto 0); BUS_LCD : OUT std_logic_vector (7 downto 0)); end cmd_lcd;

- ajout d’états : -- définition des différents états type TYPE_ETAT is (ATT_15ms, FS1, FS2, FS3, FS4, DspOff, DspC, DspOn, EMS, W_DRAM,SET_L2, RtrnHm, Bl_On, Bl_Off, SET_AC, W_RGL_U, W_RGL_D);

- déclaration du signal d’adresse du paramètre à régler : -- pointage du paramètre à régler signal Adr : std_logic_vector (7 downto 0) ;

- définition de sa valeur en fonction du mode : -- détermination de l'adresse à pointer en fonction du mode with MODE select Adr <= X"C0" when "01", --pointage des dizaines des heures, adresse "100 0000" X"C5" when "10", --pointage des dizaines des minutes X"CB" when "11", --pointage des dizaines des secondes X"00" when others;

- modification de la machine d’état : when W_DRAM => -- affichage du message et des paramètres -- si mode 01, passage dans la boucle d'affichage des paramètres à régler -- en mode 00, gestion du pointeur de mémoire et du passage à la ligne if tempo='1' then if MODE="01" then ETAT<=Bl_On; elsif i=imax/2 then ETAT <= SET_L2 ; i<=i+1; elsif i=imax then ETAT <= W_DRAM ; i<=0;

Page 22: Commande d’un afficheur LCD par FPGA - Document …denis.rabaste.free.fr/ressources/FPGA/12_TP7 cde lcd DE2.pdf · Le programme VHDL associé au bloc séquenceur est donné dans

Commande de l’afficheur LCD de la carte DE2

Denis Rabasté 22/22 IUFM Aix Marseille

else i<=i+1; end if; else ETAT <=W_DRAM; end if; when Bl_On => -- clignotement du caractère if tempo='1' then ETAT <= SET_AC ; else ETAT <=Bl_On; end if; when SET_AC => -- positionnement à l'adresse des dizaines du paramètre à régler -- configuration du pointeur de la mémoire de message if tempo='1' then ETAT <= W_RGL_D ; if MODE="01" then i<=16; elsif MODE="10" then i<=21; else i<=27; end if; else ETAT <=SET_AC; end if; when W_RGL_D =>-- affichage des dizaines du paramètre à régler if tempo='1' then ETAT <=W_RGL_U ; i<=i+1;-- incrémentation du pointeur else ETAT <=W_RGL_D; end if; when W_RGL_U =>-- affichage des unité du paramètre à régler -- rotation en boucle sur les paramètres à régler -- sortie si retour en mode 00 if tempo='1' then if MODE="00" then ETAT<=Bl_Off ; else ETAT <=SET_AC ; end if; else ETAT <=W_RGL_U; end if; when Bl_Off => --arrêt du clignotement if tempo='1' then ETAT <=W_DRAM; else ETAT <=Bl_Off; end if; when SET_L2 => -- passage sur la seconde ligne if tempo='1' then ETAT <= W_DRAM ; else ETAT <=SET_L2; end if; when others => ETAT <= ATT_15ms;-- en cas d'état non prévu, réinitialisation

- description du bus LCD pour les nouveaux états : with ETAT select BUS_LCD <=…………………………………….. X"0D" when Bl_On, -- clignotement du caractère courant X"0C" when Bl_Off, -- arrêt du clignotement Adr when Set_AC, -- positionnement sur le caractère à régler MSG(i) when W_RGL_U,-- écriture des unités du caractères en cours de réglage MSG(i) when W_RGL_D;-- écriture des dizaines du caractères en cours de réglage

- valeur de RS pour les nouveaux états : -- RS est au NL1 lors des phases d'écriture en mémoire DDRAM with ETAT select RS <= '1' when W_DRAM, '1' when W_RGL_U, '1' when W_RGL_D, '0' when others;

- temporisation associée aux nouveaux états : with ETAT select modulo <= 65000 when ATT_15ms, ……………………………………………………………………….. 120 when Bl_On, 120 when Bl_Off, 120 when Set_AC, 130 when W_RGL_U, 130 when W_RGL_D;