Vous êtes sur la page 1sur 19

16f84

; "Compteur 4 digits"
; (C) Fabrice Sincère, février 2007
; IUT Nancy-Brabois
; version 1.06
; microcontrôleur PIC 16F84A
; développé avec Microchip MPLAB IDE

List p=16F84A ; processeur utilisé


#include <p16F84A.inc>

__config _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC


;bits de configuration :
;code protect OFF
;watchdog timer OFF
;power up timer ON
;oscillateur HS (quartz 20 MHz)

;xxxxxx
; macro
;xxxxxx

bank1 macro ; passage en banque 1


bsf STATUS,RP0
endm

bank0 macro ; passage en banque 0


bcf STATUS,RP0
endm

;xxxxxxxxxxxxxxxxxxxxxxxxx
; déclaration de variables
;xxxxxxxxxxxxxxxxxxxxxxxxx

CBLOCK H'00C' ; début de la zone des registres d'usage


général du 16F84A

digit : 1 ; variable qui indique n° de


l'afficheur actif (1 à 4)
STATUS_TEMP : 1 ; sauvegarde du registre STATUS (routine
d'interruption)
W_TEMP : 1 ; sauvegarde du registre W
(routine d'interruption)
afficheur_4 : 1 ; contient le chiffre des unités à afficher
(codage BCD)
afficheur_3 : 1 ; contient le chiffre des dizaines à afficher
(codage BCD)
afficheur_2 : 1 ; contient le chiffre des centaines à
afficher (codage BCD)
afficheur_1 : 1 ; contient le chiffre des milliers à afficher
(codage BCD)
afficheur : 1 ; contient le chiffre actif à afficher
(codage BCD)
compt_BPplus : 1 ; variable de la temporisation anti-rebonds
du BP "PLUS"
compt_BPmoins : 1 ; variable de la temporisation anti-rebonds
du BP "MOINS"
flag_BPmoins :1 ; drapeau mis à 1 lors d'un front montant sur
le BP "MOINS"
; (on utilise le bit 0)
flag_tempoBPmoins : 1 ; drapeau mis à 1 lors du debut de la
temporisation
; anti-rebonds du BP
"MOINS" (on utilise le bit 0)
BPmoins_bak ; niveau antérieur sur le BP "MOINS"
(on utilise le bit 0)

ENDC

;xxxxxxxxxxxxxxxxxxxx
; démarrage sur reset
;xxxxxxxxxxxxxxxxxxxx

org H'0000'
goto initialisation

; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine d'interruption
; 2 source d'interruption
; - RB0/INT sur front montant
; - TMR0 en mode timer
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

org H'0004' ; vecteur d'interruption

movwf W_TEMP
swapf STATUS,W
movwf STATUS_TEMP ; sauvegarde du registre W puis du
registre STATUS

btfss INTCON,INTE
goto suite0 ; on vérifie que
l'interruption RB0/INT est autorisée
; (car cette
interruption est désactivée pendant la temporisation
; de l'anti-rebonds)
btfsc INTCON,INTF
goto inter1 ; si oui : on teste le
drapeau de l'interruption RB0/INT
suite0
btfsc INTCON,T0IF
goto inter2 ; on teste s'il s'agit bien
d'une interruption TMR0

goto restauration ; (par précaution)

; xxxxxxxxxxxxxxxxxxxxxxxxxxxx
; gestion interruption RB0/INT
; xxxxxxxxxxxxxxxxxxxxxxxxxxxx
inter1

; Antirebonds
; L'interruption RB0/INT est désactivée pendant 60*3,3 ms # 200 ms

movlw D'60'
movwf compt_BPplus

call conversion_plus

bcf INTCON,INTE ; on désactive l'interruption RB0/INT


bcf INTCON,INTF ; on efface le drapeau RB0/INT
goto restauration

; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; gestion de l'interruption TMR0
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
inter2
; Cette interruption a lieu toutes les :
; 0,2 µs*256*64 (prescaler) = 3,3 ms

call tempo_BPplus

; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Rafraîchissement de l'affichage
; Les 4 afficheurs sont multiplixés
; On active les afficheurs les uns après les autres (un toutes les 4 ms)

decf digit, f ; on change d'afficheur 4->3->2->1->4-> etc


btfss STATUS, Z
goto suite
movlw D'4'
movwf digit
suite

; on alimente l'afficheur correspondant


movlw D'1'
subwf digit, W
btfss STATUS, Z
goto digit2 ; (digit) différent de 1
movlw B'00011100'
movwf PORTA ; RA1=1 : afficheur1 alimenté
movf afficheur_1, W
movwf afficheur ; on charge (afficheur_1) dans (afficheur)
goto fin

digit2

movlw D'2'
subwf digit, W
btfss STATUS, Z
goto digit3 ; (digit) différent de 2
movlw B'00011010'
movwf PORTA ; RA2=1 : afficheur2 alimenté
movf afficheur_2, W
movwf afficheur ; on charge (afficheur_2) dans (afficheur)
goto fin

digit3

movlw D'3'
subwf digit, W
btfss STATUS, Z
goto digit4 ; (digit) différent de 3
movlw B'00010110'
movwf PORTA ; RA3=1 : afficheur3 alimenté
movf afficheur_3, W
movwf afficheur ; on charge (afficheur_3) dans (afficheur)
goto fin

digit4
movlw D'4'
subwf digit, W
btfss STATUS, Z
goto fin ; (digit) différent de 4
movlw B'00001110'
movwf PORTA ; RA4=1 : afficheur4 alimenté
movf afficheur_4, W
movwf afficheur ; on charge (afficheur_4) dans (afficheur)
goto fin

fin

call conversion7

; test du bouton poussoir "MOINS"


call moins

bcf INTCON,T0IF ; on efface le drapeau T0IF


goto restauration

restauration

swapf STATUS_TEMP,W ; restauration des registres STATUS


puis W
movwf STATUS
swapf W_TEMP,f
swapf W_TEMP,W

retfie ; retour d'interruption

; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine "tempo_BPplus"
; temporisation anti-rebonds 200 ms (bouton poussoir "PLUS")
tempo_BPplus

btfsc INTCON,INTE
return ; INTE = 1
decf compt_BPplus,f ; INTE = 0
btfss STATUS, Z
return ; compt_BPplus < > 0
; compt_BPplus = 0 : fin de la temporisation
bsf INTCON,INTE ; on réautorise l'interruption
RB0/INT
bcf INTCON,INTF ; on efface le drapeau RB0/INT
return

;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine de gestion de l'interrupteur "MOINS"
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; quand on appuie sur ce bouton (sur front montant), on décrémente le
compteur.
; la durée de la temporisation pour l'anti-rebonds est 60*3,3 ms # 200 ms

moins
; test front montant
btfss PORTB,1
goto suit2 ; BP "MOINS" au niveau bas
btfsc BPmoins_bak,0 ; BP "MOINS" au niveau haut
goto suit2 ; BP "MOINS" au niveau haut (3,3 ms
avant)
bsf flag_BPmoins,0 ; drapeau mis à 1
suit2
bcf BPmoins_bak,0
btfsc PORTB,1
bsf BPmoins_bak,0 ; mémorisation du niveau du BP "MOINS"

; test du drapeau de début de tempo


btfss flag_tempoBPmoins,0
goto suit3
; drapeau tempo à 1
decf compt_BPmoins,f
btfsc STATUS,Z ; on teste si (compt_BPmoins) est nul
goto suit4
return ; (compt_BPmoins) est non nul
suit4
; (compt_BPmoins) est nul
; fin de temporisation
bcf flag_tempoBPmoins,0 ; drapeau remis à 0
bcf flag_BPmoins,0 ; drapeau remis à 0
return

suit3
; drapeau tempo à 0
; test du drapeau front montant
btfss flag_BPmoins,0
return ; drapeau front montant à 0
; drapeau front montant à 1
; début temporisation
bsf flag_tempoBPmoins,0 ; drapeau mis à 1
movlw D'60'
movwf compt_BPmoins
call conversion_moins ; mise à jour affichage
return

;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine "conversion_plus"
; Incrémentation du compteur (codage BCD)
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

conversion_plus

incf afficheur_4,f
; on teste si (afficheur_4)=D'10'
movlw D'10'
subwf afficheur_4,W
btfss STATUS,Z
return ; (afficheur_4) différent (inférieur à) de D'10'
; (afficheur_4) égal à D'10'
clrf afficheur_4
incf afficheur_3,f
; on teste si (afficheur_3)=D'10'
movlw D'10'
subwf afficheur_3,W
btfss STATUS,Z
return ; (afficheur_3) différent de D'10'
; (afficheur_3) égal à D'10'
clrf afficheur_3
incf afficheur_2,f
; on teste si (afficheur_2)=D'10'
movlw D'10'
subwf afficheur_2,W
btfss STATUS,Z
return ; (afficheur_2) différent de D'10'
; (afficheur_2) égal à D'10'
clrf afficheur_2
incf afficheur_1,f
; on teste si (afficheur_1)=D'10'
movlw D'10'
subwf afficheur_1,W
btfss STATUS,Z
return ; (afficheur_1) différent de D'10'
clrf afficheur_1
return

;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine "conversion_moins"
; décrémentation du compteur (codage BCD)
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

conversion_moins

decf afficheur_4,f
; on teste si (afficheur_4)=D'255'
movlw D'255'
subwf afficheur_4,W
btfss STATUS,Z
return ; (afficheur_4) différent de D'255'
; (afficheur_4) égal à D'255'
movlw D'9'
movwf afficheur_4
decf afficheur_3,f
; on teste si (afficheur_3)=D'255'
movlw D'255'
subwf afficheur_3,W
btfss STATUS,Z
return ; (afficheur_3) différent de D'255'
; (afficheur_3) égal à D'255'
movlw D'9'
movwf afficheur_3
decf afficheur_2,f
; on teste si (afficheur_2)=D'255'
movlw D'255'
subwf afficheur_2,W
btfss STATUS,Z
return ; (afficheur_2) différent de D'255'
; (afficheur_2) égal à D'10'
movlw D'9'
movwf afficheur_2
decf afficheur_1,f
; on teste si (afficheur_1)=D'255'
movlw D'255'
subwf afficheur_1,W
btfss STATUS,Z
return ; (afficheur_1) différent de D'255'
movlw D'9'
movwf afficheur_1
return

;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine de conversion BCD -> 7 segments
; et commande de l'afficheur actif
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

conversion7

movlw D'0'
subwf afficheur, W
btfss STATUS, Z
goto valeur1 ; (afficheur) différent de 0
movlw B'00000000'
movwf PORTB
bsf PORTA,0 ; on affiche 0
return

valeur1
movlw D'1'
subwf afficheur, W
btfss STATUS, Z
goto valeur2 ; (afficheur) différent de 1
movlw B'11100100'
movwf PORTB
bsf PORTA,0 ; on affiche 1
return

valeur2
movlw D'2'
subwf afficheur, W
btfss STATUS, Z
goto valeur3 ; (afficheur) différent de 2
movlw B'10010000'
movwf PORTB
bcf PORTA,0 ; on affiche 2
return

valeur3
movlw D'3'
subwf afficheur, W
btfss STATUS, Z
goto valeur4 ; (afficheur) différent de 3
movlw B'11000000'
movwf PORTB
bcf PORTA,0 ; on affiche 3
return

valeur4
movlw D'4'
subwf afficheur, W
btfss STATUS, Z
goto valeur5 ; (afficheur) différent de 4
movlw B'01100100'
movwf PORTB
bcf PORTA,0 ; on affiche 4
return

valeur5
movlw D'5'
subwf afficheur, W
btfss STATUS, Z
goto valeur6 ; (afficheur) différent de 5
movlw B'01001000'
movwf PORTB
bcf PORTA,0 ; on affiche 5
return

valeur6
movlw D'6'
subwf afficheur, W
btfss STATUS, Z
goto valeur7 ; (afficheur) différent de 6
movlw B'00001100'
movwf PORTB
bcf PORTA,0 ; on affiche 6
return

valeur7
movlw D'7'
subwf afficheur, W
btfss STATUS, Z
goto valeur8 ; (afficheur) différent de 7
movlw B'11100000'
movwf PORTB
bsf PORTA,0 ; on affiche 7
return

valeur8
movlw D'8'
subwf afficheur, W
btfss STATUS, Z
goto valeur9 ; (afficheur) différent de 8
movlw B'00000000'
movwf PORTB
bcf PORTA,0 ; on affiche 8
return

valeur9
movlw D'9'
subwf afficheur, W
btfss STATUS, Z
return ; (par précaution)
movlw B'01100000'
movwf PORTB
bcf PORTA,0 ; on affiche 9
return

;xxxxxxxxxxxxxxx
; initialisation
;xxxxxxxxxxxxxxx

initialisation

bank0
clrf PORTA ; mise à 0 des sorties du port A
clrf PORTB ; mise à 0 des sorties du port B

bank1
movlw B'01000101'
movwf OPTION_REG
; bit 7 (/RBPU) = 0 : activation des résistances de pull-up du port
B
; bit 6 (INTEDG)= 1 : interruption RB0/INT sur front montant
; bit 5 (T0CS) = 0 : Timer0 Clock Source Select = CLKOUT
; bit 3 (PSA) = 0 : Prescaler attribué au module TMR0
; bit 2 (PS2)= 1
; bit 1 (PS1) = 0
; bit 0 (PS0) = 1 : Facteur de division du prescaler = 1:64
; bit 4 : ici, option non utilisée (= 0, par exemple)

movlw B'00000000'
movwf TRISA
; bit 0 du port A (RA0) = 0 : configuration en sortie (segment G)
; bit 1 du port A (RA1) = 0 : configuration en sortie (afficheur
1 : chiffre des milliers)
; bit 2 du port A (RA2) = 0 : configuration en sortie (afficheur
2 : chiffre des centaines)
; bit 3 du port A (RA3) = 0 : configuration en sortie (afficheur
3 : chiffre des dizaines)
; bit 4 du port A (RA4) = 0 : configuration en sortie (afficheur
4 : chiffre des unités)

movlw B'00000011'
movwf TRISB
; bit 0 du port B (RB0) = 1 : configuration en entrée (bouton
poussoir PLUS)
; bit 1 du port B (RB1) = 1 : configuration en entrée (bouton
poussoir MOINS)
; bit 2 du port B (RB2) = 0 : configuration en sortie (segment A)
; bit 3 du port B (RB3) = 0 : configuration en sortie (segment B)
; bit 4 du port B (RB4) = 0 : configuration en sortie (segment C)
; bit 5 du port B (RB5) = 0 : configuration en sortie (segment D)
; bit 6 du port B (RB6) = 0 : configuration en sortie (segment E)
; bit 7 du port B (RB7) = 0 : configuration en sortie (segment F)

; affichage possible de 0000 à 9999

bank0
movlw B'10110000'
movwf INTCON
; bit 7 (GIE) = 1 : autorisation globale des interruptions
; bit 5 (T0IE) = 1 : autorisation de l'interruption TMR0
; bit 4 (INTE) = 1 : autorisation de l'interruption RB0/INT (bouton
poussoir PLUS)
; bit 2 (T0IF)= 0 : on efface le drapeau de l'interruption TMR0
; bit 1 (INTF)= 0 : on efface le drapeau de l'interruption RB0/INT
; les autres bits sont inutilisés (valeur par défaut = 0)

clrf PORTA ; sorties du port A au niveau bas


; les afficheurs sont donc éteints

clrf TMR0 ; mise à zero du timer0


clrf afficheur_1
clrf afficheur_2
clrf afficheur_3
clrf afficheur_4
clrf afficheur
movlw D'4'
movwf digit
movlw D'60'
movwf compt_BPplus
movwf compt_BPmoins
clrf flag_BPmoins
clrf flag_tempoBPmoins
bsf BPmoins_bak,0
goto debut_programme

;xxxxxxxxxxxxxxxxxxxxx
; programme principal
;xxxxxxxxxxxxxxxxxxxxx

debut_programme

; on attend le débordement de TMR0 (H'FF' -> H'00')


; ou un front montant
sur l'entrée RB0/INT,
; ce qui génére une
interruption
goto debut_programme

END

16f628
; "Compteur 4 digits"
; (C) Fabrice Sincère, février 2007
; IUT Nancy-Brabois
; version 1.06
; microcontrôleur PIC 16F628A
; développé avec Microchip MPLAB IDE

List p=16F628A ; processeur utilisé


#include <p16F628A.inc>

__config _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC & _LVP_OFF &
_DATA_CP_OFF & _BOREN_OFF & _MCLRE_ON
;bits de configuration :
;code protect OFF
;watchdog timer OFF
;power up timer ON
;oscillateur HS (quartz 20 MHz)
;low voltage program OFF
;data EE read protect OFF
;brown out detect OFF
;master clear enable ON

;xxxxxx
; macro
;xxxxxx

bank1 macro ; passage en banque 1


bsf STATUS,RP0
bcf STATUS,RP1
endm

bank0 macro ; passage en banque 0


bcf STATUS,RP0
bcf STATUS,RP1
endm

;xxxxxxxxxxxxxxxxxxxxxxxxx
; déclaration de variables
;xxxxxxxxxxxxxxxxxxxxxxxxx
CBLOCK H'020' ; début de la zone des registres d'usage général du
16F628A

digit : 1 ; variable qui indique n° de


l'afficheur actif (1 à 4)
STATUS_TEMP : 1 ; sauvegarde du registre STATUS (routine
d'interruption)
W_TEMP : 1 ; sauvegarde du registre W
(routine d'interruption)
afficheur_4 : 1 ; contient le chiffre des unités à afficher
(codage BCD)
afficheur_3 : 1 ; contient le chiffre des dizaines à afficher
(codage BCD)
afficheur_2 : 1 ; contient le chiffre des centaines à
afficher (codage BCD)
afficheur_1 : 1 ; contient le chiffre des milliers à afficher
(codage BCD)
afficheur : 1 ; contient le chiffre actif à afficher
(codage BCD)
compt_BPplus : 1 ; variable de la temporisation anti-rebonds
du BP "PLUS"
compt_BPmoins : 1 ; variable de la temporisation anti-rebonds
du BP "MOINS"
flag_BPmoins :1 ; drapeau mis à 1 lors d'un front montant sur
le BP "MOINS"
; (on utilise le bit 0)
flag_tempoBPmoins : 1 ; drapeau mis à 1 lors du debut de la
temporisation
; anti-rebonds du BP
"MOINS" (on utilise le bit 0)
BPmoins_bak ; niveau antérieur sur le BP "MOINS"
(on utilise le bit 0)

ENDC

;xxxxxxxxxxxxxxxxxxxx
; démarrage sur reset
;xxxxxxxxxxxxxxxxxxxx

org H'0000'
goto initialisation

; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine d'interruption
; 2 source d'interruption
; - RB0/INT sur front montant
; - TMR0 en mode timer
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

org H'0004' ; vecteur d'interruption

movwf W_TEMP
swapf STATUS,W
movwf STATUS_TEMP ; sauvegarde du registre W puis du
registre STATUS

btfss INTCON,INTE
goto suite0 ; on vérifie que
l'interruption RB0/INT est autorisée
; (car cette
interruption est désactivée pendant la temporisation
; de l'anti-rebonds)
btfsc INTCON,INTF
goto inter1 ; si oui : on teste le
drapeau de l'interruption RB0/INT
suite0
btfsc INTCON,T0IF
goto inter2 ; on teste s'il s'agit bien
d'une interruption TMR0

goto restauration ; (par précaution)

; xxxxxxxxxxxxxxxxxxxxxxxxxxxx
; gestion interruption RB0/INT
; xxxxxxxxxxxxxxxxxxxxxxxxxxxx
inter1

; Antirebonds
; L'interruption RB0/INT est désactivée pendant 60*3,3 ms # 200 ms

movlw D'60'
movwf compt_BPplus

call conversion_plus

bcf INTCON,INTE ; on désactive l'interruption RB0/INT


bcf INTCON,INTF ; on efface le drapeau RB0/INT

goto restauration

; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; gestion de l'interruption TMR0
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
inter2
; Cette interruption a lieu toutes les :
; 0,2 µs*256*64 (prescaler) = 3,3 ms

call tempo_BPplus

; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Rafraîchissement de l'affichage
; Les 4 afficheurs sont multiplixés
; On active les afficheurs les uns après les autres (un toutes les 4 ms)

decf digit, f ; on change d'afficheur 4->3->2->1->4-> etc


btfss STATUS, Z
goto suite
movlw D'4'
movwf digit
suite

; on alimente l'afficheur correspondant


movlw D'1'
subwf digit, W
btfss STATUS, Z
goto digit2 ; (digit) différent de 1
movlw B'00011100'
movwf PORTA ; RA1=1 : afficheur1 alimenté
movf afficheur_1, W
movwf afficheur ; on charge (afficheur_1) dans (afficheur)
goto fin
digit2

movlw D'2'
subwf digit, W
btfss STATUS, Z
goto digit3 ; (digit) différent de 2
movlw B'00011010'
movwf PORTA ; RA2=1 : afficheur2 alimenté
movf afficheur_2, W
movwf afficheur ; on charge (afficheur_2) dans (afficheur)
goto fin

digit3

movlw D'3'
subwf digit, W
btfss STATUS, Z
goto digit4 ; (digit) différent de 3
movlw B'00010110'
movwf PORTA ; RA3=1 : afficheur3 alimenté
movf afficheur_3, W
movwf afficheur ; on charge (afficheur_3) dans (afficheur)
goto fin

digit4

movlw D'4'
subwf digit, W
btfss STATUS, Z
goto fin ; (digit) différent de 4
movlw B'00001110'
movwf PORTA ; RA4=1 : afficheur4 alimenté
movf afficheur_4, W
movwf afficheur ; on charge (afficheur_4) dans (afficheur)
goto fin

fin

call conversion7

; test du bouton poussoir "MOINS"


call moins

bcf INTCON,T0IF ; on efface le drapeau T0IF


goto restauration

restauration

swapf STATUS_TEMP,W ; restauration des registres STATUS


puis W
movwf STATUS
swapf W_TEMP,f
swapf W_TEMP,W

retfie ; retour d'interruption

; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine "tempo_BPplus"
; temporisation anti-rebonds 200 ms (bouton poussoir "PLUS")
tempo_BPplus
btfsc INTCON,INTE
return ; INTE = 1
decf compt_BPplus,f ; INTE = 0
btfss STATUS, Z
return ; compt_BPplus < > 0
; compt_BPplus = 0 : fin de la temporisation
bsf INTCON,INTE ; on réautorise l'interruption
RB0/INT
bcf INTCON,INTF ; on efface le drapeau RB0/INT
return

;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine de gestion de l'interrupteur "MOINS"
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; quand on appuie sur ce bouton (sur front montant), on décrémente le
compteur.
; la durée de la temporisation pour l'anti-rebonds est 60*3,3 ms # 200 ms

moins
; test front montant
btfss PORTB,1
goto suit2 ; BP "MOINS" au niveau bas
btfsc BPmoins_bak,0 ; BP "MOINS" au niveau haut
goto suit2 ; BP "MOINS" au niveau haut (3,3 ms
avant)
bsf flag_BPmoins,0 ; drapeau mis à 1
suit2
bcf BPmoins_bak,0
btfsc PORTB,1
bsf BPmoins_bak,0 ; mémorisation du niveau du BP "MOINS"

; test du drapeau de début de tempo


btfss flag_tempoBPmoins,0
goto suit3
; drapeau tempo à 1
decf compt_BPmoins,f
btfsc STATUS,Z ; on teste si (compt_BPmoins) est nul
goto suit4
return ; (compt_BPmoins) est non nul
suit4
; (compt_BPmoins) est nul
; fin de temporisation
bcf flag_tempoBPmoins,0 ; drapeau remis à 0
bcf flag_BPmoins,0 ; drapeau remis à 0
return

suit3
; drapeau tempo à 0
; test du drapeau front montant
btfss flag_BPmoins,0
return ; drapeau front montant à 0
; drapeau front montant à 1
; début temporisation
bsf flag_tempoBPmoins,0 ; drapeau mis à 1
movlw D'60'
movwf compt_BPmoins
call conversion_moins ; mise à jour affichage
return

;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine "conversion_plus"
; Incrémentation du compteur (codage BCD)
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

conversion_plus

incf afficheur_4,f
; on teste si (afficheur_4)=D'10'
movlw D'10'
subwf afficheur_4,W
btfss STATUS,Z
return ; (afficheur_4) différent (inférieur à) de D'10'
; (afficheur_4) égal à D'10'
clrf afficheur_4
incf afficheur_3,f
; on teste si (afficheur_3)=D'10'
movlw D'10'
subwf afficheur_3,W
btfss STATUS,Z
return ; (afficheur_3) différent de D'10'
; (afficheur_3) égal à D'10'
clrf afficheur_3
incf afficheur_2,f
; on teste si (afficheur_2)=D'10'
movlw D'10'
subwf afficheur_2,W
btfss STATUS,Z
return ; (afficheur_2) différent de D'10'
; (afficheur_2) égal à D'10'
clrf afficheur_2
incf afficheur_1,f
; on teste si (afficheur_1)=D'10'
movlw D'10'
subwf afficheur_1,W
btfss STATUS,Z
return ; (afficheur_1) différent de D'10'
clrf afficheur_1
return

;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine "conversion_moins"
; décrémentation du compteur (codage BCD)
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

conversion_moins

decf afficheur_4,f
; on teste si (afficheur_4)=D'255'
movlw D'255'
subwf afficheur_4,W
btfss STATUS,Z
return ; (afficheur_4) différent de D'255'
; (afficheur_4) égal à D'255'
movlw D'9'
movwf afficheur_4
decf afficheur_3,f
; on teste si (afficheur_3)=D'255'
movlw D'255'
subwf afficheur_3,W
btfss STATUS,Z
return ; (afficheur_3) différent de D'255'
; (afficheur_3) égal à D'255'
movlw D'9'
movwf afficheur_3
decf afficheur_2,f
; on teste si (afficheur_2)=D'255'
movlw D'255'
subwf afficheur_2,W
btfss STATUS,Z
return ; (afficheur_2) différent de D'255'
; (afficheur_3) égal à D'10'
movlw D'9'
movwf afficheur_2
decf afficheur_1,f
; on teste si (afficheur_1)=D'255'
movlw D'255'
subwf afficheur_1,W
btfss STATUS,Z
return ; (afficheur_1) différent de D'255'
movlw D'9'
movwf afficheur_1
return

;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; Routine de conversion BCD -> 7 segments
; et commande de l'afficheur actif
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

conversion7

movlw D'0'
subwf afficheur, W
btfss STATUS, Z
goto valeur1 ; (afficheur) différent de 0
movlw B'00000000'
movwf PORTB
bsf PORTA,0 ; on affiche 0
return

valeur1
movlw D'1'
subwf afficheur, W
btfss STATUS, Z
goto valeur2 ; (afficheur) différent de 1
movlw B'11100100'
movwf PORTB
bsf PORTA,0 ; on affiche 1
return

valeur2
movlw D'2'
subwf afficheur, W
btfss STATUS, Z
goto valeur3 ; (afficheur) différent de 2
movlw B'10010000'
movwf PORTB
bcf PORTA,0 ; on affiche 2
return

valeur3
movlw D'3'
subwf afficheur, W
btfss STATUS, Z
goto valeur4 ; (afficheur) différent de 3
movlw B'11000000'
movwf PORTB
bcf PORTA,0 ; on affiche 3
return

valeur4
movlw D'4'
subwf afficheur, W
btfss STATUS, Z
goto valeur5 ; (afficheur) différent de 4
movlw B'01100100'
movwf PORTB
bcf PORTA,0 ; on affiche 4
return

valeur5
movlw D'5'
subwf afficheur, W
btfss STATUS, Z
goto valeur6 ; (afficheur) différent de 5
movlw B'01001000'
movwf PORTB
bcf PORTA,0 ; on affiche 5
return

valeur6
movlw D'6'
subwf afficheur, W
btfss STATUS, Z
goto valeur7 ; (afficheur) différent de 6
movlw B'00001100'
movwf PORTB
bcf PORTA,0 ; on affiche 6
return

valeur7
movlw D'7'
subwf afficheur, W
btfss STATUS, Z
goto valeur8 ; (afficheur) différent de 7
movlw B'11100000'
movwf PORTB
bsf PORTA,0 ; on affiche 7
return

valeur8
movlw D'8'
subwf afficheur, W
btfss STATUS, Z
goto valeur9 ; (afficheur) différent de 8
movlw B'00000000'
movwf PORTB
bcf PORTA,0 ; on affiche 8
return

valeur9
movlw D'9'
subwf afficheur, W
btfss STATUS, Z
return ; (par précaution)
movlw B'01100000'
movwf PORTB
bcf PORTA,0 ; on affiche 9
return

;xxxxxxxxxxxxxxx
; initialisation
;xxxxxxxxxxxxxxx

initialisation

bank0
clrf PORTA ; mise à 0 des sorties du port A
clrf PORTB ; mise à 0 des sorties du port B

movlw B'00000111'
movwf CMCON ; inactivation des comparateurs
analogiques

bank1
movlw B'01000101'
movwf OPTION_REG
; bit 7 (/RBPU) = 0 : activation des résistances de pull-up du port
B
; bit 6 (INTEDG)= 1 : interruption RB0/INT sur front montant
; bit 5 (T0CS) = 0 : Timer0 Clock Source Select = CLKOUT
; bit 3 (PSA) = 0 : Prescaler attribué au module TMR0
; bit 2 (PS2)= 1
; bit 1 (PS1) = 0
; bit 0 (PS0) = 1 : Facteur de division du prescaler = 1:64
; bit 4 : ici, option non utilisée (= 0, par exemple)

movlw B'00000000'
movwf TRISA
; bit 0 du port A (RA0) = 0 : configuration en sortie (segment G)
; bit 1 du port A (RA1) = 0 : configuration en sortie (afficheur
1 : chiffre des milliers)
; bit 2 du port A (RA2) = 0 : configuration en sortie (afficheur
2 : chiffre des centaines)
; bit 3 du port A (RA3) = 0 : configuration en sortie (afficheur
3 : chiffre des dizaines)
; bit 4 du port A (RA4) = 0 : configuration en sortie (afficheur
4 : chiffre des unités)

movlw B'00000011'
movwf TRISB
; bit 0 du port B (RB0) = 1 : configuration en entrée (bouton
poussoir PLUS)
; bit 1 du port B (RB1) = 1 : configuration en entrée (bouton
poussoir MOINS)
; bit 2 du port B (RB2) = 0 : configuration en sortie (segment A)
; bit 3 du port B (RB3) = 0 : configuration en sortie (segment B)
; bit 4 du port B (RB4) = 0 : configuration en sortie (segment C)
; bit 5 du port B (RB5) = 0 : configuration en sortie (segment D)
; bit 6 du port B (RB6) = 0 : configuration en sortie (segment E)
; bit 7 du port B (RB7) = 0 : configuration en sortie (segment F)
; affichage possible de 0000 à 9999

bank0
movlw B'10110000'
movwf INTCON
; bit 7 (GIE) = 1 : autorisation globale des interruptions
; bit 5 (T0IE) = 1 : autorisation de l'interruption TMR0
; bit 4 (INTE) = 1 : autorisation de l'interruption RB0/INT (bouton
poussoir PLUS)
; bit 2 (T0IF)= 0 : on efface le drapeau de l'interruption TMR0
; bit 1 (INTF)= 0 : on efface le drapeau de l'interruption RB0/INT
; les autres bits sont inutilisés (valeur par défaut = 0)

clrf PORTA ; sorties du port A au niveau bas


; les afficheurs sont donc éteints

clrf TMR0 ; mise à zero du timer0


clrf afficheur_1
clrf afficheur_2
clrf afficheur_3
clrf afficheur_4
clrf afficheur
movlw D'4'
movwf digit
movlw D'60'
movwf compt_BPplus
movwf compt_BPmoins
clrf flag_BPmoins
clrf flag_tempoBPmoins
bsf BPmoins_bak,0

goto debut_programme

;xxxxxxxxxxxxxxxxxxxxx
; programme principal
;xxxxxxxxxxxxxxxxxxxxx

debut_programme

; on attend le débordement de TMR0 (H'FF' -> H'00')


; ou un front montant
sur l'entrée RB0/INT,
; ce qui génére une
interruption
goto debut_programme

END

Vous aimerez peut-être aussi