;************************************************************************** ; Routines pour la gestion de l'afficheur LCD avec controleur Hitachi * ; J.FRANCOMME - mars 2002 - * ; Lycée Louis Armand 321 rue lecourbe 75015 PARIS * ; web : http://francomme.fr.fm * ;************************************************************************** ; Chacune des procédures permet le retour au programme principal ; sans changer le contenu des registres de travail. ; LCD_Init --> pas de paramètre d'entrée ; Initialisation afficheur - Ecriture sur 2 lignes vers la droite - ; Afficheur effacé ; Affiche_Text --> paramètre d'entrée : ; Adresse de la chaine de caractères dans registre dptr avant appel ; CLS --> Pas de paramètre d'entrée ; Efface afficheur LCD - ; LCD_ATT_Flag --> Pas de paramètre d'entrée ; Lecture du bit Busy du controleur de l'afficheur - ; Sortie quand toutes les opérations demandées terminées ; attend --> Pas de paramètre d'entrée ; Temporisation courte ~= 0.5s ; attend_long --> Pas de paramètre d'entrée ; Temporisation longue ~= quelques secondes ; LCD_Ligne1 --> Pas de paramètre d'entrée ; Passage à la première ligne de l'afficheur ; LCD_Ligne2 --> Pas de paramètre d'entrée ; Passage à la deuxième ligne de l'afficheur ; clic_sonore --> Pas de paramètre d'entrée ; génère un clic sonore ;************************************************************************** $include (mon51dcl.inc) $include (reg_51.pdf) ; déclaration du module LCD de XEVA_DEMO, accessible zone XDATA à E000h EQU LCD_BASE 0E000h EQU DataEeprom 600h ; déclaration des accès au module LCD de XEVA_DEMO EQU LCD_IR_ECRITURE LCD_BASE+0 ; écriture instructions EQU LCD_DR_ECRITURE LCD_BASE+1 ; écriture données EQU LCD_IR_LECTURE LCD_BASE+2 ; lecture instructions EQU LCD_DR_LECTURE LCD_BASE+3 ; lecture données ;*********************************************************************** ; Chargement du moniteur pour le déboggage ; Emplacement du vecteur de démarrage ;*********************************************************************** code at 0 ljmp a51monitorinit ;*********************************************************************** ; Programme principal ;*********************************************************************** code at 100h ;Code placé dans la RAM a l'adresse indiquée public main: acall LCD_Init ; appel de la procédure d'initialisation de l'afficheur acall introduction ; appel de la procédure introduction - menu sjmp $ ;********************************************************************** ; fin programme principal ;********************************************************************** ;********************************************************************** ; Procédure d'initialisation et introduction personnalisée pour le TP ; TSEN1 ;********************************************************************** ; A l'initialisation, le curseur est sur la ligne 1 introduction: mov dptr,#invite_L1 ; chargement du pointeur de chaine à afficher lcall Affiche_Text ; appel de la procédure d'affichage lcall LCD_Ligne2 ; positionnement en debut de ligne 2 mov dptr,#nom_L2 ; chargement du pointeur de chaine à afficher lcall Affiche_Text ; affichage message ret ; retour au programme principal ;************************************************************************** ; configuration de base du module LCD * ; gestion de l'affichage à partir de la première ligne en haut à gauche * ; effacement de la totalité de la mémoire d'affichage * ; pas de curseur visible, le pointeur d'affichage se décale vers la droite* ; affichage cyclique par défaut sur deux rangées de 40 caractères * ;************************************************************************** ;Function set ;DB5=1 => (DB4=DL=1_8bits, DB3=N=1_2lignes, DB2=F=*) LCD_Init: lcall LCD_ATT_Flag mov A,#00111000b mov dptr,#LCD_IR_ECRITURE movx @dptr,a ;entry mode set ;DB2=1 => code d'initialisation mode d'entrée (DB1=I/D=1_increment, DB0=S=0_right) lcall LCD_ATT_Flag mov A,#00000110b mov dptr,#LCD_IR_ECRITURE movx @dptr,a ;Display on/off control ;DB3=1 => code de contrôle de l'affichage (DB2=D=1_on, DB1=C=1_display_c, DB0=B=0_no_blink_car: ON/OFF) lcall LCD_ATT_Flag mov A,#00001110b mov dptr,#LCD_IR_ECRITURE movx @dptr,a ;Clear display ;DB0=1 => code d'effacement de la totalité de la mémoire d'affichage et pointeur à l'@=0 lcall CLS ;Return Home lcall LCD_ATT_Flag mov A,#02h mov dptr,#LCD_IR_ECRITURE movx @dptr,a ; set ddrram_address ;DB7=1 => code d'initialisation du pointeur de position d'affichage avec lcall LCD_ATT_Flag mov A,#10000000b mov dptr,#LCD_IR_ECRITURE movx @dptr,a ret ;********************************************************************* ; Procédure d'affichage de texte sur l'afficheur ; l'adresse de début de la chaîne est chargée dans le registre dptr ; avant l'appel de cette procédure ;********************************************************************* Affiche_Text: push acc ; sauvegarde de l'accumulateur qui contient en général le code de la touche lu encore_affich: clr A movc A,@A+dptr ; lecture du caractère courant dans la chaine de caractères à afficher cjne A,#'$',suite_affich ; caractère suivant tant que l'on ne trouve pas le caractère '$' ajmp Fin_affich suite_affich: inc dptr ; incrémentation pointeur de chaine push dpl ; sauvegarde dptr dans la pile push dph lcall LCD_ATT_Flag ; lecture du bit busy de l'afficheur mov dptr,#LCD_DR_ECRITURE ; chargement du pointeur du registre de donnée en écriture dans dptr movx @dptr,a ; écriture du caractère dans la mémoire de l'afficheur (CGRAM) acall clic_sonore ; écho sonore de l'action sur une touche par le relais lcall attend ; attente entre l'affichage de chacun des caractères - pas obligatoire pop dph ; restitution du contenu du registre dptr pop dpl ajmp encore_affich ; caractère suivant Fin_affich: pop acc ; restitution du contenu original de l'accumulateur ret ;************************************************************************** ;Clear display ;************************************************************************** ;DB0=1 => code d'effacement de la totalité de la mémoire d'affichage et pointeur à l'@=0 CLS: push acc ; sauvegarde de l'accumulateur qui contient en général le code de la touche lu lcall LCD_ATT_Flag ; lecture du bit busy de l'afficheur mov A,#00000001b ; code correspondant au clear mov dptr,#LCD_IR_ECRITURE ; chargement du pointeur du registre d'instruction en écriture dans dptr movx @dptr,a ; écriture de la commande dans le registre instruction de l'afficheur pop acc ; restitution du contenu original de l'accumulateur ret ;************************************************************************** ; fonction d'attente avant l'envoi d'une nouvelle commande ; par scrutation du bit BF jusqu'à BF=0 (t#50µs ou 1.64ms selon instruction) ;************************************************************************** LCD_ATT_Flag: push dpl ; sauvegarde dptr dans la pile push dph push acc ; sauvegarde del'accumulateur qui contient en général le code de la touche lu mov dptr,#LCD_IR_LECTURE ; init dptr avec adresse registre instruction en lecture OCCUPE: movx a,@dptr ; lecture du registre d'instruction jb ACC.7,OCCUPE ; attente que le bit 7 (busy flag) = 0 pop acc ; restitution du contenu original de l'accumulateur pop dph ; restitution du contenu du registre dptr pop dpl ret ;************************************************************************** ;temporisation courte ;************************************************************************** attend: mov R0,#040h boucle1: R1,#0ffh ; Initialisation de la tempo courte boucle2: djnz R1,boucle2 ; temporisation logicielle ... estimation de la duree de la boucle ! djnz R0,boucle1 ret ;************************************************************************** ;temporisation longue ;************************************************************************** attend_long: mov R0,#07h boucl1: mov R1,#0ffh ; Initialisation de la tempo longue boucl2: mov R2,#0ffh boucl3: djnz R3,boucl3 djnz R1,boucl2 ; temporisation logicielle ... estimation de la duree de la boucle ! djnz R0,boucl1 ret ;******************************************************************* ; Procédure qui positionne le curseur au début de la première ligne ; modification du registre "set_DDRAM_Address" avec la valeur 080h ;******************************************************************* LCD_Ligne1: push dph ; sauvegarde dptr dans la pile push dpl push acc ; sauvegarde del'accumulateur qui contient en général le code de la touche lu mov A,#080h ; code correspondant au debut de la ligne 1 mov dptr,#LCD_IR_ECRITURE ; init dptr avec adresse registre instruction en ecriture movx @dptr,a ; ecriture dans le registre d'instruction pop acc ; restitution du contenu original de l'accumulateur pop dpl ; restitution du contenu du registre dptr pop dph ret ;******************************************************************* ; Procédure qui positionne le curseur au début de la deuxième ligne ; modification du registre "set_DDRAM_Address" avec la valeur 0c0h ;******************************************************************* LCD_Ligne2: push dph ; sauvegarde dptr dans la pile push dpl push acc ; sauvegarde del'accumulateur qui contient en général le code de la touche lu mov A,#0C0h ; code correspondant au debut de la ligne mov dptr,#LCD_IR_ECRITURE ; init dptr avec adresse registre instruction en ecriture movx @dptr,a ; ecriture dans le registre d'instruction pop acc ; restitution du contenu original de l'accumulateur pop dpl ; restitution du contenu du registre dptr pop dph ret ;****************************************************************************** ; Procédure qui produit un clic sonore entre chaque affichage de caractère ; il ne faut pas modifier les autres bits du port P1 qui sont utilisés pour le clavier ;****************************************************************************** clic_sonore: push acc ; sauvegarde del'accumulateur qui contient en général le code de la touche lu mov a,#00000001b ; le ou-exclusif avec le bit de poids faible revient à inverser celui-ci xrl P1,A ; à chaque fois que cette opération est effectuée pop acc ; restitution du contenu original de l'accumulateur ret ;******************************************************************* ; ma zone de données ;******************************************************************* code at DataEeprom invite_L1: db = 'BTS Electronique $' nom_L2: db = 'J.FRANCOMME $' END