1ef9816fd6b51b1501238c8c44071034.ppt
- Количество слайдов: 59
Driver de port parallèle Commande d’un module d’affichage LCD jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 1
Objectif du chapitre • Faire fonctionner un module d’affichage LCD couplé sur le port parallèle de la cible CEPC – – Étude sommaire du port parallèle standard des PC Étude sommaire du module LCD Écriture d’un driver pour ce module Écriture d’une application pour afficher deux lignes sur le module LCD – Téléchargement dans le CEPC – Exécution jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 2
Port Parallèle d’un PC (1) • Le port parallèle standard (SPP) est un port prévu dès l’origine du PC pour obtenir une liaison plus rapide que la liaison série de l’époque, utile pour commander une imprimante • Dans un PC-XT ou dans un PC-AT le SPP n’était pas sur la carte mère mais sur une carte additionnelle qui contenait aussi un port série • Carte à installer dans un connecteur du bus ISA jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 3
Port Parallèle d’un PC (2) • Il était possible d’installer sur le bus ISA deux cartes série/parallèle en choisissant par des straps deux décodages d’adresse possibles – 0 x 378 : Parallel Printer 1 (LPT 1) associé à l’IRQ 7 – 0 x 278 : Parallel Printer 2 associé à l’IRQ 5 • Cet adaptateur parallèle n’était même pas un boîtier spécifique mais l’association d’un PAL et de quelques latches et drivers constituant trois registres • Plus tard sont apparus des circuits spécifiques plus polyvalents jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 4
Port Parallèle d’un PC (3) • Registre de données (D 0 -D 7) – à l’adresse de base du port • Registre de Status (S 3 -S 7) – à l’adresse de base du port + 1 – utilisé pour ses cinq bits de poids forts seulement S 3 -S 7, S 0 -S 2 inutilisés ou inexistants • Registre de commande (C 0 -C 4) – à l’adresse de base du port + 2 – Utilisé pour ses cinq bits de poids faibles C 0 -C 4, C 5 C 7 inutilisés ou inexistants – ici nous n’utilisons que C 0 -C 4 jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 5
Registres du port parallèle Registre de données Adresse de base D 7 D 6 Poids fort D 5 D 4 D 3 D 2 Registre de status (lecture) D 1 D 0 Poids faible Adresse de base + 1 S 7 S 6 S 5 S 4 S 3 Registre de contrôle Adresse de base + 2 C 4 jc/md/lp-01/05 C 3 Module d'affichage LCD sur le port parallèle : corrigé C 2 C 1 C 0 6
Registres données et commande D 0 C 0 D 1 C 1 D 2 C 2 D 3 C 3 D 4 D 5 D 6 D 7 Registre données jc/md/lp-01/05 Buffer Registre commande Module d'affichage LCD sur le port parallèle : corrigé Buffer 7
Registre status • Inutilisé dans notre application jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 8
Écriture sur un port VOID WRITE_PORT_UCHAR(PUCHAR Port, UCHAR Value); Parameters Port [in] Pointer to the port that must be a mapped memory range in I/O space. Value [in] Byte to be written to the port. Return Values None. jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 9
Module d’affichage LCD HD 44780 • Le module possède – Une mémoire de 80 caractères : Display Data RAM (DD RAM) – Un générateur de police de caractère – Deux registres internes DR et IR • Taille de l’afficheur utilisé : – Nombre de lignes d’affichage : 2 – Nombre de caractères par ligne : 20 jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 10
Signaux du module LCD • • • Port de données D 0 -D 7 RS Register Select E Enable R/W Lecture/écriture, pour nous 0, écriture VDD Alimentation, pour nous sera prise sur le port sur la broche C 2 • VSS Masse • VL Contrôle du contraste, pour nous 0, contraste maximal jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 11
Câblage du module LCD sur le port parallèle Module d’affichage LCD D 7 D 6 D 5 D 4 D 3 D 2 D 1 D 0 RS E R/W VSS VL VDD VDD 10 KΩ D 7 D 6 D 5 D 4 D 3 D 2 D 1 D 0 10 KΩ C 3 C 0 Port parallèle 9 8 jc/md/lp-01/05 7 6 5 4 3 2 17 VDD VL à la masse donne le contraste maximum 1 Module d'affichage LCD sur le port parallèle : corrigé 12
Registres internes du module LCD • Deux registres internes – IR registre d’instruction – DR registre de données • Commande des registres par deux signaux – RS : Register Selector relié à la broche C 3 du port parallèle différencie ces deux registres – E : Enable relié à la broche C 0 du port parallèle valide l’introduction des données dans les registres jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 13
Séquence d’écriture dans IR et DR Repos IR RS=0 E=0 Repos DR RS=1 E=0 Donnée → IR RS=0 E→ 0 jc/md/lp-01/05 Donnée → DR RS=1 E→ 0 Module d'affichage LCD sur le port parallèle : corrigé 14
Commandes pour écrire IR • Signaux de commande en position de repos RS relié à C 3 et E relié à C 0 mais C 3 et C 0 sont complémentées d’où : commande. . 1 x x 1 (RS=0 E=0) • Mettre l’instruction sur le port parallèle D 0 -D 7 • Écrire cette instruction dans le registre IR commande. . 1 x x 0 (RS=0 E=1) • Retour à l’état de repos commande . . 1 x x 1 (RS=0 E=0) jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 15
Commandes pour écrire DR • Signaux de commande en position de repos RS relié à C 3 et E relié à C 0 mais C 3 et C 0 sont complémentées d’où : commande. . 0 x x 1 (RS=1 E=0) • Mettre la donnée sur le port parallèle D 0 -D 7 • Écrire cette donnée dans le registre DR commande. . 1 x x 0 (RS=1 E=1) • Retour à l’état de repos commande . . 1 x x 1 (RS=1 E=0) jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 16
Options • On peut commander la tension VDD avec la ligne C 2, ce qui évite une alimentation externe C 2 VDD 1 N 4148 + 1 µF • La ligne C 1 est réservée pour avoir un second signal Enable utilisé avec un afficheur à 4 lignes jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 17
Détail des commandes IR et DR • Afficheur LCD à deux lignes → C 1 inutilisé, à 0 Alimentation par le port → C 2 toujours à 1 • Repos en prévision d’une commande pour IR %1101 = 0 x. D «CTRL» C 2=1 RS=0 E=0 • Entrée de la commande dans IR %1100 = 0 x. C «CTRLEN» C 2=1 RS=0 E=1 • Repos en prévision d’une commande pour DR %0101 = 0 x 5 «DATA» C 2=1 RS=1 E=0 • Entrée de la commande dans DR %0100 = 0 x 4 «DATAEN» C 2=1 RS=1 E=1 jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 18
DDRAM du module LCD • Le module LCD contient une DDRAM gérée automatiquement par les écritures dans le registre DR • La donnée écrite dans le registre DR est transférée systématiquement dans la DDRAM à une adresse définie par un compteur d’adresse interne (AC) • AC incrémenté à chaque écriture dans DR • AC initialisé par écriture de l’instruction Set DDRAM address dans le registre IR jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 19
LCD à 2 lignes de 20 caractères DDRAM 0 x 00 0 x 13 Première ligne 20 caractères 0 x 27 0 x 40 0 x 53 0 x 54 Seconde ligne 20 caractères 0 x 67 jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 20
Instructions pour le LCD (1) • • • Clear Display: 0 x 01 Return Home: 0 x 02 Entry Mode Set: 0 x 04 à 0 x 07 (%000001 I/D S) – I/D = 1 incrément – S = 0 pas de décalage • Display ON/OFF: 0 x 08 à 0 x 0 F (%00001 D C B) – D = 0 display OFF – C = 0 cursor OFF – B = 0 blink OFF jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 21
Instructions pour le LCD (2) • Function Set: 0 x 38 pour nous (%001 DL N F 00) – DL=1 Interface 8 bits – N=0 LCD à deux lignes (0 pour une ligne) – F=0 Matrice 5 x 7 • Set DDRAM address: 0 x 80 à 0 x. FF (%1 AAAAAAA) – AAAAAAA jc/md/lp-01/05 Adresse à placer dans le compteur AC Module d'affichage LCD sur le port parallèle : corrigé 22
Initialisation du LCD • Timing à respecter après la mise sous tension • Séquence de commande obligatoire de configuration du LCD jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 23
Timing à respecter après Power On jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 24
Séquence d’initialisation • RESET: Instruction 0 x 30 (Function Set: interface 8 bits) envoyée 3 fois • Display OFF • Display ON • Clear Display • Function Set: taille de l’interface, nombre de lignes et police. (non modifiable ensuite) • Mode Set: gestion affichage (décalage texte, incrément d’adresse mémoire) jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 25
Exemple d’envoi de commande // Mise du port dans l’état repos commande WRITE_PORT_UCHAR(PARCOMMAND, CTRL); Sleep(15); // Attente de 15 ms après la mise sous tension // Function Set 1 (interface 8 bits) WRITE_PORT_UCHAR(PARDATA, 0 x 30); WRITE_PORT_UCHAR(PARCOMMAND, CTRLEN); Sleep(2); // Attente de 2 ms WRITE_PORT_UCHAR(PARCOMMAND, CTRL); Sleep(5); // Attente de 5 ms jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 26
Travail à réaliser • • Préparer une plate-forme Préparer un driver à inclure Générer le noyau avec le driver Préparer une application Générer l’application sans l’inclure avec le noyau Télécharger le noyau dans la cible Exécuter l’application jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 27
Driver • Le driver comprendra deux IOCTL – Écriture d’un caractère – Positionnement du curseur • On définira un projet PARA_DRV de type WCE Dynamic Link Library à inclure dans le noyau • On créera un fichier PARA. def que l’on inclura dans le projet PARA_DRV jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 28
Application • L’application – écrira un texte sur la ligne 1 du LCD – puis positionnera le curseur en début de ligne 2 – écrira un deuxième texte sur la ligne 2 • On définira l’application PARA_APP de type WCE Application à ne pas inclure dans le noyau jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 29
Driver Corrigé jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 30
PARA. def jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 31
#include
Driver (2) // Définition des IOCTL #define IOCTL_PUTC CTL_CODE(FILE_DEVICE_UNKNOWN, 2048, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_CURSEUR CTL_CODE(FILE_DEVICE_UNKNOWN, 2049, METHOD_BUFFERED, FILE_ANY_ACCESS) jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 33
Driver (3) // Définition des adresses du port parallèle #define PARBASE ((PUCHAR) 0 x 0378) #define PARDATA PARBASE #define PARCOMMAND PARBASE+2 // Définition des mots de commande #define CTRL 0 x. D #define CTRLEN 0 x. C #define DATA 0 x 5 #define DATAEN 0 x 4 jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 34
Driver (4) BOOL APIENTRY Dll. Main(HANDLE h. Module, DWORD ul_reason_for_call, LPVOID lp. Reserved) { return TRUE; } jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 35
Driver (5) DWORD PAR_Init(DWORD dw. Context) { DWORD dw. Ret = 1; RETAILMSG(1, (TEXT("PARA_DRV: PAR_Initn"))); // Mise du port dans l’état repos commande WRITE_PORT_UCHAR(PARCOMMAND, CTRL); Sleep(15); jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 36
Driver (6) // Envoi des trois Function Set de RESET // Positionnement de la donnée : 0 x 30 WRITE_PORT_UCHAR(PARDATA, 0 x 30); // Function Set 1 WRITE_PORT_UCHAR(PARCOMMAND, CTRLEN); Sleep(2); WRITE_PORT_UCHAR(PARCOMMAND, CTRL); Sleep(5); jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 37
Driver (7) // Function Set 2 WRITE_PORT_UCHAR(PARCOMMAND, CTRLEN); Sleep(2); WRITE_PORT_UCHAR(PARCOMMAND, CTRL); Sleep(1); // Function Set 3 WRITE_PORT_UCHAR(PARCOMMAND, CTRLEN); Sleep(2); WRITE_PORT_UCHAR(PARCOMMAND, CTRL); Sleep(10); jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 38
Driver (8) // Display OFF WRITE_PORT_UCHAR(PARDATA, 0 x 08); WRITE_PORT_UCHAR(PARCOMMAND, CTRLEN); Sleep(2); WRITE_PORT_UCHAR(PARCOMMAND, CTRL); Sleep(10); // Display ON WRITE_PORT_UCHAR(PARDATA, 0 x 0 F); WRITE_PORT_UCHAR(PARCOMMAND, CTRLEN); Sleep(2); WRITE_PORT_UCHAR(PARCOMMAND, CTRL); Sleep(10); jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 39
Driver (9) // Clear Display WRITE_PORT_UCHAR(PARDATA, 0 x 01); WRITE_PORT_UCHAR(PARCOMMAND, CTRLEN); Sleep(2); WRITE_PORT_UCHAR(PARCOMMAND, CTRL); Sleep(10); // Function Set (2 lignes, 8 bits) WRITE_PORT_UCHAR(PARDATA, 0 x 38); WRITE_PORT_UCHAR(PARCOMMAND, CTRLEN); Sleep(2); WRITE_PORT_UCHAR(PARCOMMAND, CTRL); Sleep(10); jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 40
Driver (10) // Mode Set (incrément, pas de décalage) WRITE_PORT_UCHAR(PARDATA , 0 x 06); WRITE_PORT_UCHAR(PARCOMMAND, CTRLEN); Sleep(2); WRITE_PORT_UCHAR(PARCOMMAND, CTRL); Sleep(10); // Mise du port dans l’état repos data WRITE_PORT_UCHAR(PARCOMMAND, DATA); return dw. Ret; } jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 41
Driver (11) BOOL PAR_Deinit(DWORD h. Device. Context) { BOOL b. Ret = TRUE; RETAILMSG(1, (TEXT("PARA_DRV: PAR_Deinitn"))); return b. Ret; } jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 42
Driver (12) DWORD PAR_Open(DWORD h. Device. Context, DWORD Access. Code, DWORD Share. Mode) { DWORD dw. Ret = 1; RETAILMSG(1, (TEXT("PARA_DRV: PAR_Openn"))); return dw. Ret; } jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 43
Driver (13) BOOL PAR_Close(DWORD h. Open. Context) { BOOL b. Ret = TRUE; RETAILMSG(1, (TEXT("PARA_DRV: PAR_Closen"))); return b. Ret; } jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 44
Driver (14) BOOL PAR_IOControl(DWORD h. Open. Context, DWORD dw. Code, PBYTE p. Buf. In, DWORD dw. Len. In, PBYTE p. Buf. Out, DWORD dw. Len. Out, PDWORD pdw. Actual. Out) { int val; BOOL b. Ret; jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 45
Driver (15) switch(dw. Code) { case IOCTL_PUTC: WRITE_PORT_UCHAR(PARDATA, p. Buf. In[0]); WRITE_PORT_UCHAR(PARCOMMAND, DATAEN); Sleep(2); WRITE_PORT_UCHAR(PARCOMMAND, DATA); break; jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 46
Driver (16) case IOCTL_CURSEUR: // Positionnement du curseur val=p. Buf. In[0]; // Commande 1 xxxxxxx (xxxxxxx position curseur) val=val+0 x 80; // Mise du port en repos commande WRITE_PORT_UCHAR(PARCOMMAND, CTRL); Sleep(2); jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 47
Driver (17) // Envoi de la commande de positionnement WRITE_PORT_UCHAR(PARDATA, val); WRITE_PORT_UCHAR(PARCOMMAND, CTRLEN); Sleep(2); WRITE_PORT_UCHAR(PARCOMMAND, CTRL); // Mise du port en repos data WRITE_PORT_UCHAR(PARCOMMAND, DATA); break; }// switch jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 48
Driver (18) *pdw. Actual. Out=1; return b. Ret; } jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 49
Application Corrigé jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 50
// Définition des" src="https://present5.com/presentation/1ef9816fd6b51b1501238c8c44071034/image-51.jpg" alt="Application (1) // #include nécessaires #include "stdafx. h" #include
Application (2) int WINAPI Win. Main(HINSTANCE h. Instance, HINSTANCE h. Prev. Instance, LPTSTR lp. Cmd. Line, int n. Cmd. Show) { jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 52
Application (3) // Déclarations et réservations HANDLE h. Device; CHAR carac 1[1]; DWORD dw. Nb; HANDLE h. Para; CHAR* pstring 1 = "essai port parallèlen"; CHAR* pstring 2 = "miracle ca marchen"; unsigned int i; jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 53
Application (4) // Chargement du driver h. Device=Register. Device(TEXT("PAR"), 1, TEXT("PARA_DRV. dll"), NULL); if(h. Device==0) { Message. Box(NULL, _T("Pb Register PAR 1: "), _T("PARA_APP"), MB_OK); return 0; } jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 54
Application (5) // Ouverture du driver h. Para=Create. File(TEXT("PAR 1: "), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); if(h. Para==INVALID_HANDLE_VALUE) { Message. Box(NULL, _T("Pb Ouverture PAR 1: "), _T("PARA_APP"), MB_OK); Deregister. Device(h. Device); Close. Handle(h. Device); return 0; } jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 55
Application (6) // Envoi première chaîne for(i=0; i
Application (7) // Positionnement du curseur au début de la ligne 2 carac 1[0]=0 x 40; Device. Io. Control(h. Para, IOCTL_CURSEUR, carac 1, 1, &dw. Nb, NULL); // Envoi deuxième chaîne for(i=0; i
Application (8) // Fermeture des handles Close. Handle(h. Para); Deregister. Device(h. Device); Close. Handle(h. Device); Message. Box(NULL, _T("Fin application PARA_APP"), _T("PARA_APP"), MB_OK); return 0; } jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 58
Conclusion • Nous avons construit un driver et une application rudimentaires pour commander un module d’affichage LCD installé sur un port parallèle standard de PC. jc/md/lp-01/05 Module d'affichage LCD sur le port parallèle : corrigé 59


