;---------------------------------------------------------------------------- ; C O M P T E U R D E J O U R S B L A N C S E T R O U G E S ; ; T A R I F T E M P O E D F ;---------------------------------------------------------------------------- ; ; SPECIFICATIONS : - microcontrôleur ST62T20 (EPROM 4 Ko - quartz 8 MHz) ; -------------- - décodage de la trame Pulsadis EDF, ; - afficheur LCD, 1 ligne, 16 caractères (LM16155), ; - sauvegarde par pile 9v en cas de coupure secteur, ; - indication d'état de fonctionnement (symboles), ; - indication de détection de trame Pulsadis (.), ; - boutons 'correction ou RAZ compteurs', ; - bouton RESET. ; ;---------------------------------------------------------------------------- ; FONCTION : ; --------- ; Ce programme permet la réalisation d'un compteur des jours BLANCS et ROUGES ; du tarif TEMPO d'EDF. ; ; Pour celà, il décode la trame PULSADIS pour en extraire les impulsions ; relatives à TEMPO (imp. 18, 21, 24, 29, 33, 36 et 39). ; ; Le contenu des compteurs et affiché sur un afficheur LCD. Des symboles ; représentent la situation tarifaire du jour courant (jour bleu, blanc ou ; rouge) ainsi que celle du lendemain (entre 20h00 et 6h00). ; ; Les compteurs peuvent être réinitialisés et/ou corrigés à l'aide de ; touches. ;---------------------------------------------------------------------------- ; Fichier : tempo01.asm ; ; Auteur : alb ; ; Version : 1.0 - 28/02/2001 ; ; Révision : 1.1 - 27/04/2003 ; portage du programme sous l'environnement Raisonance (RIDE ST6) ;---------------------------------------------------------------------------- ; Code Option Byte : (série 'C' seulement) ; - chien de garde : HWD ; - OSG : oui ; - Timer pull-up : non ; - NMI pull-up : non ; - LVD reset : oui ; - oscillateur : quartz ; - ext. STOP mode : non ;---------------------------------------------------------------------------- ; ;########################## D E C L A R A T I O N ########################### ;*** déclaration des segments TABROM SEGMENT DATAROM PROGRAM SEGMENT CODE PAGE 0 DATARAM SEGMENT DATA PAGE STATIC ; Registre DRx (PortX) - Pas de port C ! - PA EQU dra ; port A PB EQU drb ; port B ; Constantes : DEB_ROM EQU 0080H ; émulation modèle ST6220 CLS EQU 1 ; valeur pour effacer l'afficheur HOME EQU 2 ; valeur pour la position 'home' BLEU EQU 0 ; état : bleu BLANC EQU 1 ; : blanc ROUGE EQU 2 ; : rouge CAR_B EQU 3 ; caractère 'B' personnalisé CAR_R EQU 4 ; caractère 'R' personnalisé N1 EQU 18 ; num. 1e impulsion attendue N2 EQU 21 ; num. 2e impulsion attendue N3 EQU 24 ; num. 3e impulsion attendue N4 EQU 29 ; num. 4e impulsion attendue N5 EQU 33 ; num. 5e impulsion attendue N6 EQU 36 ; num. 6e impulsion attendue N7 EQU 39 ; num. 7e impulsion attendue CHIEN EQU 0FEH PRECHARG EQU 238 ; T = 238 * 1,428 ms (f = 700,28 Hz) QUARTDEP EQU 140 ; nb quarts période signal à intégrer SEUIL EQU 100 TOPDEP EQU 3 FENETOPN EQU 10 TESTTOPN EQU 2 FENETR1 EQU (15+(50 * N1)) / 4 ; délai en nb d'interruptions FENETR2 EQU (15+(50 * N2)) / 4 FENETR3 EQU (15+(50 * N3)) / 4 FENETR4 EQU (15+(50 * N4)) / 4 FENETR5 EQU (15+(50 * N5)) / 4 FENETR6 EQU (15+(50 * N6)) / 4 FENETR7 EQU (15+(50 * N7)) / 4 FINTRAM EQU (15+(50 * 40)) / 4 ; 40ème impulsion ; RAM interne 60 octets (de 84H à 0BFH) : RSEG DATARAM Table: DSB 8 Fintabl EQU 8CH Mesures: DSB 2 ; 2 octets Mespos: DSB 1 ; 1 octet Nbint: DSB 1 ; nb d'interruptions totalisées Imp18: DSB 1 ; état de l'impulsion 18 Imp21: DSB 1 ; état de l'impulsion 21 Imp24: DSB 1 ; état de l'impulsion 24 Imp29: DSB 1 ; état de l'impulsion 29 Imp33: DSB 1 ; état de l'impulsion 33 Imp36: DSB 1 ; état de l'impulsion 36 Imp39: DSB 1 ; état de l'impulsion 39 SauvAcc: DSB 1 ; reg. sauvegarde accu lors de l'int Cur_Pos: DSB 1 ; position du curseur LCD Sauv_a: DSB 1 ; sauvegarde du registre A Sauv_x: DSB 1 ; sauvegarde registre CopyPB: DSB 1 ; image du port B pour les E/S Puls: DSB 1 ; témoin de détection de trame jBLC: DSB 1 ; compteur des jours BLANCS jRGE: DSB 1 ; compteur des jours ROUGES Symb: DSB 1 ; contient n° symbole à afficher SymbD: DSB 1 ; contient n° symbole tarif lendemain Cpt1: DSB 1 ; compteurs pour temporisations Cpt2: DSB 1 Buf: DSB 1 ; tampon Flag: DSB 1 ; indicateurs CptAppui: DSB 1 ; compteur 'touche appuyée' Somme1: DSB 1 ; sommes pour contrôle du décodage Somme2: DSB 1 ; bits : bPSI EQU 3 ; TSCR.3 : bit de marche/arrêt timer bTMZ EQU 7 ; TSCR.7 : bit de redémarrage du timer bE EQU 0 ; PB.0 : ligne E LCD bRS EQU 1 ; PB.1 : ligne RS LCD bVER EQU 3 ; PB.3 : sélection version (n. u.) bRaZ EQU 4 ; PB.4 : cde de RAZ générale bAdjB EQU 5 ; PB.5 : correc. compteur BLANC (B.P.) bAdjR EQU 6 ; PB.6 : correc. compteur ROUGE (B.P.) bSEC EQU 7 ; PB.7 : entrée signal EDF (CA/N) ; indicateurs (flags) : fDem EQU 0 ; Flag.0 : indique couleur lendemain ;############################# M A C R O S ################################ outpb macro val_PB ; MACRO : écriture sur le port B ld a,val_PB ; valeur à écrire sur le port B ld PB,a ; écrit sur le port endm ;---------------------------------------------------------------------------- swap_a macro ; MACRO : intervertion des quartets rlc a ; décale avec carry rlc a rlc a rlc a rlc a endm ;############################################################################ RSEG TABROM ;####################### - Zone des Tableaux en ROM - ####################### ; tableau de définition des nouveaux symboles (codes 0 à 7) du LCD DRSEG AT 0080H PAGE 0 Tab_Car: DB 00H,00H,08H,15H ; caractère n°0 (jour BLEU) '~' DB 02H,00H,00H,00H DB 0CH,0CH,0CH,0CH ; caractère n°1 (jour BLANC) '!' DB 00H,0CH,0CH,00H DB 02H,04H,08H,1FH ; caractère n°2 (jour ROUGE) DB 02H,04H,08H,00H DB 1EH,19H,19H,1EH ; caractère n°3 ('B' personnalisé) DB 19H,19H,1EH,00H DB 1EH,19H,19H,1EH ; caractère n°4 ('R' personnalisé) DB 1CH,1AH,19H,00H ; messages à afficher sur l'écran LCD : DRSEG AT 0080H+64 PAGE 0 M_Init: DB "TEMPO [alb] v1.0",0 M_Ini2: DB " d:- " ; message "vide" d'init. DB 3 DB ":-- " DB 4 DB ":--",0 ; fin message "vide" M_Dem: DB " d:",0 M_jR: DB " " ; " R:" DB 4 DB ":",0 ;**************************************************************************** ;* P R O G R A M M E * ;**************************************************************************** RSEG PROGRAM Reset: ldi wdr,CHIEN ; chargement chien de garde ldi ddra,11111111B ldi ora, 00001111B ldi PA, 00000000B ; PA.0 à PA.3 : sorties push-pull ldi ddrb, 00000011B ; PB.7 : entrée num. (& ana.) ldi orb, 00000011B ; autres : entrées avec pull-up ldi drb, 00000000B ; PB.0/1 : sorties push-pull ldi CopyPB,00000000B ; 'image' du port B set bSEC,orb ; conf. PB.7 en entrée analogique set bSEC,CopyPB outpb CopyPB ldi adcr,00110000B ; initialisation du convertisseur A/N ; pré-initialisation du timer ldi ior,00010000B ; interruption timer seulement ldi tcr,PRECHARG ; compte pour le relancement du timer ; initialisation mémoire ldi y,Table ; Y : index réservé à l'interruption ldi v,Somme2-Table ldi x,Table ; X : index réservé au prog. principal clr a Raz: ld (x),a ; remise à zéro de la mémoire inc x dec v jrnz Raz reti ; retour au mode normal call TempoLcd res bSEC,orb ; conf. PB.7 en entrée numérique ldi wdr,CHIEN ; jette un os au chien clr Puls ; init. témoin détection trame ('.') clr jBLC ; init. compteur de jours BLANCS clr jRGE ; init. compteur de jours ROUGES clr Symb ; init. n° symbole (BLEU) clr SymbD ; init. n° symbole lendemain (BLEU) clr Flag ; init. des flags ; initialisation de l'afficheur LCD ; ldi drwr,Tab_Car.w ; init. reg. 'data ROM window' ldi drwr,window(Tab_Car) ; init. reg. 'data ROM window' call Init_Lcd ; initialisation de l'afficheur ; ldi drwr,M_Init.w ; init. 2nd 'data ROM window' ; ldi x,M_Init.d ; init. du pointeur de message ldi drwr,window(M_Init); init. 2nd 'data ROM window' ldi x,winoffset(M_Init); init. du pointeur de message call Aff_Mess ; affiche le message d'init. call Tempo4s ; temporisation de 4 s call Cls_Lcd ; efface l'afficheur ; affichage du message standard ; ldi x,M_Ini2.d ldi x,winoffset(M_Ini2) call Aff_Mess ; affiche " ~ d:- B:-- R:--" ldi Cur_Pos,01H call SetCur ; curseur en 1 ld a,Symb call Aff_Car ; affiche symbole '~' ; configure & démarre le timer ldi tscr,01111010B ; 1/4 de 8 MHz (T = 1,428 ms) ;-------------------------------------------------------------- ; DECODAGE DE LA TRAME PULSADIS ;-------------------------------------------------------------- ; 1. Recherche de l'impulsion de départ : Princip: ld a,Mesures AttInt: cp a,Mesures ; on attend l'incrémentation jrnz ReDep jp AttInt ReDep: clr Mespos clr Mesures clr Mesures+1 ld a,Mesures Depart: cp a,Mesures ; on attend l'incrémentation jrz Tst_BP jp Dep1 Tst_BP: jrr bRaZ,PB,Tst_RaZ ; appui touche RAZ générale ? jrr bAdjB,PB,Corr_Blc ; appui touche correction cpt BLANC ? jrr bAdjR,PB,Corr_Rge ; appui touche correction cpt ROUGE ? jp Depart Tst_RaZ: call RaZ_UC ; RAZ générale si confirmée jp Princip Corr_Blc: call AjusteB ; ajustage ou RAZ du compteur jp Aff_Cpt ; affiche nouvelle valeur Corr_Rge: call AjusteR jp Aff_Cpt ; affiche nvlle valeur Dep1: ld a,Mesures cp a,Mespos ; toutes les mesures sont positives ? jrz Dep2 jp ReDep ; non : on attend Dep2: cpi a,TOPDEP ; nbre prévu d'imp. [+] successives ? jrz Dep3 jp Depart ; non ; 2. Test de présence de la première impulsion attendue : Dep3: ldi v,FENETR1/256 ldi w,FENETR1 MOD 256 call TestImp ; impulsion présente au temps indiqué ? ld Imp18,a ; résultat du test ; 3. Test de présence de la deuxième impulsion attendue : ldi v,FENETR2/256 ldi w,FENETR2 MOD 256 call TestImp ; test si impulsion présente ld Imp21,a ; résultat du test ; 4. Test de présence de la 3ième impulsion attendue : ldi v,FENETR3/256 ldi w,FENETR3 MOD 256 call TestImp ; test si impulsion présente ld Imp24,a ; résultat du test ; 5. Test de présence de la 4ième impulsion attendue : ldi v,FENETR4/256 ldi w,FENETR4 MOD 256 call TestImp ; test si impulsion présente ld Imp29,a ; résultat du test ; 6. Test de présence de la 5ième impulsion attendue : ldi v,FENETR5/256 ldi w,FENETR5 MOD 256 call TestImp ; test si impulsion présente ld Imp33,a ; résultat du test ; 7. Test de présence de la 6ième impulsion attendue : ldi v,FENETR6/256 ldi w,FENETR6 MOD 256 call TestImp ; test si impulsion présente ld Imp36,a ; résultat du test ; 8. Test de présence de la 7ième impulsion attendue : ldi v,FENETR7/256 ldi w,FENETR7 MOD 256 call TestImp ; test si impulsion présente ld Imp39,a ; résultat du test ldi v,FINTRAM/256 ldi w,FINTRAM MOD 256 call TestImp ; pour attendre dernière impulsion ; 9. Utilisation des signaux reçus : call Exploite ; détermination état ; 10. Affichage de l'état sur le LCD : call Cls_Lcd ; efface l'afficheur inc Puls ; chgt état du témoin jrr 0,Puls,Temoin00 ; indique détection d'une trame ldi a,'.' ; alterne le symbole suivant... jp Temoin01 ; ...la parité de Puls Temoin00: ldi a,' ' Temoin01: call Aff_Car ; affiche '.' ou ' ' ; affiche 'couleur' du jour courant ld a,Symb call Aff_Car ; affiche symbole (bleu, blanc, rouge) ; si décodé, affiche couleur du lendemain jrr fDem,Flag,Aff_Cpt ; couleur du lendemain ? ; ldi x,M_Dem.d ldi x,winoffset(M_Dem) call Aff_Mess ; message "d:" ld a,SymbD call Aff_Car ; affiche symb. tarif lendemain ; affichage des compteurs Aff_Cpt: ldi Cur_Pos,7 ; affichage de "B:xx" call SetCur ldi a,CAR_B call Aff_Car ; 'B' ldi Cur_Pos,40H ; 2nd moitiée ligne call SetCur ldi a,':' call Aff_Car ld a,jBLC call AffOctet ; ldi x,M_jR.d ; affichage de "R:xx" ldi x,winoffset(M_jR) call Aff_Mess ld a,jRGE call AffOctet jp Princip ;**************************************************************************** ;* CORRECTION OU RAZ DU COMPTEUR BLANC * ;* ----------------------------------- * ;* Entr‚e : * * ;* Sortie : jBLC * ;* Modifie : TSCR,WDR,Cpt1,Cpt2,CptAppui * ;**************************************************************************** ; un appui court incrémente le compteur, ; un appui long (>= 2 s) provoque une RAZ du compteur BLANC. AjusteB: ldi CptAppui,16 ; init. compteur touche appuyée Adj3B: ldi Cpt2,50 ; décompteur 2 (50 * 2,5 ms) Adj2B: ldi Cpt1,0 ; décompteur 1 (256 * (6,5+3,25)æs) Adj1B: dec Cpt1 ; décrémente le compteur jrnz Adj1B ; compteur1 = 0 ? (t ÷ 2,5 ms) ldi wdr,CHIEN ; recharge le watch dog dec Cpt2 ; oui : décrémente le compteur 2 jrnz Adj2B ; compteur2 = 0 ? (t ÷ 125 ms) jrs bAdjB,PB,AdjIncB ; toujours appuyé ? dec CptAppui ; oui : décrémente compteur d'appui jrz Adj4B ; dépassement ? jp Adj3B Adj4B: clr jBLC ; réinit. du compteur BLANC ret ; sort AdjIncB: call IncCptB ; incrémente le compteur jours BLANCS ret ;**************************************************************************** ;* CORRECTION OU RAZ DU COMPTEUR ROUGE * ;* ----------------------------------- * ;* Entr‚e : * * ;* Sortie : jRGE * ;* Modifie : TSCR,WDR,Cpt1,Cpt2,CptAppui * ;**************************************************************************** ; un appui court incrémente le compteur, ; un appui long (>= 2 s) provoque une RAZ du compteur ROUGE. AjusteR: ldi CptAppui,16 ; init. compteur touche appuyée Adj3R: ldi Cpt2,50 ; décompteur 2 (50 * 2,5 ms) Adj2R: ldi Cpt1,0 ; décompteur 1 (256 * (6,5+3,25)æs) Adj1R: dec Cpt1 ; décrémente le compteur jrnz Adj1R ; compteur1 = 0 ? (t ÷ 2,5 ms) ldi wdr,CHIEN ; recharge le watch dog dec Cpt2 ; oui : décrémente le compteur 2 jrnz Adj2R ; compteur2 = 0 ? (t ÷ 125 ms) jrs bAdjR,PB,AdjIncR ; toujours appuyé ? dec CptAppui ; oui : décrémente compteur d'appui jrz Adj4R ; dépassement ? jp Adj3R Adj4R: clr jRGE ; réinit. du compteur ROUGE ret ; sort AdjIncR: call IncCptR ; incrémente le compteur jours ROUGES ret ;**************************************************************************** ;* COMMANDE DE RAZ GENERALE DU COMPTEUR TEMPO * ;* ------------------------------------------ * ;* Entr‚e : * * ;* Sortie : * * ;* Modifie : TSCR,WDR,Cpt1,Cpt2,CptAppui * ;**************************************************************************** ; un appui court n'a aucune action, ; un appui long (>= 2 s) provoque une RAZ du microcontrôleur. RaZ_UC: ldi CptAppui,16 ; init. compteur touche appuyée RaZ_3: ldi Cpt2,50 ; décompteur 2 (50 * 2,5 ms) RaZ_2: ldi Cpt1,0 ; décompteur 1 (256 * (6,5+3,25)æs) RaZ_1: dec Cpt1 ; décrémente le compteur jrnz RaZ_1 ; compteur1 = 0 ? (t ÷ 2,5 ms) ldi wdr,CHIEN ; recharge le watch dog dec Cpt2 ; oui : décrémente le compteur 2 jrnz RaZ_2 ; compteur2 = 0 ? (t ÷ 125 ms) jrs bRaZ,PB,RaZ_5 ; toujours appuyé ? dec CptAppui ; oui : décrémente compteur d'appui jrz RaZ_4 ; dépassement ? jp RaZ_3 RaZ_4: res bPSI,tscr ; arrête le timer jp $ ; attend RAZ par watchdog RaZ_5: ret ;**************************************************************************** ;* ATTENTE ET DETECTION D'UNE IMPULSION * ;* ------------------------------------ * ;* Entr‚e : Mesures * ;* Sortie : A * ;* Modifie : A,V,W,Mespos * ;**************************************************************************** TestImp: ld a,v ; V : borne inférieure de la fenêtre cp a,Mesures+1 ; attend inc. jusqu'à la borne inf. jrnz TestImp ; octet fort d'abord ld a,w cp a,Mesures jrnz TestImp clr Mespos ; raz compteur de mesures ld a,w ; décale VW à la borne supérieure addi a,FENETOPN ; de la fenêtre ld w,a jrnc TstI2 inc v TstI2: ld a,v cp a,Mesures+1 ; attend inc. jusqu'à la borne sup. jrnz TstI2 ld a,w cp a,Mesures jrnz TstI2 ld a,Mespos cpi a,TESTTOPN ; assez de lectures positives ? jrc TstI3 ; non : impulsion absente ldi a,1 ; oui : impulsion présente ret TstI3: clr a ret ;**************************************************************************** ;* UTILISATION DES SIGNAUX RECUS * ;* ----------------------------- * ;* Entr‚e : Imp18,Imp21,Imp24,Imp29,Imp33,Imp36,Imp39 * ;* Sortie : compteurs jBLC & jRGE, indicateurs d'état * ;* Modifie : A,Symb,SymbD,jBLC,jRGE,flag,Somme1,Somme2 * ;**************************************************************************** ; Signification des impulsions : ; ; 18 : tarif du lendemain = BLEU ; 21 : tarif du lendemain = BLANC ; 24 : tarif du lendemain = ROUGE ; 29 : fin d'indication du tarif du lendemain ; 33 : tarif courant = BLEU ; 36 : tarif courant = BLANC ; 39 : tarif courant = ROUGE Exploite: ; vérifie la qualité du décodage ld a,Imp18 ; somme des impulsions (18+21+24) add a,Imp21 add a,Imp24 ld Somme1,a ; sauve résultat de la somme cpi a,2 jrc Expl0 ; somme < 2 ? ret ; non (>= 2) : erreur ! sort Expl0: ld a,Imp33 ; somme des impulsions (33+36+39) add a,Imp36 add a,Imp39 ld Somme2,a ; sauve résultat de la somme cpi a,2 jrc Expl1 ; somme < 2 ? ret ; non (>= 2) : erreur ! sort Expl1: ld a,Somme1 jrnz Expl1a ld a,Somme2 jrnz Expl1a ret ; somme1 = somme2 = 0 --> on sort Expl1a: ld a,Somme1 jrnz Expl2 ; somme1 > 0 ? jp Expl3 Expl2: ld a,Somme2 jrnz Expl3 ; somme1 > 0 ET somme2 = 0 ? ret ; erreur donc sort ; ici, les impulsions sont considérées bonnes ; test de l'impulsion 29 : couleur du lendemain Expl3: ld a,Imp29 jrz Expl3c ; Imp29 = 0 ? jp Expl4 Expl3c: set fDem,Flag ; positionne flag couleur lendemain ld a,Imp18 jrz Expl3a ; BLEU ? ldi SymbD,BLEU jp Expl5 Expl3a: ld a,Imp21 jrz Expl3b ; BLANC ? ldi SymbD,BLANC jp Expl5 Expl3b: ldi SymbD,ROUGE ; alors ROUGE jp Expl5 ; ici Imp29 est à 1 = fin de couleur du lendemain, donc ; changement de jour et incrémentation d'un compteur en tenant ; compte de l'état prévu (mémo dans SymD) Expl4: jrs fDem,Flag,Expl4c ; répétition d'impulsion ? jp Expl5 Expl4c: ld a,Imp36 ; test jour BLANC jrz Expl4a ld a,SymbD cpi a,BLANC ; c'est le tarif prévu ? jrz Expl4d ret ; non : erreur, on sort ! Expl4d: call IncCptB ; incrémente le compteur BLANC jp Expl4b Expl4a: ld a,Imp39 ; test jour ROUGE jrz Expl4b ld a,SymbD cpi a,ROUGE ; c'est le tarif prévu ? jrz Expl4e ret ; non : erreur, on sort ! Expl4e: call IncCptR ; incrémente ou non compteur ROUGE Expl4b: res fDem,Flag ; RAZ flag couleur lendemain active ; défini la couleur tarifaire courante Expl5: ld a,Imp33 jrz Expl5a ; BLEU ? ldi Symb,BLEU jp Expl6 Expl5a: ld a,Imp36 jrz Expl5b ; BLANC ? ldi Symb,BLANC jp Expl6 Expl5b: ldi Symb,ROUGE ; alors ROUGE Expl6: ret ;**************************************************************************** ;* INCREMENTATION DU COMPTEUR BCD BLANC * ;* ------------------------------------ * ;* Entr‚e : compteur BCD jBLC * ;* Sortie : compteur BCD jBLC * ;* Modifie : A,WDR,jBLC * ;**************************************************************************** ; max. compteur = 43 jours IncCptB: ldi wdr,CHIEN ld a,jBLC cpi a,43H ; compteur = max (43) ? jrnz IncB01 ldi jBLC,1 ; oui : alors compteur = 1 ret IncB01: ld a,jBLC ; lit compteur andi a,0FH ; masque poids fort cpi a,09H ; poids faible = 9 ? jrnz IncB00 ; différent de 9 : incrémente ld a,jBLC addi a,07H ; ajustement décimal (09H + 7 = 10H) ld jBLC,a ret IncB00: inc jBLC ; incrémente compteur ret ;**************************************************************************** ;* INCREMENTATION DU COMPTEUR BCD ROUGE * ;* ------------------------------------ * ;* Entr‚e : compteur BCD jRGE * ;* Sortie : compteur BCD jRGE * ;* Modifie : A,WDR,jRGE * ;**************************************************************************** ; max. compteur = 22 jours IncCptR: ldi wdr,CHIEN ld a,jRGE cpi a,22H ; compteur = max (22) ? jrnz IncR01 ldi jRGE,1 ; oui : alors compteur = 1 ret IncR01: ld a,jRGE ; lit compteur andi a,0FH ; masque poids fort cpi a,09H ; poids faible = 9 ? jrnz IncR00 ; différent de 9 : incrémente ld a,jRGE addi a,07H ; ajustement décimal (09H + 7 = 10H) ld jRGE,a ret IncR00: inc jRGE ; incrémente compteur ret ;**************************************************************************** ;* AFFICHAGE D'UN OCTET HEXA * ;* ------------------------- * ;* Entr‚e : donn‚e … afficher dans A * ;* Sortie : * * ;* Modifie : A,Sauv_x * ;**************************************************************************** AffOctet: ld Sauv_x,a ; sauve accu swap_a ; interverti les quartets call ConvAsc ; converti MSB cpi a,'0' ; compare avec '0' jrnz AffOct00 ; zéro non significatif ? ldi a,' ' ; oui : on ne l'affiche pas AffOct00: call Aff_Car ; affiche MSB ld a,Sauv_x call ConvAsc ; converti LSB call Aff_Car ; et affiche ret ; Conversion hexad‚cimal vers ASCII ConvAsc: andi a,0FH ; masque le poids fort jrr 3,a,NoAdj ; converti en ASCII jrs 2,a,Adj jrr 1,a,NoAdj Adj: addi a,07H NoAdj: addi a,30H ret ;######################### ROUTINES DE GESTION LCD ########################## ;**************************************************************************** ;* INITIALISATION DE L'AFFICHEUR LCD * ;* --------------------------------- * ;* Entr‚e : * * ;* Sortie : * * ;* Modifie : A,V,X,CopyPB * ;**************************************************************************** ; Initialisation en mode 4 bits (cf. doc Hitachi LCD-II) ; Init_Lcd: res bRS,CopyPB outpb CopyPB ; ligne RS à 0 (registre d'instr.) ldi PA,0 ; met 0 sur PA set bE,CopyPB outpb CopyPB ; met E à 1 ldi PA,00000010B ; écrit la donnée sur PA res bE,CopyPB outpb CopyPB ; valide la donnée (latch) call TempoLcd ; tempo 5 ms ldi a,00101000B call Ecr_Inst ; mode 4 bits, ligne du bas call TempoLcd ; tempo 5 ms ldi a,00101000B call Ecr_Inst ; mode 4 bits, ligne du bas call TempoLcd ldi a,00001111B ; Lcd ON, curseur ON, clign. ON call Ecr_Inst call TempoLcd ldi a,00000110B call Ecr_Inst ; manière de visu des caractères call TempoLcd ldi a,00010100B call Ecr_Inst ; décalage (curseur --> droite) call TempoLcd ldi a,HOME call Ecr_Inst ; afficheur en position Home (0,0) ; création de nouveaux caractères (symboles) call TempoLcd ldi a,01000000B ; adresse caract. N°0 en CG RAM call Ecr_Inst ldi v,8*5 ; compteur pour 5 caractères ; ldi x,Tab_Car.d ; init. du pointeur de tableau ldi x,winoffset(Tab_Car); init. du pointeur de tableau DefCar: ld a,(x) ; lecture de la donnée pointée call Aff_Car ; écrit la donnée en CG RAM inc x ; incrémente le pointeur dec v ; décrémente le compteur jrnz DefCar ; toutes les données écrites ? call TempoLcd ldi a,CLS call Ecr_Inst ; efface l'afficheur call TempoLcd ldi a,00001100B ; LCD ON, curseur OFF, cligno. OFF call Ecr_Inst ret ;**************************************************************************** ;* AFFICHAGE D'UN CARACTERE SUR LE LCD * ;* ----------------------------------- * ;* Entr‚e : caractère à afficher dans A * ;* Sortie : * * ;* Modifie : * * ;**************************************************************************** Aff_Car: call TempoLcd ; attend afficheur prêt call Ecr_Data ; écrit la donnée sur l'afficheur ret ;**************************************************************************** ;* POSITIONNE LE CURSEUR DU LCD * ;* ---------------------------- * ;* Entr‚e : position du curseur dans Cur_Pos * ;* Sortie : * * ;* Modifie : A * ;**************************************************************************** SetCur: ld a,Cur_Pos set 7,a ; met le bit 7 à 1 (cf. doc LCD) call TempoLcd ; attend afficheur prêt call Ecr_Inst ; transmet la donnée à l'afficheur ret ;**************************************************************************** ;* EFFACE L'AFFICHEUR LCD * ;* ---------------------- * ;* Entr‚e : * * ;* Sortie : * * ;* Modifie : A * ;**************************************************************************** Cls_Lcd: ldi a,CLS call TempoLcd call Ecr_Inst ; efface l'afficheur ret ;**************************************************************************** ;* MET LE CURSEUR EN POSITION HOME * ;* ------------------------------- * ;* Entr‚e : * * ;* Sortie : * * ;* Modifie : A * ;**************************************************************************** Home_Lcd: ldi a,HOME call TempoLcd call Ecr_Inst ; met le curseur en (0,0) ret ;**************************************************************************** ;* AFFICHAGE D'UN MESSAGE SUR LE LCD * ;* --------------------------------- * ;* Entr‚e : adresse du message dans X * ;* Sortie : * * ;* Modifie : A,V,X,Cur_Pos * ;**************************************************************************** ; le message se termine par le caractère NULL (0) ! Aff_Mess: ldi v,8 ; init. compteur de caractères ld a,(x) ; lecture caractère pointé Aff_M1: call TempoLcd call Ecr_Data ; affiche le caractère dec v jrnz LitCar ; 8 caractères affichés ? ldi Cur_Pos,40H ; oui : call SetCur ; positionne le curseur (spé. LM16155) LitCar: inc x ; incrémente le pointeur ld a,(x) ; lit la donnée pointée jrz FinAffMe ; fin de message ? jp Aff_M1 ; non : continue FinAffMe: ret ;**************************************************************************** ;* ECRITURE D'UNE DONNEE OU D'UNE INSTRUCTION SUR LE LCD * ;* ----------------------------------------------------- * ;* Entr‚e : la donnée ou l'instruction dans A * ;* Sortie : * * ;* Modifie : A,W,Buf,CopyPB,Sauv_a * ;**************************************************************************** Ecr_Data: ldi wdr,CHIEN ld Sauv_a,a ; sauve la donnée set bRS,CopyPB outpb CopyPB ; sélectionne reg. de données ; traitement du MSB de la donnée ld a,Sauv_a Ecr_Inst: ld Buf,a ; sauve la valeur d'origine swap_a ; interverti quartets andi a,00001111B ; masque le MSB ld Sauv_a,a ; sauve l'accu ldi PA,0 set bE,CopyPB outpb CopyPB ; ligne E à 1 ld a,Sauv_a ; restitue l'accu ld PA,a ; écrit la donnée MSB res bE,CopyPB outpb CopyPB ; ...et la valide (E = 0) ; traitement du LSB de la donnée ld a,Buf ; restitue la donnée d'origine andi a,00001111B ; masque le MSB ld Sauv_a,a ; sauve l'accu set bE,CopyPB outpb CopyPB ld a,Sauv_a ld PA,a ; écrit la donnée LSB res bE,CopyPB outpb CopyPB ; ...et la valide res bRS,CopyPB outpb CopyPB ; par défaut : sélection reg. instruc. ret ;**************************************************************************** ;* TEMPORISATION 5 ms POUR LE LCD * ;* ------------------------------ * ;* Entr‚e : * * ;* Sortie : * * ;* Modifie : Cpt1,Cpt2,WDR * ;**************************************************************************** ; tempo calculée avec un quartz de 8 MHz ! TempoLcd: ldi Cpt2,2 ; décompteur 2 (2 * 2,5 ms) Dcpt2: ldi Cpt1,0 ; décompteur 1 (256 * (6,5+3,25)æs) Dcpt1: dec Cpt1 ; décrémente le compteur jrnz Dcpt1 ; compteur1 = 0 ? (t ÷ 2,5 ms) ldi wdr,CHIEN ; recharge le watch dog dec Cpt2 ; oui : décrémente le compteur 2 jrnz Dcpt2 ; compteur2 = 0 ? (t ÷ 5 ms) ret ;**************************************************************************** ;* TEMPORISATION 640 MS * ;* -------------------- * ;* Entr‚e : * * ;* Sortie : * * ;* Modifie : Cpt1,Cpt2,WDR * ;**************************************************************************** ; tempo calculée avec un quartz de 8 MHz ! Tempo: ldi Cpt2,0 ; décompteur 2 (256 * 2,5 ms) Dcpt20: ldi Cpt1,0 ; décompteur 1 (256 * (6,5+3,25)æs) Dcpt10: dec Cpt1 ; décrémente le compteur jrnz Dcpt10 ; compteur1 = 0 ? (t ÷ 2,5 ms) ldi wdr,CHIEN ; recharge le watch dog dec Cpt2 ; oui : décrémente le compteur 2 jrnz Dcpt20 ; compteur2 = 0 ? (t ÷ 640 ms) ret ;**************************************************************************** ;* TEMPORISATION DE 4 S * ;* -------------------- * ;* Entr‚e : * * ;* Sortie : * * ;* Modifie : V * ;**************************************************************************** ; tempo calcul‚e avec un quartz de 8 MHz ! Tempo4s: ldi v,6 ; 6 * 640 ms = 3,84 s Tmp40: call Tempo dec v jrnz Tmp40 ; 6 * 640 ms ? ret ;**************************************************************************** ;* ROUTINE D'INTERRUPTION DU TIMER * ;* ------------------------------- * ;* Entr‚e : * * ;* Sortie : Mesures,Mespos * ;* Modifie : SauvAcc,WDR,TSCR,Y,ADCR,Nbint,Mesures,Table,Mespos * ;**************************************************************************** ; la fréquence d'interruption est de 700 Hz (4 * 175 Hz) ; T = 1,428 ms IntTimer: res bTMZ,tscr ; RAZ du bit TMZ ldi wdr,CHIEN ; on jette un os au chien de garde ld SauvAcc,a ; sauvegarde accu set bSEC,orb ; conf. PB.7 en entrée analogique set bSEC,CopyPB outpb CopyPB ldi a,PRECHARG-2 ; état actuel timer; on en tient compte add a,tcr ; pour le relancement du timer de sorte ; que la fréquence soit constante. ld tcr,a ; Le -2 inclut le temps de calcul ld a,adr ; acquisition de la tension d'entrée ldi adcr,030H ; lancement conversion suivante add a,(y) ; accumulation en table ld (y),a inc y jrnc Tim1 ; report de la retenue éventuelle. inc (y) Tim1: inc y ; on pointe sur prochain mot en table ld a,y cpi a,Fintabl ; arrive à la fin ? jrc Tim2 ldi y,Table ; oui : on retourne au début Tim2: inc Nbint ; nb de mesures faites ld a,Nbint cpi a,QUARTDEP jrnc Tim2a ; fin du cycle ? ld a,SauvAcc ; oui : restauration accu reti ; plus rien à faire Tim2a: clr Nbint inc Mesures ; oui : un de plus jrnz Tim3 inc Mesures+1 Tim3: ld a,Table ; valeur de rang 0 sub a,Table+4 ; - valeur de rang 2 ld Table,a ; dans valeur de rang 0 jrnc Tim4 inc Table+5 ; si retenue, inc. valeur de rang 2 Tim4: ld a,Table+1 sub a,Table+5 ld Table+1,a jrr 7,a,Tim6 ; si différence nég., inverse le signe ld a,Table com a inc a ld Table,a jrnz Tim5 dec Table+5 ; si retenue Tim5: ld a,Table+1 com a ld Table+1,a Tim6: ld a,Table+2 ; valeur de rang 1 sub a,Table+6 ; - valeur de rang 3 ld Table+2,a ; dans valeur de rang 1 jrnc Tim7 inc Table+7 ; si retenue, inc. valeur de rang 2 Tim7: ld a,Table+3 sub a,Table+7 ld Table+3,a jrr 7,a,Tim9 ; si différence nég., inverse le signe ld a,Table+2 com a inc a ld Table+2,a jrnz Tim8 dec Table+7 ; si retenue Tim8: ld a,Table+3 com a ld Table+3,a Tim9: ld a,Table ; addition des deux valeurs absolues add a,Table+2 ld Table,a jrnc Tim10 inc Table+1 Tim10: ld a,Table+1 add a,Table+3 ld Table+1,a ld a,Table+1 jrnz Mesurbon ; si <>0, le cumul est > 255 : ok ld a,Table cpi a,SEUIL jrnc Mesurbon jp IntTim2 Mesurbon: inc Mespos ; oui : une mesure positive de plus IntTim2: clr Table ; réinitialisation du tableau clr Table+1 clr Table+2 clr Table+3 clr Table+4 clr Table+5 clr Table+6 clr Table+7 FinTim: ld a,SauvAcc ; restauration accu reti ; fin de l'interruption. ;**************************************************************************** ;* ROUTINE D'INTERRUPTION DU CONVERTISSEUR A/N * ;* ------------------------------------------- * ;* Entr‚e : * * ;* Sortie : * * ;* Modifie : ADCR * ;**************************************************************************** IntADC: ldi adcr,10010000B reti ;############################################################################ ;**************************************************************************** ;* VECTEURS D'INTERRUPTIONS ET DE DEMARRAGE * ;**************************************************************************** CSEG AT 0FF0H Adc: jp IntADC ; convertisseur A/N Timer: jp IntTimer ; timer IntPBC: nop ; port B (N.U.) reti IntPA: nop ; port A (N.U.) reti CSEG AT 0FFCH Nmi: nop ; interruption Non Masquable (N.U) reti _Res: jp Reset ; vecteur reset END