Si vous avez récupéré une horloge déportée de type ZEPHIA d'ACEB, il faut la brancher sur une horloge mère, car ce n'est qu'un afficheur.
J'ai conçu un petit montage pour mettre à jour cet afficheur, sans avoir besoin de l'horloge mère.
Il utilise un PIC 16F876A de Microchip et un module horloge à base de circuit DS1307.
L'écran LCD sert juste à la mise à l'heure.
Ci-dessous le fichier assembleur et le .hex.
A+
Code : Tout sélectionner
; Horloge / Calendrier / pour horloge ACEB de type ZEPHIA Le 16/01/2023
;
; http://www.aceb-elec.com/gamme_zephia.htm
;L'écran LDC sert uniquement à la mise à l'heure. En temps normal l'écran est étient (Mettre un interrupteur sur la led blanche de l'écran LCD).
; Un bouton pour sélectionner la mise à jour
; Un bouton pour incrémenter
; Une fois l'heure saisie, les secondes sont remises à zéro.
;
;
; Voici un montage pour alimenter en donnéés horaires, un afficheur déporté de type ZEPHIA d'ACEB.
; Ce programme sur PIC 16F876A avec un quart à 20 Mhz
;
; Cet afficheur ZEPHIA doit être connectée à une horloge mère type MH90.
; Pour se passer de cette horloge mère, j'ai conçu un programme sur PIC pour envoyer les données à cett afficheur.
; Les routines I²C sont de fabrice SINCERE : http://fabrice.sincere.pagesperso-orange.fr/cm_electronique/projet_pic/RTC/RTC_I2C.htm
;
; Exemple de données envoyées :
; lundi 31.12.2022 23h59mn00sec
; hhh-hhhh--mmmm-mmmm--ssss-ssss--Lund--JJJJ-JJJJ--MMMM-MMMM
; Diz-Unit--Diza-Unit--Diza-Unit--Mard--Diza-Unit--Diza-Unit
; 010-0011--0101-1001--0010-0000--0001--0011-0001--0001-0010
; ^ dernier bit sorti premier bit sorti ^
;
; ------ ------ ---
; ----- --- ------
; 20 10 20 20 10
; Top _______ _______
; Dép 0 1
; 0,2 msec - 0,1 msec. + grosse pose 19 msec
;
; Les données sont envoyées en série, avec un entête de 0,2 msec + 44 bits de données.
; Un bit de données à 0 = un état à 0 de 0,1 msec + un état à 1 de 0,2 msec
; Un bit de données à 1 = un état à 0 de 0,2 msec + un état à 1 de 0,1 msec
;
; On connectera les pattes RC6 et RC7 du PIC à l'entrée de l'afficheur.
; C'est une entére différentielle, donc on y branchera les 2 fils qui sortent un signal en opposition de phase.
; Il faut obligatoirement envoyer une trame après seulement 19 msec de pause, sinon l'horloge ne fonctionne pas.
;
Errorlevel-302 ; Supprime le message "Ensure that BANKx bits are correct"
List p=16F876A ; processeur utilisé
#include <p16F876A.inc>
__config _HS_OSC & _WDT_OFF & _PWRTE_ON & _BODEN_OFF & _LVP_OFF & _WRT_OFF & _CPD_OFF & _CP_OFF & _DEBUG_OFF
; Définition des ports utilisés
#define PORT_ACEB1 PORTC,6 ; Sortie vers l'horloge ACEB.
#define PORT_ACEB2 PORTC,7 ; Sortie vers l'horloge ACEB.
#define T18_9ms_H 0xB8 ; = 18,9 ms pour le crenéneau inter-trame
#define T18_9ms_L 0x92
#define T0_2ms_H 0x01 ; 470 = 0,2 ms pour le crenéneau long
#define T0_2ms_L 0xD6
#define T0_1ms_H 0x00 ; 218 = 0,1ms pour le crenéneau court
#define T0_1ms_L 0xDA
;xxxxxxxxxxxxxxx
; Macro
;xxxxxxxxxxxxxxx
BANK1 macro ; passage en BANK 1
bsf STATUS,RP0
bcf STATUS,RP1
endm
BANK0 macro ; passage en BANK 0
bcf STATUS,RP0
bcf STATUS,RP1
endm
;xxxxxxxxxxxxxxxxxxxxxxxxxx
; Déclaration des variables
;xxxxxxxxxxxxxxxxxxxxxxxxxx
CBLOCK 0x070 ; début de la zone des registres d'usage général du 16F876A : 16 variables.
STATUS_TEMP : 1 ; sauvegarde du registre STATUS (routine d'interruption)
W_TEMP : 1 ; sauvegarde du registre W (routine d'interruption)
data1 : 1 ; contient le niveau des bits RS et R/W (module LCD): ; (000000 RS R/W)
data2 : 1 ; contient le niveau des bits DB7-DB0 (module LCD): ; (DB7 ... DB0)
busy_flag : 1 ; seul le bit 0 est utilisé (module LCD)
secondes : 1 ; lecture des secondes (registre d'adresse 0x00 du DS1307)
minutes : 1 ; lecture des minutes (registre d'adresse 0x01 du DS1307)
heures : 1 ; lecture des heures (registre d'adresse 0x02 du DS1307)
jours : 1 ; lecture des jours (registre d'adresse 0x03 du DS1307)
date : 1 ; lecture de la date (registre d'adresse 0x04 du DS1307)
mois : 1 ; lecture du mois (registre d'adresse 0x05 du DS1307)
annee : 1 ; lecture de l'année (registre d'adresse 0x06 du DS1307)
chiffre : 1 ; variable d'entrée de la routine affichagechiffre
etape : 1 ; = numéro de l'étape (1 à 11 en mode réglage) ; en mode normal : étape n°0
clignotement : 1 ; bit 1 = 0 : affichage ; bit 1 = 1 : masquage (' ')
tampon : 1 ; variable temporaire
ENDC
CBLOCK 0x020 ; début de la zone des registres d'usage général du 16F876A : 80 variables.
boutonpoussoir : 1 ; le bit 1 contient le niveau du BP1 de la dernière scrutation ; le bit 2 contient le niveau du BP2 de la dernière scrutation
boutonpoussoirbak : 1 ; le bit 1 contient le niveau du BP1 de l'avant dernière scrutation ; le bit 2 contient le niveau du BP2 de l'avant dernière scrutation
boutonpoussoiractivite : 1 ; bit 1 = 1 <=> BP1 a été appuyé entre les deux dernières scrutation ; Le bit 2 = 1 <=> BP2 a été appuyé entre les deux dernières scrutation
jours0 : 1 ; variables d'entrées de la routine affichageLCDdateheure ; numéro du jour (.1 <=> Di ...)
date0 : 1 ; codage BCD
mois0 : 1 ; codage BCD
annee0 : 1 ; codage BCD
heures0 : 1 ; codage BCD
minutes0 : 1 ; codage BCD
secondes0 : 1 ; codage BCD
compteur : 1
temp : 1 ;
cpt1_bp : 1 ; Compteur pour vérifier les boutons poussoirs.
cpt2_bp : 1 ; Compteur pour vérifier les boutons poussoirs.
cpt_oct : 1
cpt_bit : 1
cpt_phase : 1
cpt_init : 1
mois_bcd : 1
jour_bcd : 1
lundi_bcd : 1
seconde_bcd : 1
minute_bcd : 1
heure_bcd : 1
SECONDS : 1
MINUTES : 1
HOURS : 1
CCPR1L_sav : 1
CCPR1H_sav : 1
etat_bit : 1 ; Bit (2) Retard au démarrage bit(1) = envoi trame vers ACEB en pause, bit(0) Réception bit DS = 1 Hertz
cpt3_bp : 1 ;
ENDC
org 0x2100 ; Initialize EEPROM Data
dt "Horloge pour panneau ZEPHIA d''ACEB " ; Texte visible dans le '.hex'.
dt "Le 16/01/2023 "
dt "http://www.la-tour.info/uts/uts_index.html "
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Démarrage sur reset
org 0x0000 ; vecteur Reset
goto initialisation
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine d'interruption
org 0x0004
movwf W_TEMP
swapf STATUS,w
movwf STATUS_TEMP
BANK0
btfss INTCON,INTE ; 1= Enables the RB0/INT external interrupt
goto int_suite
btfss INTCON,INTF ; 1= The RB0/INT external interrupt occurred (must be cleared in software)
goto int_suite
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Traitement de l'interruption RB0/INT toutes les secondes
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
bsf etat_bit,0 ; On informe au programme d'émission de trame, que quand il à fini on peut déclencher la lecture du DS1307.
bcf INTCON,INTF ; on efface le drapeau de l'interruption RB0/INT
swapf STATUS_TEMP,w ; restauration des registres STATUS puis W
movwf STATUS
swapf W_TEMP,f
swapf W_TEMP,w
retfie ; retour d'interruption
int_suite
btfss INTCON,PEIE ; 1= Enables all unmasked peripheral interrupt
goto int_fin
BANK1
btfsc PIR1,CCP1IF ; Interrupt comparaison Timer1 == CCP1 en cours ?
goto interruption_Timer1
int_fin
BANK0
swapf STATUS_TEMP,w ; restauration des registres STATUS puis W
movwf STATUS
swapf W_TEMP,f
swapf W_TEMP,w
retfie ; retour d'interruption
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Traitement de l'interruption Timer1 au bout de 0,1 msec, 0,2 msec ou 18,9 msec.
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
interruption_Timer1
BANK0
clrf TMR1L
clrf TMR1H
bcf PIR1, CCP1IF ; on efface le drapeau de la comparaison Timer1
btfss etat_bit,2 ; Au départ, etat_bit(2) = 0 pendant 1 sec, on attend avant d'envoyer une trame à l'horloge ACEB.
goto phase_99
bcf T1CON,TMR1ON ; Mise à l'arrêt du Timer1.
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; On envoie la trame à l'horloge ACEB.
envoi_aceb ; heure_bcd, minute_bcd, seconde_bcd, lundi_bcd, jour_bcd, mois_bcd
BANK0
btfss cpt_init,0 ; Au départ, cpt_init = 1 !
goto phase_09 ; cpt_init == 0 ! => L'entête de la trame a été envoyée. On envoie la suite de la trame.
btfsc cpt_phase,0 ; cpt_phase pour envoyer le créneau haut (cpt_phase==0), puis le créneau bas (cpt_phase==1).
goto phase_01
; -----------------------------
; cpt_phase == 0 !
; cpt_init == 0 ! => On envoie l'entête de la trame.
phase_00 ; cpt_init(0) = 1 et cpt_phase(0) = 0
incf cpt_phase,f ; cpt_phase(0) 0 -> 1.
bsf PORT_ACEB1
bcf PORT_ACEB2
movlw T0_2ms_L ; cpt_init(0) = 1 => 1er créneau envoyé = 0,2 msec.
movwf CCPR1L
movlw T0_2ms_H
movwf CCPR1H ; 0x0179 = 377 = 0,2 msec.
bsf T1CON,TMR1ON ; Mise en marche du Timer1.
goto phase_99
; -----------------------------
; cpt_phase == 1 !
phase_01 ; cpt_init(0) = 1 et cpt_phase(0) = 1
; Pour ce premier créneau, il n'y a pas de phase 1. On repasse en phase 0.
incf cpt_phase,f ; cpt_phase(0) 1 -> 0.
bcf cpt_init,0 ; cpt_init(0) 1 -> 0.
movlw 1 ; On peut commencer à envoyer les octets de la trame.
movwf cpt_bit ; cpt_bit = 00000001
clrf cpt_oct ; cpt_oct = 0
phase_09
; -----------------------------
; cpt_init == 0 ! => L'entête de la trame a été envoyée. On envoie la suite de la trame.
btfsc cpt_phase,0
goto phase_20
phase_10 ; cpt_phase = 0 => Première partie du signal.
incf cpt_phase,f
bcf PORT_ACEB1
bsf PORT_ACEB2
movf cpt_oct,w
sublw heure_bcd - mois_bcd + 1
btfss STATUS,Z
goto phase_11
clrf cpt_phase ; Raz cpt_phase.
bsf cpt_init,0 ; cpt_init(0) 0 -> 1.
movlw T18_9ms_L ; On a envoyé tous les octets !!! Fin de la trame. Maintenant une pause de 18,9 msec
movwf CCPR1L
movlw T18_9ms_H
movwf CCPR1H
bsf T1CON,TMR1ON ; Mise en marche du Timer1. Dernier octet envoyé.
btfsc etat_bit,0
bsf etat_bit,1 ; On va pouvoir indiquer au programme principal de lire le DS1307 et afficher l'heure sur l'écran LCD.
goto phase_99
phase_11
movf cpt_bit,w ; cpt_bit = 00000001, 00000010, 00000100, ... => temp.
movwf temp
movlw mois_bcd
addwf cpt_oct,w ; cpt_oct = n° n'octet en cours d'envoi.
movwf FSR ; On charge l'adresse de début des octets à envoyer.
movf INDF,w ; Contenu du registre pointé par FSR
andwf temp,w ; Bit Z = 1 si positionné.
btfss STATUS,Z
goto phase_12
movlw T0_1ms_L ; On envoi un "0".
movwf CCPR1L
movlw T0_1ms_H
movwf CCPR1H ; 0x0179 = 377 = 0,2 msec 0x00BC = 188 = 0,1 msec
movlw T0_2ms_L
movwf CCPR1L_sav
movlw T0_2ms_H
movwf CCPR1H_sav ; 0x0179 = 377 = 0,2 msec 0x00BC = 188 = 0,1 msec
bsf T1CON,TMR1ON ; Mise en marche du Timer1.
goto phase_99
phase_12
movlw T0_2ms_L ; On envoi un "1".
movwf CCPR1L
movlw T0_2ms_H
movwf CCPR1H ; 0x0179 = 377 = 0,2 msec 0x00BC = 188 = 0,1 msec
movlw T0_1ms_L
movwf CCPR1L_sav
movlw T0_1ms_H
movwf CCPR1H_sav ; 0x0179 = 377 = 0,2 msec 0x00BC = 188 = 0,1 msec
bsf T1CON,TMR1ON ; Mise en marche du Timer1.
goto phase_99
; -----------------------------
phase_20 ; cpt_phase = 1 => Deuxième partie du signal.
incf cpt_phase,f
bsf PORT_ACEB1
bcf PORT_ACEB2
movf CCPR1L_sav,w
movwf CCPR1L
movf CCPR1H_sav,w
movwf CCPR1H ; 0x0179 = 377 = 0,2 msec 0x00BC = 188 = 0,1 msec
movf cpt_oct,w ; Pour "lundi_bcd" => sur 4 bits seulement.
sublw lundi_bcd - mois_bcd
btfss STATUS,Z
goto phase_22
btfss cpt_bit,3
goto phase_22
incf cpt_oct,f
movlw 1
movwf cpt_bit ; On passe à l'octet suivant, bit n°1.
bsf T1CON,TMR1ON ; Mise en marche du Timer1.
goto phase_99
phase_22
movf cpt_oct,w ; Pour "heure_bcd" => sur 7 bits seulement.
sublw heure_bcd - mois_bcd
btfss STATUS,Z
goto phase_23
btfss cpt_bit,6
goto phase_23
incf cpt_oct,f
movlw 1
movwf cpt_bit ; On passe à l'octet suivant, bit n°1.
bsf T1CON,TMR1ON ; Mise en marche du Timer1.
goto phase_99
phase_23
bcf STATUS,C ; Status[C] = 0 !
rlf cpt_bit,f ; bit suivant.
btfsc STATUS,C
incf cpt_oct,f ; Si cpt_bit valait "1000 0000" cpt_oct = cpt_oct+1
phase_24
btfsc STATUS,C ; Le status[C] n'a pas bougé.
rlf cpt_bit,f ; Si cpt_bit valait "1000 0000" cpt_bit vaut maintenant "0000 0001"
bsf T1CON,TMR1ON ; Mise en marche du Timer1.
phase_99
swapf STATUS_TEMP,w ; Fin - Restauration des registres STATUS puis W
movwf STATUS
swapf W_TEMP,f
swapf W_TEMP,w
retfie ; retour d'interruption
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine de commande du module LCD
; On traite ici les instructions d'écriture (R/W = 0)
; - Display clear
; - Entry mode set
; - Display On/Off Control
; - Set function
; - Set DDRAM address
; - Write Data into DDRAM
; 2 variables d'entrée : data1, data2
; pas de variable de sortie
commandeLCD
BANK0
; 1ère étape : RS =0, R/W=0,E = 0
bcf PORTB,5 ; E = 0
nop
bcf PORTB,3 ; RS = 0
nop
bcf PORTB,4 ; R/W = 0
; mise à jour RS (RB3)
btfsc data1,1
bsf PORTB,3
btfss data1,1
bcf PORTB,3
; mise à jour R/W (RB4)
btfsc data1,0
bsf PORTB,4
btfss data1,0
bcf PORTB,4
; 2ème étape : DB7 DB6 DB5 DB4
; mise à jour DB7 (RA3)
btfsc data2,7
bsf PORTA,3
btfss data2,7
bcf PORTA,3
; mise à jour DB6 (RA2)
btfsc data2,6
bsf PORTA,2
btfss data2,6
bcf PORTA,2
; mise à jour DB5 (RA1)
btfsc data2,5
bsf PORTA,1
btfss data2,5
bcf PORTA,1
; mise à jour DB4 (RA0)
btfsc data2,4
bsf PORTA,0
btfss data2,4
bcf PORTA,0
; 3ème étape E=1 (RB5)
bsf PORTB,5
nop
nop
nop
nop
nop
nop
nop ; une pause de 1 µs (220 ns suffisent)
; 4ème étape E=0 (RB5)
bcf PORTB,5
; 5ème étape DB3 DB2 DB1 DB0
; mise à jour DB3 (RA3)
btfsc data2,3
bsf PORTA,3
btfss data2,3
bcf PORTA,3
; mise à jour DB2 (RA2)
btfsc data2,2
bsf PORTA,2
btfss data2,2
bcf PORTA,2
; mise à jour DB1 (RA1)
btfsc data2,1
bsf PORTA,1
btfss data2,1
bcf PORTA,1
; mise à jour DB0 (RA0)
btfsc data2,0
bsf PORTA,0
btfss data2,0
bcf PORTA,0
; 6ème étape E=1 (RB5)
bsf PORTB,5
nop
nop
nop
nop
nop
nop
nop ; une pause de 1 µs (220 ns suffisent)
; 7ème étape E=0 (RB5)
bcf PORTB,5
; xxxxxxxxxxxxxxxxxxxxxxxx
; on teste le drapeau Busy
fin_instruction
call busy
btfsc busy_flag,0
goto fin_instruction ; drapeau Busy = 1 (instruction en cours)
; drapeau Busy = 0 : instruction terminée
return
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine (module LCD)
; Instruction "Read Busy Flag"
; Pas de variable d'entrée
; Variable de sortie : bit 0 de busy_flag
busy
; étape initiale : configuration des broches RA0 à RA3 en entrées
BANK1
bsf TRISA,0 ; bit 0 du port A (RA0) = 1 : configuration en entrée (DB4)
bsf TRISA,1 ; bit 1 du port A (RA1) = 1 : configuration en entrée (DB5)
bsf TRISA,2 ; bit 2 du port A (RA2) = 1 : configuration en entrée (DB6)
bsf TRISA,3 ; bit 3 du port A (RA3) = 1 : configuration en entrée (DB7)
BANK0
; 1ère étape : RS= 0, R/W =1,E = 0
bcf PORTB,5 ; E = 0
nop
bcf PORTB,3 ; RS = 0
nop
bsf PORTB,4 ; R/W = 1
; 2ème étape : E = 1
bsf PORTB,5
nop
nop ; une petite pause de 200 ns
; 3ème étape : lecture DB7 (RA3)(busy flag)
btfsc PORTA,3
bsf busy_flag,0
btfss PORTA,3
bcf busy_flag,0
; bcf busy_flag,0 ; à supprimer (test debugger MPLAB SIM)
; 4ème étape : E = 0
bcf PORTB,5
nop
nop ; une petite pause de 200 ns
; 5ème étape : E = 1
bsf PORTB,5
nop
nop ; une petite pause de 200 ns
; 6ème étape : DB3 DB2 DB1 DB0
nop
; 7ème étape : E = 0
bcf PORTB,5
nop ; une petite pause de 200 ns
nop
; 8ème étape : R/W = 0
bcf PORTB,4
; dernière étape : configuration des broches RA0 à RA3 en sorties
BANK1
bcf TRISA,0 ; bit 0 du port A (RA0) = 0 : configuration en sortie (DB4)
bcf TRISA,1 ; bit 1 du port A (RA1) = 0 : configuration en sortie (DB5)
bcf TRISA,2 ; bit 2 du port A (RA2) = 0 : configuration en sortie (DB6)
bcf TRISA,3 ; bit 3 du port A (RA3) = 0 : configuration en sortie (DB7)
BANK0
return
;xxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine I2C Start
; Pas de variable d'entrée
; Pas de variable de sortie
I2C_start
call I2C_idle ; on attend que le bus I2C soit libre
BANK1
bsf SSPCON2,SEN ; SEN = 1 (lancement d'une opération Start)
BANK0
return
;xxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine I2C Idle
; Pas de variable d'entrée
; Pas de variable de sortie
I2C_idle
BANK1
I2C_idle0
btfsc SSPCON2,ACKEN
goto I2C_idle0 ; le bit ACKEN n'est pas nul
btfsc SSPCON2,RCEN
goto I2C_idle0 ; le bit RCEN n'est pas nul
btfsc SSPCON2,PEN
goto I2C_idle0 ; le bit PEN n'est pas nul
btfsc SSPCON2,RSEN
goto I2C_idle0 ; le bit RSEN n'est pas nul
btfsc SSPCON2,SEN
goto I2C_idle0 ; le bit SEN n'est pas nul
btfsc SSPSTAT,R_W
goto I2C_idle0 ; le bit R_W n'est pas nul
BANK0
return
;xxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine I2C_write
; Variable d'entrée : W (accumulateur)
; Pas de variable de sortie
I2C_write
call I2C_idle ; on attend que le bus I2C soit prêt
movwf SSPBUF
return
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine I2C_ACK_slave_to_master
; Pas de variable d'entrée; Pas de variable de sortie
I2C_ACK_slave_to_master
call I2C_idle ; on attend que le bus I2C soit prêt
BANK1
I2C_ACK_slave_to_master0
btfsc SSPCON2,ACKSTAT
goto I2C_ACK_slave_to_master0 ; on attend la réception du bit ACK
BANK0
return
;xxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine I2C_Repeated_Start
; Pas de variable d'entrée; Pas de variable de sortie
I2C_Repeated_Start
call I2C_idle ; on attend que le bus I2C soit prêt
BANK1
bsf SSPCON2,RSEN ; RSEN = 1 (lancement d'une opération Repeated Start)
BANK0
return
;xxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine I2C_read
; Pas de variable d'entrée
; variable de sortie : W (accumulateur)
I2C_read
call I2C_idle ; on attend que le bus I2C soit prêt
BANK1
bsf SSPCON2,RCEN ; on lance la réception
I2C_read0
btfsc SSPCON2,RCEN
goto I2C_read0 ; on attend la fin de la réception
BANK0
movf SSPBUF,w
return
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine I2C_ACK_master_to_slave
; Pas de variable d'entrée; Pas de variable de sortie
I2C_ACK_master_to_slave
call I2C_idle ; on attend que le bus I2C soit prêt
BANK1
bcf SSPCON2,ACKDT ; ACKDT = 0
bsf SSPCON2,ACKEN ; ACKEN = 1 (lancement d'une opération Acknowledge)
BANK0
return
;xxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine I2C_NOACK
; Pas de variable d'entrée; Pas de variable de sortie
I2C_NOACK
call I2C_idle ; on attend que le bus I2C soit prêt
BANK1
bsf SSPCON2,ACKDT ; ACKDT = 1
bsf SSPCON2,ACKEN ; ACKEN = 1 (lancement d'une opération Acknowledge)
BANK0
return
;xxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine I2C_stop
; Pas de variable d'entrée; Pas de variable de sortie
I2C_stop
call I2C_idle ; on attend que le bus I2C soit prêt
BANK1
bsf SSPCON2,PEN ; PEN = 1 (lancement d'une opération Stop)
BANK0
return
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine BP1
; Détection d'un appui sur le bouton poussoir BP1 (broche RB1)
; Pas de variable d'entrée
; Variable de sortie :
; bit 1 du registre boutonpoussoiractivite (BANKque 0)
BP1
BANK0
bsf boutonpoussoirbak,1
btfss boutonpoussoir,1
bcf boutonpoussoirbak,1 ; (boutonpoussoirbak,1) = (boutonpoussoir,1)
bsf boutonpoussoir,1
btfss PORTB,1
bcf boutonpoussoir,1 ; (boutonpoussoir,1) = niveau actuel de RB1
bcf boutonpoussoiractivite,1
btfss boutonpoussoirbak,1
return
btfsc boutonpoussoir,1
return
bsf boutonpoussoiractivite,1 ; bouton poussoir 1 a été appuyé
return
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine BP2
; Détection d'un appui sur le bouton poussoir BP2 (broche RB2)
; Pas de variable d'entrée
; Variable de sortie :
; bit 2 du registre boutonpoussoiractivite (BANKque 0)
BP2
BANK0
bsf boutonpoussoirbak,2
btfss boutonpoussoir,2
bcf boutonpoussoirbak,2 ; (boutonpoussoirbak,2) = (boutonpoussoir,2)
bsf boutonpoussoir,2
btfss PORTB,2
bcf boutonpoussoir,2 ; (boutonpoussoir,2) = niveau actuel de RB2
bcf boutonpoussoiractivite,2
btfss boutonpoussoirbak,2
return
btfsc boutonpoussoir,2
return
bsf boutonpoussoiractivite,2 ; bouton poussoir 2 a été appuyé
return
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine affichageLCDdateheure
; 1ère ligne : jj dd/mm/aaaa
; 2ème ligne : hh:mm +XXX,X °C
; exemple :
; Lu 22/04/2010
; 21:45 +023,5 °C
; Variables d'entrée (BANKque 0) :
; etape
; clignotement (bit 1)
; jour0, date0, mois0, annee0
; heures0, minutes0, secondes0
; Pas de variable de sortie
affichageLCDdateheure
BANK0
incf clignotement,f ; période de clignotement 2*104,8576 ms
; Instruction "Display Clear" (durée 1,53 ms)
; (Efface l'écran
; Place le curseur dans la position d'origine :
; 1ère position à gauche, 1ère ligne : compteur d'adresse à 0x00)
movlw B'00000000'
movwf data1
movlw B'00000001'
movwf data2
call commandeLCD
; jours0 : 00000b2b1b0 -> n° du jours
; 1 -> lundi (Lu)
; 2 -> mardi (Ma)
; 3 -> Me
; 4 -> Je
; 5 -> Ve
; 6 -> Sa
; 7 -> dimanche (Di)
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
; si etape = 1 et (clignotement,1) = 1
; alors on affiche deux espaces
movlw .1 ; W = .1
subwf etape,w ; W = (etape) - .1
btfss STATUS,Z ; test du bit Z
goto jour1 ; Z = 0 c'est-à-dire (etape) != .1
btfss clignotement,1
goto jour1
movlw B'00000010' ; ; on affiche ' '
movwf data1 ; RS = 1 R/W = 0
movlw ' '
movwf data2
call commandeLCD
movlw ' '
movwf data2
call commandeLCD
goto _date
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
jour1
movlw 0x01
subwf jours0,w ; W = (jours0) - 0x01
btfss STATUS,Z ; test du bit Z
goto jour2 ; Z = 0 c'est-à-dire (jours0) != 0x01
; on affiche 'Lu'
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw 'L'
movwf data2
call commandeLCD
movlw 'u'
movwf data2
call commandeLCD
goto _date
jour2
movlw 0x02
subwf jours0,w ; W = (jours0) - 0x02
btfss STATUS,Z ; test du bit Z
goto jour3 ; Z = 0 c'est-à-dire (jours0) != 0x02
; on affiche 'Ma'
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw 'M'
movwf data2
call commandeLCD
movlw 'a'
movwf data2
call commandeLCD
goto _date
jour3
movlw 0x03
subwf jours0,w ; W = (jours0) - 0x03
btfss STATUS,Z ; test du bit Z
goto jour4 ; Z = 0 c'est-à-dire (jours0) != 0x03
; on affiche 'Me'
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw 'M'
movwf data2
call commandeLCD
movlw 'e'
movwf data2
call commandeLCD
goto _date
jour4
movlw 0x04
subwf jours0,w ; W = (jours0) - 0x04
btfss STATUS,Z ; test du bit Z
goto jour5 ; Z = 0 c'est-à-dire (jours0) != 0x04
; on affiche 'Je'
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw 'J'
movwf data2
call commandeLCD
movlw 'e'
movwf data2
call commandeLCD
goto _date
jour5
movlw 0x05
subwf jours0,w ; W = (jours0) - 0x05
btfss STATUS,Z ; test du bit Z
goto jour6 ; Z = 0 c'est-à-dire (jours0) != 0x05
; on affiche 'Ve'
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw 'V'
movwf data2
call commandeLCD
movlw 'e'
movwf data2
call commandeLCD
goto _date
jour6
movlw 0x06
subwf jours0,w ; W = (jours0) - 0x06
btfss STATUS,Z ; test du bit Z
goto jour7 ; Z = 0 c'est-à-dire (jours0) != 0x06
; on affiche 'Sa'
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw 'S'
movwf data2
call commandeLCD
movlw 'a'
movwf data2
call commandeLCD
goto _date
jour7
; on affiche 'Di'
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw 'D'
movwf data2
call commandeLCD
movlw 'I'
movwf data2
call commandeLCD
goto _date
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; date0 : bit 5 bit 4 -> dizaines (00 à 11)
; b3b2b1b0 -> unités (0000 à 1001)
_date
movlw ' ' ; affichage espace
movwf data2
call commandeLCD
; affichage dizaine
; si etape = 2 et (clignotement,1) = 1
; alors on affiche un espace
movlw .2 ; W = .2
subwf etape,w ; W = (etape) - .2
btfss STATUS,Z ; test du bit Z
goto datedizaine ; Z = 0 c'est-à-dire (etape) != .2
btfss clignotement,1
goto datedizaine
; on affiche ' '
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw ' '
movwf data2
call commandeLCD
goto dateunite
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
datedizaine
movf date0,w
movwf chiffre ; (chiffre) = (date0)
movlw B'00110000' ; masque
andwf chiffre,f ; fonction ET logique
swapf chiffre,f ; (chiffre) = (000000b5b4)
call affichagechiffre
; affichage unité
dateunite
; si etape = 3 et (clignotement,1) = 1
; alors on affiche un espace
movlw .3 ; W = .3
subwf etape,w ; W = (etape) - .3
btfss STATUS,Z ; test du bit Z
goto dateunite0 ; Z = 0 c'est-à-dire (etape) != .3
btfss clignotement,1
goto dateunite0
; on affiche ' '
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw ' '
movwf data2
call commandeLCD
goto moisdizaine
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
dateunite0
movf date0,w
movwf chiffre ; (chiffre) = (date)
movlw B'00001111' ; masque
andwf chiffre,f ; fonction ET logique (chiffre) = (0000b3b2b1b0)
call affichagechiffre
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; mois0 : b4 -> dizaines (0 à 1)
; b3b2b1b0 -> unités (0000 à 1001)
moisdizaine
movlw '/' ; affichage '/'
movwf data2
call commandeLCD
; affichage dizaine
; si etape = 4 et (clignotement,1) = 1
; alors on affiche un espace
movlw .4 ; W = .4
subwf etape,w ; W = (etape) - .4
btfss STATUS,Z ; test du bit Z
goto moisdizaine0 ; Z = 0 c'est-à-dire (etape) != .4
btfss clignotement,1
goto moisdizaine0
; on affiche ' '
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw ' '
movwf data2
call commandeLCD
goto moisunite
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
moisdizaine0
movf mois0,w
movwf chiffre ; (chiffre) = (mois)
movlw B'00010000' ; masque
andwf chiffre,f ; fonction ET logique
swapf chiffre,f ; (chiffre) = (0000000b4)
call affichagechiffre
; affichage unité
moisunite
; si etape = 5 et (clignotement,1) = 1
; alors on affiche un espace
movlw .5 ; W = .5
subwf etape,w ; W = (etape) - .5
btfss STATUS,Z ; test du bit Z
goto moisunite0 ; Z = 0 c'est-à-dire (etape) != .5
btfss clignotement,1
goto moisunite0
; on affiche ' '
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw ' '
movwf data2
call commandeLCD
goto anneedizaine
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
moisunite0
movf mois0,w
movwf chiffre ; (chiffre) = (mois)
movlw B'00001111' ; masque
andwf chiffre,f ; fonction ET logique (chiffre) = (0000b3b2b1b0)
call affichagechiffre
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; annee0 : b7b6b5b4 -> dizaines (0000 à 1001)
; b3b2b1b0 -> unités (0000 à 1001)
anneedizaine
movlw '/' ; affichage '/'
movwf data2
call commandeLCD
movlw '2' ; affichage année 2XXX
movwf data2
call commandeLCD
movlw '0' ; affichage année 20XX
movwf data2
call commandeLCD
; affichage dizaine
; si etape = 6 et (clignotement,1) = 1
; alors on affiche un espace
movlw .6 ; W = .6
subwf etape,w ; W = (etape) - .6
btfss STATUS,Z ; test du bit Z
goto anneedizaine0 ; Z = 0 c'est-à-dire (etape) != .6
btfss clignotement,1
goto anneedizaine0
; on affiche ' '
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw ' '
movwf data2
call commandeLCD
goto anneeunite
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
anneedizaine0
movf annee0,w
movwf chiffre ; (chiffre) = (annee)
movlw B'11110000' ; masque
andwf chiffre,f ; fonction ET logique
swapf chiffre,f ; (chiffre) = (0000b7b6b5b4)
call affichagechiffre
; affichage unité
anneeunite
; si etape = 7 et (clignotement,1) = 1
; alors on affiche un espace
movlw .7 ; W = .7
subwf etape,w ; W = (etape) - .7
btfss STATUS,Z ; test du bit Z
goto anneeunite0 ; Z = 0 c'est-à-dire (etape) != .7
btfss clignotement,1
goto anneeunite0
; on affiche ' '
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw ' '
movwf data2
call commandeLCD
goto heuredizaine
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
anneeunite0
movf annee0,w
movwf chiffre ; (chiffre) = (annee)
movlw B'00001111' ; masque
andwf chiffre,f ; fonction ET logique (chiffre) = (0000b3b2b1b0)
call affichagechiffre
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; On se positionne sur la deuxième ligne
; Instruction Set DDRAM Address
heuredizaine
movlw B'00000000'
movwf data1
movlw B'11000000' ; adresse 0x40
movwf data2
call commandeLCD
; on affiche ' '
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw ' '
movwf data2
call commandeLCD
movlw ' '
movwf data2
call commandeLCD
movlw ' '
movwf data2
call commandeLCD
movlw ' '
movwf data2
call commandeLCD
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; heures0 : b5b4 -> dizaines (00 à 10)
; b3b2b1b0 -> unités (0000 à 1001)
; affichage dizaine
; si etape = 8 et (clignotement,1) = 1
; alors on affiche un espace
movlw .8 ; W = .8
subwf etape,w ; W = (etape) - .8
btfss STATUS,Z ; test du bit Z
goto heuredizaine0 ; Z = 0 c'est-à-dire (etape) != .8
btfss clignotement,1
goto heuredizaine0
; on affiche ' '
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw ' '
movwf data2
call commandeLCD
goto heureunite
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
heuredizaine0
movf heures0,w
movwf chiffre ; (chiffre) = (heures)
movlw B'00110000' ; masque
andwf chiffre,f ; fonction ET logique
swapf chiffre,f ; (chiffre) = (000000b5b4)
call affichagechiffre
; affichage unité
heureunite
; si etape = 9 et (clignotement,1) = 1
; alors on affiche un espace
movlw .9 ; W = .9
subwf etape,w ; W = (etape) - .9
btfss STATUS,Z ; test du bit Z
goto heureunite0 ; Z = 0 c'est-à-dire (etape) != .9
btfss clignotement,1
goto heureunite0
; on affiche ' '
; Instruction "Write Data into DDRAM"
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw ' '
movwf data2
call commandeLCD
goto minutedizaine
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
heureunite0
movf heures0,w
movwf chiffre ; (chiffre) = (date)
movlw B'00001111' ; masque
andwf chiffre,f ; fonction ET logique (chiffre) = (0000b3b2b1b0)
call affichagechiffre
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; minutes0 : b6b5b4 -> dizaines (000 à 101)
; b3b2b1b0 -> unités (0000 à 1001)
minutedizaine
movlw ':' ; affichage ':'
movwf data2
call commandeLCD
; affichage dizaine
; si etape = 10 et (clignotement,1) = 1
; alors on affiche un espace
movlw .10 ; W = .10
subwf etape,w ; W = (etape) - .10
btfss STATUS,Z ; test du bit Z
goto minutedizaine0 ; Z = 0 c'est-à-dire (etape) != .10
btfss clignotement,1
goto minutedizaine0
; on affiche ' '
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw ' '
movwf data2
call commandeLCD
goto minuteunite
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
minutedizaine0
movf minutes0,w
movwf chiffre ; (chiffre) = (annee)
movlw B'01110000' ; masque
andwf chiffre,f ; fonction ET logique
swapf chiffre,f ; (chiffre) = (0000b7b6b5b4)
call affichagechiffre
; affichage unité
minuteunite
; si etape = 11 et (clignotement,1) = 1
; alors on affiche un espace
movlw .11 ; W = .11
subwf etape,w ; W = (etape) - .11
btfss STATUS,Z ; test du bit Z
goto minuteunite0 ; Z = 0 c'est-à-dire (etape) != .11
btfss clignotement,1
goto minuteunite0
; on affiche ' '
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw ' '
movwf data2
call commandeLCD
goto secondedizaine
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
minuteunite0
movf minutes0,w
movwf chiffre ; (chiffre) = (annee)
movlw B'00001111' ; masque
andwf chiffre,f ; fonction ET logique (chiffre) = (0000b3b2b1b0)
call affichagechiffre
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; secondes0 : b6b5b4 -> dizaines (000 à 101)
; b3b2b1b0 -> unités (0000 à 1001)
secondedizaine
movlw ':' ; affichage ':'
movwf data2
call commandeLCD
; affichage dizaine
movf etape,w
btfsc STATUS,Z
goto secondedizaine0
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw '0'
movwf data2
call commandeLCD
goto secondeunite
secondedizaine0
movf secondes0,w
movwf chiffre ; (chiffre) = (annee)
movlw B'01110000' ; masque
andwf chiffre,f ; fonction ET logique
swapf chiffre,f ; (chiffre) = (0000b7b6b5b4)
call affichagechiffre
; affichage unité
secondeunite
movf etape,w
btfsc STATUS,Z
goto secondeunite0
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw '0'
movwf data2
call commandeLCD
return
secondeunite0
movf secondes0,w
movwf chiffre ; (chiffre) = (annee)
movlw B'00001111' ; masque
andwf chiffre,f ; fonction ET logique (chiffre) = (0000b3b2b1b0)
call affichagechiffre
return
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine affichage d'un chiffre sur le module LCD
; 1 variable d'entrée : chiffre
; (chiffre) doit contenir un nombre
; compris entre (00000000) et (00001001) 0 à 9
; Pas de variable de sortie
affichagechiffre
BANK0
movlw B'00000010'
movwf data1 ; RS = 1 R/W = 0
movlw '0'
addwf chiffre,w
movwf data2
call commandeLCD
return
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Initialisation
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
initialisation
BANK0
clrf PORTA ; mise à 0 des sorties du port A
clrf PORTB ; mise à 0 des sorties du port B
clrf PORTC ; mise à 0 des sorties du port C
movlw 0x20 ; RAZ toute la zone mémoire des variables.
movwf FSR ; on charge l'adresse de début.
init_01 clrf INDF ; effacement du contenu du registre pointé par FSR
incf FSR,f
movlw 0x7F+.1 ; adresse de fin + 1.)
subwf FSR, W
btfss STATUS,Z
goto init_01
movlw .13
movwf temp
retard_500ms
decfsz cpt1_bp,f ; 0,5 sec de tempo pour laisser le temps à l'fficheur LCD de démarrer.
goto retard_500ms
decfsz cpt2_bp,f
goto retard_500ms
decfsz temp,f
goto retard_500ms
clrf cpt_oct
movlw 1
movwf cpt_bit
movwf cpt_init
movlw b'00100010'
movwf heure_bcd
movlw b'00100100'
movwf minute_bcd
movlw b'01001000'
movwf seconde_bcd
movlw b'00000110'
movwf lundi_bcd
movlw b'00000110'
movwf jour_bcd
movlw b'00000111'
movwf mois_bcd
BANK1
movlw B'00111111'
movwf OPTION_REG
; bit 7 (/RBPU) = 0 : PORTB pull-ups are enabled (boutons poussoirs sur RB1 et RB2)
; bit 6 (INTEDG) = 0 : Interrupt on falling edge of RB0/INT pin
; bit 3 (PSA) = 1
; bit 2 (PS2) = 1
; bit 1 (PS1) = 1
; bit 0 (PS0) = 1
; watchdog : prescaler 1:128 (environ 2,3 secondes)
movlw B'00000110'
movwf ADCON1 ; les broches RA0, RA1, RA2, RA3 et RA5 sont configurées commme entrée/sortie de type numérique
movlw B'11110000'
movwf TRISA
; bit 0 du port A (RA0) = 0 : configuration en sortie (DB4, module LCD)
; bit 1 du port A (RA1) = 0 : configuration en sortie (DB5, module LCD)
; bit 2 du port A (RA2) = 0 : configuration en sortie (DB6, module LCD)
; bit 3 du port A (RA3) = 0 : configuration en sortie (DB7, module LCD)
; bit 5 du port A (RA5) = 0 : configuration en sortie (Sortie vers Horloge ACEB)
movlw B'11000111'
movwf TRISB
; bit 0 du port B (RB0) = 1 : configuration en entrée (reliée à la sortie SQW/OUT du DS1307
; signal de fréquence 1,000 000 Hz)
; bit 1 du port B (RB1) = 1 : configuration en entrée (Bouton poussoir 1)
; bit 2 du port B (RB2) = 1 : configuration en entrée (Bouton poussoir 2)
; bit 3 du port B (RB3) = 0 : configuration en sortie (RS, module LCD)
; bit 4 du port B (RB4) = 0 : configuration en sortie (R/W, module LCD)
; bit 5 du port B (RB5) = 0 : configuration en sortie (E, module LCD)
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Configuration du module MSSP du PIC 16F876A (I2C maître)
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
BANK1
bsf TRISC,3 ; broche RC3/SCK/SCL configurée en entrée
bsf TRISC,4 ; broche RC4/SDI/SDA configurée en entrée
bcf TRISC,6 ; ACEB
bcf TRISC,7
bsf SSPSTAT,SMP ; bit 7 (SMP) = 1 : fréquence de l'horloge du bus I2C : F SCL = 100 kHz
bcf SSPSTAT,CKE ; bit 6 (CKE) = 0 : Disable SMBus specific inputs
movlw 0x31
movwf SSPADD ; (SSPADD) = (FOSC / (4*f SCL)) - 1 = 0x31
; FOSC = 20 MHz
BANK0
movlw B'00101000'
movwf SSPCON
; bit 5 (SSPEN) = 1 : enable the MSSP
; bit 3 (SSPM3) = 1
; bit 2 (SSPM2) = 0
; bit 1 (SSPM1) = 0
; bit 0 (SSPM0) = 0
; (SSPM3:SSPM0) = (1000) : MSSP configuré dans le mode I2C maître
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Initialisation du module LCD (interface 4 bits)
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Instruction "Set Function"
; Choix du mode 4 bits (à la mise sous tension : mode 8 bits par défaut)
; RS R/W DB7 DB6 DB5 DB4
; 0 0 0 0 1 0
bcf PORTB,5 ; E = 0
nop
bcf PORTB,3 ; RS = 0
nop
bcf PORTB,4 ; R/W = 0
nop
bcf PORTA,0 ; DB4 = 0
nop
bsf PORTA,1 ; DB5 = 1
nop
bcf PORTA,2 ; DB6 = 0
nop
bcf PORTA,3 ; DB7 = 0
nop
bsf PORTB,5 ; E = 1
nop
nop
nop
nop
nop
nop
nop ; une pause de 5 x 200 ns = 1 µs (220 ns suffisent)
bcf PORTB,5 ; E = 0
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Pause de 3 x 256 x 0,2 = 153,6 µs (N.B. 39 µs suffisent)
clrf cpt1_bp
clrf cpt2_bp
retard_40ms
decfsz cpt1_bp,f ; 40 msec de tempo pour laisser le temps à l'fficheur LCD de démarrer.
goto retard_40ms
decfsz cpt2_bp,f
goto retard_40ms
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; data1 : contient le niveau des bits RS et R/W (module LCD):
; (000000 RS R/W)
; data2 : contient le niveau des bits DB7-DB0 (module LCD):
; (DB7 ... DB0)
; Instruction "Set Function" (DL = 0, N = 1, F = 0)
movlw B'00000000'
movwf data1
movlw B'00101000'
movwf data2
call commandeLCD
; Instruction "Set Function" (DL = 0, N = 1, F = 0)
; on recommence par précaution
movlw B'00000000'
movwf data1
movlw B'00101000'
movwf data2
call commandeLCD
; Instruction "Display On/Off" (D = 1,C = 0,B = 0)
movlw B'00000000'
movwf data1
movlw B'00001100'
movwf data2
call commandeLCD
; Instruction "Entry Mode Set" (I/D = 1,SH = 0)
movlw B'00000000'
movwf data1
movlw B'00000110'
movwf data2
call commandeLCD
; Instruction "Display Clear"
movlw B'00000000'
movwf data1
movlw B'00000001'
movwf data2
call commandeLCD
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Configuration DS1307 (Real Time Clock) bus I2C esclave
; adresse I2C : 1011000
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Ecriture dans le registre de contrôle (adresse 0x07) du DS1307
call I2C_start
movlw B'11010000' ; 8 bits à écrire (7 bits d'adresse + RW)
; 1011000 + 0 (write)
call I2C_write
call I2C_ACK_slave_to_master
movlw 0x07 ; 8 bits à écrire (adresse du registre de contrôle du DS1307)
call I2C_write
call I2C_ACK_slave_to_master
movlw B'00010000' ; écriture du contenu du registre de contrôle du DS1307
; bit 4 : SQWE = 1
; bit 1 : RS1 = 0
; bit 0 : RS0 = 0
; 1,000 000 Hz sur la sortie SQW/OUT
call I2C_write
call I2C_ACK_slave_to_master
call I2C_stop
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Lecture dans le registre d'adresse 0x00 (seconds) du DS1307
call I2C_start
movlw B'11010000' ; 8 bits à écrire (7 bits d'adresse I2C + 0 Write )
call I2C_write
call I2C_ACK_slave_to_master
movlw B'00000000' ; 8 bits à écrire (registre d'adresse 0x00)
call I2C_write
call I2C_ACK_slave_to_master
call I2C_Repeated_Start
movlw B'11010001' ; 8 bits à écrire (7 bits d'adresse + 1 Read)
call I2C_write
call I2C_ACK_slave_to_master
call I2C_read
movwf secondes ; lecture des secondes (registre d'adresse 0x00)
call I2C_NOACK
call I2C_stop
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Ecriture dans le registre d'adresse 0x00 (secondes) du DS1307
call I2C_start
movlw B'11010000' ; 8 bits à écrire (7 bits d'adresse + RW)
; 1011000 + 0 (write)
call I2C_write
call I2C_ACK_slave_to_master
movlw 0x00 ; 8 bits à écrire (adresse du registre du DS1307)
call I2C_write
call I2C_ACK_slave_to_master
bcf secondes,7 ; bit 7 (CH) = 0 : enable the oscillator
movf secondes,w ; écriture du contenu du registre
call I2C_write
call I2C_ACK_slave_to_master
call I2C_stop
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Lecture dans le registre d'adresse 0x02 (seconds) du DS1307
call I2C_start
movlw B'11010000' ; 8 bits à écrire (7 bits d'adresse I2C + 0 Write )
call I2C_write
call I2C_ACK_slave_to_master
movlw B'00000010' ; 8 bits à écrire (registre d'adresse 0x02)
call I2C_write
call I2C_ACK_slave_to_master
call I2C_Repeated_Start
movlw B'11010001' ; 8 bits à écrire (7 bits d'adresse + 1 Read)
call I2C_write
call I2C_ACK_slave_to_master
call I2C_read
movwf heures ; lecture des heures (registre d'adresse 0x02)
call I2C_NOACK
call I2C_stop
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; écriture dans le registre d'adresse 0x02 (hours) du DS1307
call I2C_start
movlw B'11010000' ; 8 bits à écrire (7 bits d'adresse + RW)
; 1011000 + 0 (write)
call I2C_write
call I2C_ACK_slave_to_master
movlw 0x02 ; 8 bits à écrire (adresse du registre du DS1307)
call I2C_write
call I2C_ACK_slave_to_master
bcf heures,6 ; bit 6 (AM/PM) = 0 : mode 24 heures
movf heures,w ; écriture du contenu du registre
call I2C_write
call I2C_ACK_slave_to_master
call I2C_stop
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Configuration du TIMER1 (16 bits) en mode timer
BANK0
movlw b'00001010' ; 1010= Compare mode, generate software interrupt on match (CCPxIF bit is set, CCPx pin is unaffected)
movwf CCP1CON
movlw B'00010000'
movwf T1CON ; bit 5 (T1CKPS1) = 0 : prescaler 1:2 ; bit 4 (T1CKPS0) = 0 ; bit 1 (TMR1CS) = 0 : Internal clock (FOSC/4) ; bit 0 (TMR1ON) = 1 : Enables Timer1
movlw 0xFE
movwf CCPR1L
movlw 0xFF
movwf CCPR1H ; Pour envoyer la première trame vers l'horloge ACEB avec un peu de retard (26 msec).
clrf TMR1L
clrf TMR1H
BANK0
clrf PIR1 ; Efface le Flag CCP1 Interrupt Enable bit.
clrf PIR2 ; Efface le Flag CCP1 Interrupt Enable bit.
clrf INTCON ; Efface le Flag RA0
BANK1
clrf PIE1 ;
clrf PIE2 ;
bsf PIE1,CCP1IE ; CCP1 Interrupt Enable bit
BANK0
bsf INTCON,PEIE ; 1= Enables all unmasked peripheral interrupts
bsf INTCON,INTE ; 1= Enables the RB0/INT external interrupt
bsf INTCON,GIE ; 1= Enables all unmasked interrupts
bsf T1CON,TMR1ON ; Mise en marche du Timer1. Programme d'interruption pour envoyer la trame à l'horloge ACEB.
movlw 1
movwf cpt_bit ; Spécial ACEB
movwf cpt_init
bsf boutonpoussoir,1
bsf boutonpoussoir,2
bsf boutonpoussoirbak,1
bsf boutonpoussoirbak,2
clrf boutonpoussoiractivite
clrf etape ; étape n°0 (mode normal)
clrf clignotement ; bit 1 = 0 (affichage)
movlw .10 ; Tempo x fois 95 msec avant d'envoyer une trame à l'horloge ACEB
movwf cpt3_bp
bsf etat_bit,0 ; et l'on lire la premièere fois l'horloge sans attentdre la fin de l'envoi de la trame.
bsf etat_bit,1 ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Programme principal
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
debut_programme
btfss etat_bit,0
goto fin_DS
btfss etat_bit,1
goto fin_DS
bcf etat_bit,0 ; On passe ici quand on a reçu un top seconde du DS1307 et que le programme a fini d'envoyer une trame complète à l'horloge ACEB.
bcf etat_bit,1 ; Raz des bits d'état pour la prochaine fois.
movf etape,f ; (etape) = (etape)
btfss STATUS,Z ; test du bit Z
goto fin_DS ; Z = 0 c'est-à-dire (etape) != .0
clrf clignotement ; bit 1 = 0 (affichage)
; étape n°0 (mode normal) PAS DE CAPTEUR DE TEMPERATURE
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Lecture du calendrier (DS1307)
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
call I2C_start
movlw B'11010000' ; 8 bits à écrire (7 bits d'adresse I2C + 0 Write )
call I2C_write
call I2C_ACK_slave_to_master
movlw B'00000000' ; 8 bits à écrire (registre d'adresse 0x00)
call I2C_write
call I2C_ACK_slave_to_master
call I2C_Repeated_Start
movlw B'11010001' ; 8 bits à écrire (7 bits d'adresse + 1 Read)
call I2C_write
call I2C_ACK_slave_to_master
call I2C_read
movwf secondes ; lecture des secondes (registre d'adresse 0x00)
call I2C_ACK_master_to_slave
call I2C_read
movwf minutes ; lecture des minutes (registre d'adresse 0x01)
call I2C_ACK_master_to_slave
call I2C_read
movwf heures ; lecture des heures (registre d'adresse 0x02)
call I2C_ACK_master_to_slave
call I2C_read
movwf jours ; lecture des jours (registre d'adresse 0x03)
call I2C_ACK_master_to_slave
call I2C_read
movwf date ; lecture de la dates (registre d'adresse 0x04)
call I2C_ACK_master_to_slave
call I2C_read
movwf mois ; lecture des mois (registre d'adresse 0x05)
call I2C_ACK_master_to_slave
call I2C_read
movwf annee ; lecture de l'année (registre d'adresse 0x06)
call I2C_NOACK
call I2C_stop
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Mise à jour de l'affichage du module LCD
BANK0
movlw B'00000111' ; masque
andwf jours,f ; fonction ET logique
movf jours,w ; W = (jours)
movwf jours0 ; (jours0) = (jours)
movf date,w ; W = (date)
movwf date0 ; (date0) = (date)
movf mois,w ; W = (mois)
movwf mois0 ; (mois0) = (mois)
movf annee,w ; W = (annee)
movwf annee0 ; (annee0) = (annee)
movf heures,w ; W = (heures)
movwf heures0 ; (heures0) = (heures)
movf minutes,w ; W = (minutes)
movwf minutes0 ; (minutes0) = (minutes)
movf secondes,w ; W = (minutes)
movwf secondes0 ; (minutes0) = (minutes)
call affichageLCDdateheure
; Initialisation des variables pour envoyer une trame vers ACEB.
; A ce moment, on est sûr que l'on n'est pas en train d'envoyer une trame.
movf jours,w ; W = (jours)
movwf lundi_bcd
movf date,w ; W = (date)
movwf jour_bcd
movf mois,w ; W = (mois)
movwf mois_bcd
movf heures,w ; W = (heures)
movwf heure_bcd
movf minutes,w ; W = (minutes)
movwf minute_bcd
movf secondes,w ; W = (minutes)
movwf seconde_bcd
fin_DS
decf cpt1_bp,f
btfss STATUS,Z
goto debut_programme
decf cpt2_bp,f
btfss STATUS,Z
goto debut_programme
decf cpt3_bp,f
btfsc STATUS,Z
bsf etat_bit,2 ; Bit(2)=1 => On autorise à envoyer des trames à l'horloge ACEB.
; On passe ici une fois toutes les 95 msec.
; on teste si on a appuyé sur le bouton BP1 ou BP2.
call BP1
call BP2
; si (etape) = 0 et BP1 non appuyé et BP2 non appuyé alors retour
BANK0
btfsc boutonpoussoiractivite,1
goto Bouton_pous_1
btfsc boutonpoussoiractivite,2
goto Bouton_pous_1
movf etape,f ; (etape) = (etape)
btfss STATUS,Z ; test du bit Z
goto Bouton_pous_1
goto etape_fin_fin
Bouton_pous_1
; si BP1 a été appuyé : incrémentation du numéro d'étape
btfss boutonpoussoiractivite,1
goto Bouton_pas_pous_1 ; BP1 n'a pas été appuyé
clrf secondes
clrf secondes0
incf etape,f
; si (etape > .11) alors (etape = .0)
movf etape,w ; W = (etape)
sublw .11 ; W = .11 - (etape)
btfsc STATUS,C ; test du bit C (Carry)
goto etape_fin_fin ; C = 1 c'est-à-dire (etape)<= .11
; C = 0 c'est-à-dire (etape)> .11
clrf etape ; (etape) = .0
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; écriture de la nouvelle date/heure dans DS1307
call I2C_start
movlw B'11010000' ; 8 bits à écrire (7 bits d'adresse + RW) ; 1011000 + 0 (write)
call I2C_write
call I2C_ACK_slave_to_master
movlw 0x00 ; 8 bits à écrire (adresse du registre du DS1307)
call I2C_write
call I2C_ACK_slave_to_master
;;;; movf secondes0,w ; écriture dans le registre d'adresse 0x00
movlw .0 ; écriture dans le registre d'adresse 0x00 ON MET A JOUR LE DS1307 AVEC LES SECONDES A 00 !!!
call I2C_write
call I2C_ACK_slave_to_master
movf minutes0,w ; écriture dans le registre d'adresse 0x01
call I2C_write
call I2C_ACK_slave_to_master
movf heures0,w ; écriture dans le registre d'adresse 0x02
call I2C_write
call I2C_ACK_slave_to_master
movf jours0,w ; écriture dans le registre d'adresse 0x03
call I2C_write
call I2C_ACK_slave_to_master
movf date0,w ; écriture dans le registre d'adresse 0x04
call I2C_write
call I2C_ACK_slave_to_master
movf mois0,w ; écriture dans le registre d'adresse 0x05
call I2C_write
call I2C_ACK_slave_to_master
movf annee0,w ; écriture dans le registre d'adresse 0x06
call I2C_write
call I2C_ACK_slave_to_master
call I2C_stop
goto etape_fin
Bouton_pas_pous_1
; test BP2
btfss boutonpoussoiractivite,2
goto etape_fin ; BP2 n'a pas été appuyé
; BP2 a été appuyé
; on teste si (etape = 1)
etape01 ; jours
movlw .1 ; W = .1
subwf etape,w ; W = (etape) - .1
btfss STATUS,Z ; test du bit Z
goto etape02 ; Z = 0 c'est-à-dire (etape) != .1
incf jours0,f
; si (jours0) > .7 alors (jours0) = .1
movf jours0,w ; W = (jours0)
sublw .7 ; W = .7 - (jours0)
btfsc STATUS,C ; test du bit C (Carry)
goto etape_fin ; C = 1 c'est-à-dire (jours0)<= .7
movlw .1
movwf jours0 ; (jours0) = .1
goto etape_fin
; on teste si (etape = 2)
etape02 ; date (chiffre des dizaines)
movlw .2 ; W = .2
subwf etape,w ; W = (etape) - .2
btfss STATUS,Z ; test du bit Z
goto etape03 ; Z = 0 c'est-à-dire (etape) != .2
; on incrémente la date (chiffre des dizaines)
movlw 0x10
addwf date0,f ; (date0) = (date0) + 0x10
; si (date0) > 0x31 alors (date0) = 0x01
movf date0,w ; W = (date0)
sublw 0x31 ; W = 0x31 - (date0)
btfsc STATUS,C ; test du bit C (Carry)
goto etape_fin ; C = 1 c'est-à-dire (date0)<= 0x31
;(date0) > 0x31
movlw 0x01
movwf date0 ; (date0) = 0x01
goto etape_fin
; on teste si (etape = 3)
etape03 ; date (chiffre des unités)
movlw .3 ; W = .3
subwf etape,w ; W = (etape) - .3
btfss STATUS,Z ; test du bit Z
goto etape04 ; Z = 0 c'est-à-dire (etape) != .3
; on incrémente la date (chiffre des unités)
incf date0,f ; (date0) = (date0) + 0x01
; si (chiffre des unités) > .9 alors (chiffre des unités) =.0
movf date0,w ; W = (date0)
movwf tampon ; (tampon) = (date0)
movlw B'00001111' ; masque
andwf tampon,f ; fonction ET logique
movf tampon,w ; W = (tampon)
sublw .9 ; W = .9 - (tampon)
btfsc STATUS,C ; test du bit C (Carry)
goto etape03_0 ; C = 1 c'est-à-dire (tampon)<= .9
;(tampon) > .9
movlw B'11110000' ; masque
andwf date0,f
goto etape03_0
etape03_0
; si (date0) > 0x31 alors (date0) = 0x30
movf date0,w ; W = (date0)
sublw 0x31 ; W = 0x31 - (date0)
btfsc STATUS,C ; test du bit C (Carry)
goto etape03_1 ; C = 1 c'est-à-dire (date0)<= 0x31
movlw 0x30
movwf date0 ; (date0) = 0x30
goto etape03_1
etape03_1
; si (date0) = 0x00 alors (date0) = 0x01
movf date0,f ; (date0) = (date0)
btfss STATUS,Z ; test du bit Z
goto etape_fin ; Z = 0 c'est-à-dire (date0) != 0x00
movlw 0x01
movwf date0 ; (date0) = 0x01
goto etape_fin
; on teste si (etape = 4)
etape04 ; mois (chiffre des dizaines)
movlw .4 ; W = .4
subwf etape,w ; W = (etape) - .4
btfss STATUS,Z ; test du bit Z
goto etape05 ; Z = 0 c'est-à-dire (etape) != .4
; on incrémente le mois (chiffre des dizaines)
movlw 0x10
addwf mois0,f ; (mois0) = (mois0) + 0x10
; si (mois0) > 0x12 alors (mois0) = 0x01
movf mois0,w ; W = (mois0)
sublw 0x12 ; W = 0x12 - (mois0)
btfsc STATUS,C ; test du bit C (Carry)
goto etape_fin ; C = 1 c'est-à-dire (mois0)<= 0x12
;(mois0) > 0x12
movlw 0x01
movwf mois0 ; (mois0) = 0x01
goto etape_fin
; on teste si (etape = 5)
etape05 ; mois (chiffre des unités)
movlw .5 ; W = .5
subwf etape,w ; W = (etape) - .5
btfss STATUS,Z ; test du bit Z
goto etape06 ; Z = 0 c'est-à-dire (etape) != .5
; on incrémente le mois (chiffre des unités)
incf mois0,f ; (mois0) = (mois0) + 0x01
; si (chiffre des unités) > .9 alors (chiffre des unités) =.0
movf mois0,w ; W = (mois0)
movwf tampon ; (tampon) = (mois0)
movlw B'00001111' ; masque
andwf tampon,f ; fonction ET logique
movf tampon,w ; W = (tampon)
sublw .9 ; W = .9 - (tampon)
btfsc STATUS,C ; test du bit C (Carry)
goto etape05_0 ; C = 1 c'est-à-dire (tampon)<= .9
;(tampon) > .9
movlw B'11110000' ; masque
andwf mois0,f
goto etape05_0
etape05_0
; si (mois0) > 0x12 alors (mois0) = 0x10
movf mois0,w ; W = (mois0)
sublw 0x12 ; W = 0x12 - (mois0)
btfsc STATUS,C ; test du bit C (Carry)
goto etape05_1 ; C = 1 c'est-à-dire (mois0)<= 0x12
movlw 0x10
movwf mois0 ; (mois0) = 0x10
goto etape05_1
etape05_1
; si (mois0) = 0x00 alors (mois0) = 0x01
movf mois0,f ; (mois0) = (mois0)
btfss STATUS,Z ; test du bit Z
goto etape_fin ; Z = 0 c'est-à-dire (mois0) != 0x00
movlw 0x01
movwf mois0 ; (mois0) = 0x01
goto etape_fin
; on teste si (etape = 6)
etape06 ; année (chiffre des dizaines)
movlw .6 ; W = .6
subwf etape,w ; W = (etape) - .6
btfss STATUS,Z ; test du bit Z
goto etape07 ; Z = 0 c'est-à-dire (etape) != .6
; on incrémente l'année (chiffre des dizaines)
movlw 0x10
addwf annee0,f ; (annee0) = (annee0) + 0x10
; si (chiffre des dizaines) > .9 alors (chiffre des dizaines) =.0
movf annee0,w ; W = (annee0)
sublw 0x9F ; W = 0x9F - (annee0)
btfsc STATUS,C ; test du bit C (Carry)
goto etape_fin ; C = 1 c'est-à-dire (chiffre des dizaines)<= .9
;(chiffre des dizaines) > .9
movlw B'00001111' ; masque
andwf annee0,f
goto etape_fin
; on teste si (etape = 7)
etape07 ; année (chiffre des unités)
movlw .7 ; W = .7
subwf etape,w ; W = (etape) - .7
btfss STATUS,Z ; test du bit Z
goto etape08 ; Z = 0 c'est-à-dire (etape) != .7
; on incrémente l'année (chiffre des unités)
incf annee0,f ; (annee0) = (annee0) + 0x01
; si (chiffre des unités) > .9 alors (chiffre des unités) =.0
movf annee0,w ; W = (annee0)
movwf tampon ; (tampon) = (annee0)
movlw B'00001111' ; masque
andwf tampon,f ; fonction ET logique
movf tampon,w ; W = (tampon)
sublw .9 ; W = .9 - (tampon)
btfsc STATUS,C ; test du bit C (Carry)
goto etape_fin ; C = 1 c'est-à-dire (tampon)<= .9
;(tampon) > .9
movlw B'11110000' ; masque
andwf annee0,f
goto etape_fin
; on teste si (etape = 8)
etape08 ; heures (chiffre des dizaines)
movlw .8 ; W = .8
subwf etape,w ; W = (etape) - .8
btfss STATUS,Z ; test du bit Z
goto etape09 ; Z = 0 c'est-à-dire (etape) != .8
; on incrémente l'heure (chiffre des dizaines)
movlw 0x10
addwf heures0,f ; (heures0) = (heures0) + 0x10
; si (heures0) > 0x23 alors (heures0) = 0x00
movf heures0,w ; W = (heures0)
sublw 0x23 ; W = 0x23 - (heures0)
btfsc STATUS,C ; test du bit C (Carry)
goto etape_fin ; C = 1 c'est-à-dire (heures0)<= 0x23
;(heures0) > 0x23
clrf heures0 ; (heures0) = 0x00
goto etape_fin
; on teste si (etape = 9)
etape09 ; heures (chiffre des unités)
movlw .9 ; W = .9
subwf etape,w ; W = (etape) - .9
btfss STATUS,Z ; test du bit Z
goto etape10 ; Z = 0 c'est-à-dire (etape) != .9
; on incrémente l'heures (chiffre des unités)
incf heures0,f ; (heures0) = (heures0) + 0x01
; si (chiffre des unités) > .9 alors (chiffre des unités) =.0
movf heures0,w ; W = (heures0)
movwf tampon ; (tampon) = (heures0)
movlw B'00001111' ; masque
andwf tampon,f ; fonction ET logique
movf tampon,w ; W = (tampon)
sublw .9 ; W = .9 - (tampon)
btfsc STATUS,C ; test du bit C (Carry)
goto etape09_0 ; C = 1 c'est-à-dire (tampon)<= .9
;(tampon) > .9
movlw B'11110000' ; masque
andwf heures0,f
goto etape09_0
etape09_0
; si (heures0) > 0x23 alors (heures0) = 0x20
movf heures0,w ; W = (heures0)
sublw 0x23 ; W = 0x23 - (heures0)
btfsc STATUS,C ; test du bit C (Carry)
goto etape_fin ; C = 1 c'est-à-dire (heures0)<= 0x23
movlw 0x20
movwf heures0 ; (heures0) = 0x20
goto etape_fin
; on teste si (etape = 10)
etape10 ; minutes (chiffre des dizaines)
movlw .10 ; W = .10
subwf etape,w ; W = (etape) - .10
btfss STATUS,Z ; test du bit Z
goto etape11 ; Z = 0 c'est-à-dire (etape) != .10
; on incrémente les minutes (chiffre des dizaines)
movlw 0x10
addwf minutes0,f ; (minutes0) = (minutes0) + 0x10
; si (chiffre des dizaines) > .5 alors (chiffre des dizaines) =.0
movf minutes0,w ; W = (minutes0)
sublw 0x5F ; W = 0x5F - (minutes0)
btfsc STATUS,C ; test du bit C (Carry)
goto etape_fin ; C = 1 c'est-à-dire (chiffre des dizaines)<= .5
;(chiffre des dizaines) > .5
movlw B'00001111' ; masque
andwf minutes0,f
goto etape_fin
; on teste si (etape = 11)
etape11 ; minutes (chiffre des unités)
movlw .11 ; W = .11
subwf etape,w ; W = (etape) - .11
btfss STATUS,Z ; test du bit Z
goto etape_fin_fin ; Z = 0 c'est-à-dire (etape) != .11
; normalement on ne doit pas arriver ici ...
; on incrémente les minutes (chiffre des unités)
incf minutes0,f ; (minutes0) = (minutes0) + 0x01
; si (chiffre des unités) > .9 alors (chiffre des unités) =.0
movf minutes0,w ; W = (minutes0)
movwf tampon ; (tampon) = (annee0)
movlw B'00001111' ; masque
andwf tampon,f ; fonction ET logique
movf tampon,w ; W = (tampon)
sublw .9 ; W = .9 - (tampon)
btfsc STATUS,C ; test du bit C (Carry)
goto etape_fin ; C = 1 c'est-à-dire (tampon)<= .9
;(tampon) > .9
movlw B'11110000' ; masque
andwf minutes0,f
goto etape_fin
etape_fin
call affichageLCDdateheure
etape_fin_fin
goto debut_programme
END