Schema pour réaliser un Compteur Horaire

A quoi sert le montage?:
Il sert à totaliser le nombre d'heures de fonctionnement d'une machine dans le but de gérer les opérations de maintenance (par exemple:vidange, nettoyage, ...).


Le fonctionnement:
Le comptage va de "0000.0" à "9999.9" heures. Dès la mise sous tension, le comptage se déclenche. Pour garder en mémoire la durée écoée, on procède à un enregistrement toutes les 2 minutes. Par conséquent, lorsque le montage n'est pas alimenté, le comptage est arreté sur la dernière valeur enregistrée. Pour rectifiée l'erreur due à la mise en marche (et à l'arret), on donne une minute d'avance à chaque démarrage du comptage. (Cette minute sera compensée à l'arret.)
Description:
L'alimentation typique est de 12V (régée ensuite à 5V), la consommation est de l'ordre de 100 mA. Le coeur du montage est un microcontrôleur PIC16F84. IL gère:< type="circle"> L'affichage du nombre d'heures. L'enregistrement du nombre d'heures. Le cadencement du décompte (quartz 4MHz). Vous pouvez télécharger le schéma du montage en cliquant ici tout en appuyant sur la touche MAJUSCE. Voici le schéma du montage:
schema_compteur_horaire.gif (47936 octets) Les afficheurs sont de type anode commune. Le port A gère le mtiplexage et le port B pilote les segments des cinq afficheurs. La circuiterie de reset est particièrement conçue pour empêcher le PIC de fonctionner en dessous d'une tension trop faible.
Le programme: Le programme est réalisé pour un PIC16F84, il utilise les interruptions internes du PIC. Remarque importante sur le programme:
Le comptage réalisé par le PIC est en fait basé sur un décomptage: il décompte de 10 à 1. Quand un registre atteint la valeur 0, il est aussitôt réinitialisé à 10.
Pour faire apparaitre un comptage au lieu d'un décomptage, on utilise le sous programme "affiche" qui renvoi un 0 pour un 10, un 1 pour un 9, un 2 pour un 8, un 3 pour un 7, un 4 pour un 6, un 5 pour un 5, un 6 pour un 4, un 7 pour un 3, un 8 pour un et un 9 pour un 1.
On obtient bien un comptage de 0 à 9 pour chaque registre. Voici le fonctionnement de la partie enregistrement sous forme de GRAFCET:

grafcet_compteur_horaire.gif (75499 octets)

A première vue, le PIC doit juste compter en enregistrant le temps actuel dans sa memoire EEPROM. Il n'y aurait aucun problème si le protocole d'enregistrement n'éxigeait pas que l'on arrête les interruptions. Il est donc indispensable de stopper les interruptions internes à chaque enregistrement. Comme se sont les interruptions qui gèrent le comptage, on se trouve obligé de faire un compromis entre fréquence d'enregistrement et précision de l'horloge.
La précision totale du système dépend donc de nos choix: plus on enregistre souvent, plus la précision est bonne pour les transitions "marche-arrêt" et plus elle est mauvaise pour l'horloge du comptage elle même. Après réflexion, j'ai choisi d'enregistrer toutes les deux minutes.
Concrêtement, le PIC compte normalement pendant deux minutes au bout desquelles il s'arrête, enregistre et recommence à compter. On constate alors qu'il suffit de connaître le temps d'enregistrement et le tour est joué... On se reporte aussitôt à la fiche technique qui nous indique le temps typique d'enregistrement mais malheureusement ce temps peut fluctuer.
Revenons au programme en nous référant au GRAFCET ci-contre.
Tout d'abord, définissons les notations utilisées. Pour les étapes, les noms sont assez explicites; P1 et P2 correspondent aux parties de mémoire EEPROM utilisées par le PIC. Pour les transitions, "=1" signifie que la transition est validée, "test" est l'indicateur d'enregistrement, OK signifie que l'on attend que le transfert soit effectué et T est la temporisation de deux minutes.
Au démarrage, le PIC doit aller chercher la dernière valeur enregistrée. Considérons qu'il parvienne sans difficté dans la boucle. Lorsque T est valide (=1), on enregistre 0 dans test pour indiquer que l'on est en cours d'enregistrement dans le cas d'une coupure d'alimentation au moment de l'enregistrement. On enregistre alors P1, on remet test=1 et on enregistre P2.
Examinons le cas du démarrage. On commence par lire le bit test, si il est à 1, c'est que P1 est valable, on lit alors P1 et on transfert P1 dans P2 (au cas ou P2 serait nonvalable). on est alors sûr que P1 et P2 sont tous les deux valables. Si le bit test est à 0, P1 est non valable, on lit P2.
De cette manière, on remarque que même dans le cas le plus défavorable il reste toujours un emplacement valable (P1 ou P2). On note aussi que la première mise en marche du PIC exige que l'on ait déjà programmé les emplacements mémoire correspondant à P1 et P2 sur la valeur "0000,0". Il faut se reporter aux dernières lignes du programme pour voir comment on programme la mémoire EEPROM du PIC. Vous pouvez télécharger le programme compt_heure.ASM en cliquant ici tout en appuyant sur la touche MAJUSCE. Vous pouvez télécharger le fichier éxécutable compt_heure.HEX en cliquant ici tout en appuyant sur la touche MAJUSCE. Voici le programme:
;******************************************************************************************************
;montage compteur d'heure.
;24/09/2000
;programme de compteur d'heure
;
;Auteur: Raphael Bourdon
;******************************************************************************************************

list p=16f84,f=inhx8m ; Type de PIC et format de fichier
__config B'11111111110001' ; pas de protection du code, timer au demarrage,
; pas de chien de garde, oscillateur a quartz.
#include "p16f84.inc" ; Librairie pour le compilateur

;definition des variables
time1 equ H'0C'
time2 equ H'0D'
temp equ H'0E'
afficheur equ H'0F'
savstatus equ H'10'
dizieme equ H'11'
unite equ H'12'
dizaine equ H'13'
centaine equ H'14'
millier equ H'15'
temp1 equ H'16'
time3 equ H'17'
temp2 equ H'18'

;definition des adresses memoires EEPROM
s_test equ D'0' ;s_test indique l'etat de la sauvegarde
s_time3 equ D'1'
s_dizieme equ D'2'
s_unite equ D'3'
s_dizaine equ D'4'
s_centaine equ D'5'
s_millier equ D'6'
ss_time3 equ D'7'
ss_dizieme equ D'8'
ss_unite equ D'9'
ss_dizaine equ D'10'
ss_centaine equ D'11'
ss_millier equ D'12'
org 0
goto debut

;------------------------------------------------------------------------------------------------------
org H'04' ;INTERRUPTION

movwf temp ;sauvegarde de W dans temp
swapf STATUS,0 ;sauvegarde de STATUS
movwf savstatus ;dans savstatus
bcf STATUS,RP0 ;on passe dans la page memoire 0
movlw D'06' ;on initialise TMR0 a 6
movwf TMR0
bcf INTCON,T0IF ;remise a 0 du bit T0IF (il est mis a 1 a chaque interruption)


decfsz time1,1 ;time1 sert de diviseur par 250. On decompte qu'une
goto fininterrupt ;interruption sur 250.
movlw D'250' ;reinitialisation de time a 250.
movwf time1

decfsz time2,1 ;time2 sert de diviseur par 30.
goto fininterrupt ;reinitialisation de time a 30.
movlw D'30'
movwf time2

bsf temp2,0 ;temp2,0 permet l'enregistrement.
decfsz time3,1 ;time3 sert de diviseur par 3. On decompte qu'une
goto fininterrupt ;interruption sur 3.
movlw D'3' ;reinitialisation de time a 3.
movwf time3

decfsz dizieme,1 ;decremente dizieme
goto fininterrupt

movlw H'0A'
movwf dizieme
decfsz unite,1 ;decremente unite
goto fininterrupt

movlw H'0A'
movwf unite
decfsz dizaine,1 ;decremente dizaine
goto fininterrupt

movlw H'0A'
movwf dizaine
decfsz centaine,1 ;decremente centaine
goto fininterrupt

movlw H'0A'
movwf centaine
decfsz millier,1 ;decremente millier
goto fininterrupt

movlw H'0A'
movwf millier

fininterrupt
swapf savstatus,0 ; restauration de STATUS
movwf STATUS
swapf temp,1 ; restauration de W
swapf temp,0
retfie

;------------------------------------------------------------------------------------------------------
debut ; Initialisation

movlw H'01'
movwf PCLATH

movlw D'250' ; initialisation de time1 a 250
movwf time1

movlw D'15' ; initialisation de time2 a 15
movwf time2 ;on donne une minute d'avance au demarrage

movlw D'3' ; initialisation de time3 a 3
movwf time3


clrf afficheur
bsf afficheur,4 ;initialisation de afficheur

clrf temp2

;on initialise les registres sauvegardes dans l'EEPROM

movlw s_test ;lecture de s_test
call lecture
btfss EEDATA,0 ;test sur s_test,0
goto sauvegarde ;si s_test,0 = 1, s_* registres -> * registres

movlw s_time3
call lecture
movwf time3

movlw s_dizieme
call lecture
movwf dizieme

movlw s_unite
call lecture
movwf unite

movlw s_dizaine
call lecture
movwf dizaine

movlw s_centaine
call lecture
movwf centaine

movlw s_millier
call lecture
movwf millier

;enregistrement de secour * registres -> s_* registres
movlw ss_time3
movwf EEADR
movf time3,0
movwf EEDATA
call ecriture

movlw ss_dizieme
movwf EEADR
movf dizieme,0
movwf EEDATA
call ecriture

movlw ss_unite
movwf EEADR
movf unite,0
movwf EEDATA
call ecriture

movlw ss_dizaine
movwf EEADR
movf dizaine,0
movwf EEDATA
call ecriture

movlw ss_centaine
movwf EEADR
movf centaine,0
movwf EEDATA
call ecriture

movlw ss_millier
movwf EEADR
movf millier,0
movwf EEDATA
call ecriture

goto fin_init

sauvegarde ;si s_test = 0, ss_* registres -> * registres
movlw ss_time3
call lecture
movwf time3

movlw ss_dizieme
call lecture
movwf dizieme

movlw ss_unite
call lecture
movwf unite

movlw ss_dizaine
call lecture
movwf dizaine

movlw ss_centaine
call lecture
movwf centaine

movlw ss_millier
call lecture
movwf millier

fin_init


; Configuration de l'interruption et des ports A et B
bsf STATUS,RP0 ; selection de la page memoire n1

movlw B'10000101' ; On configure le prediviseur
movwf OPTION_REG ; interruption toutes les 64 instructions

movlw B'10000000' ;les pattes 0/6 du port
movwf TRISB ;B en sorties

clrf TRISA ; Tout le port A en sortie

bcf STATUS,RP0 ; on repasse dans la page memoire 0

clrf PORTA ; on met le port A a zero
comf PORTA,1

clrf PORTB ; on met le port B a zero

movlw B'10100000' ; on va configurer les interruptions
movwf INTCON

;------------------------------------------------------------------------------------------------------
boucle
bcf STATUS,C ;remise a zero de la retenue
rrf afficheur,1 ;puis on fait tourner le bit de afficheur
movf afficheur,1 ;afficheur-> afficheur
btfsc STATUS,Z ;si afficheur vaut zero
bsf afficheur,4

btfsc afficheur,0 ;si le bit 0 de afficheur vaut 1
movf millier,0 ;on met millier dans W
btfsc afficheur,1 ;si le bit 1 de afficheur vaut 1
movf centaine,0 ;on met centaine dans W
btfsc afficheur,2 ;si le bit 2 de afficheur vaut 1
movf dizaine,0 ;on met dizaine dans W
btfsc afficheur,3 ;si le bit 3 de afficheur vaut 1
movf unite,0 ;on met unite dans W
btfsc afficheur,4 ;si le bit 4 de afficheur vaut 1
movf dizieme,0 ;on met dizieme dans W

call affiche
movwf PORTB

comf afficheur,0 ;on complemente afficheur, on met le restat dans W
movwf PORTA ;W -> portA

call tempo ;la tempo sert a ralentir la vitesse sur les ports A et B

btfss temp2,0 ;on teste l'indicateur d'enregistrement temp2,0
goto boucle ;si temp2,0 = 0 on retourne a boucle
bcf temp2,0 ;temp2,0 = 0

;inserer l'enregistrement a cet endroit
movlw H'FF' ;on coupe l'affichage
movwf PORTA

movlw s_test ;on enregistre 0 dans s_test
movwf EEADR
clrf EEDATA
bcf INTCON,GIE
call ecriture

movlw s_time3 ;* registres -> s_* registres
movwf EEADR
movf time3,0
movwf EEDATA
call ecriture

movlw s_dizieme
movwf EEADR
movf dizieme,0
movwf EEDATA
call ecriture

movlw s_unite
movwf EEADR
movf unite,0
movwf EEDATA
call ecriture

movlw s_dizaine
movwf EEADR
movf dizaine,0
movwf EEDATA
call ecriture

movlw s_centaine
movwf EEADR
movf centaine,0
movwf EEDATA
call ecriture

movlw s_millier
movwf EEADR
movf millier,0
movwf EEDATA
call ecriture

valide
movlw s_test ;on enregistre 1 dans s-test
movwf EEADR
clrf EEDATA
comf EEDATA,1
bcf INTCON,GIE
call ecriture

bsf STATUS,RP0 ;on verifie que s_test = 1
bsf EECON1,RD ;sinon on va a valide
bcf STATUS,RP0
btfss EEDATA,0
goto valide

;enregistrement de secour
movlw ss_time3 ;* registres -> ss_* registres
movwf EEADR
movf time3,0
movwf EEDATA
call ecriture

movlw ss_dizieme
movwf EEADR
movf dizieme,0
movwf EEDATA
call ecriture

movlw ss_unite
movwf EEADR
movf unite,0
movwf EEDATA
call ecriture

movlw ss_dizaine
movwf EEADR
movf dizaine,0
movwf EEDATA
call ecriture

movlw ss_centaine
movwf EEADR
movf centaine,0
movwf EEDATA
call ecriture

movlw ss_millier
movwf EEADR
movf millier,0
movwf EEDATA
call ecriture

movlw D'241' ;compense le retard du a l'enregistrement
movwf time1

comf afficheur,0 ;on remet en marche l'affichage
movwf PORTA
bsf INTCON,GIE ;reactive les interruptions
goto boucle

;------------------------------------------------------------------------------------------------------
;sous-programmes

lecture
movwf EEADR
bsf STATUS,RP0
bsf EECON1,RD
bcf STATUS,RP0
movf EEDATA,W
return

ecriture
bsf STATUS,RP0
clrf EECON1
bsf EECON1,WREN
movlw H'55'
movwf EECON2
movlw H'AA'
movwf EECON2
bsf EECON1,WR
fin_ecriture
btfsc EECON1,WR
goto fin_ecriture
bcf STATUS,RP0
bcf temp2,0
return

tempo
decfsz temp1,1
goto tempo
return

affiche
addwf PCL,1 ;on charge le registre PCL par la
nop ;valeur qu'il contient plus la valeur

retlw b'01101111'
retlw b'01111111' ;de W
retlw b'00000111' ;On se deplace ainsi a l'adresse:
retlw b'01111101' ;adresse de 'addwf PCL,1' + W
retlw b'01101101' ;il faut intercaler une instruction nop
retlw b'01100110' ;car W varie de 0 à 9 Enfin, on
retlw b'01001111' ;retourne dans W la valeur a afficher
retlw b'01011011'
retlw b'00000110'
retlw b'00111111'

;definition des contenus des registres de sauvegarde pour initialiser l'EEPROM a la premiere
;utilisation du montage
;le comptage demarre ainsi a "0000,0" apres la programmation du PIC
org H'2100'
de H'FF',H'03',H'0A',H'0A',H'0A',H'0A',H'0A',H'03',H'0A',H'0A',H'0A',H'0A',H'0A'

end
Realisation:


typon_compteur_horaire.gif (34191 octets)

Voici l'implantation des composants et le typon du circuit :
Il faut cabler les deux circuits imprimés perpendicairement. C'est à cause du manque de place que les résistances ne sont pas sur le circuit mais soudées entre les deux parties. Pour établir les autres contacts entre les deux circuits vous devez souder des queues de résistances. Le montage est prévu pour un boitier TEKO metallique de 40x40x70 (constitué de deux parties vissées).
Les afficheurs sont des HDSP-F101 (Hewlett Packard), on peut les remplacer par des afficheurs ayant des caractéristiques équivalentes: même boitier, courant nominal de 5mA et anode commune.
Voici des photos de la réalisation:

Le montage vu de dessus:
photo_compteur_heure2.jpg (20568 octets)
Le compteur en marche:

photo_compteur_heure1.jpg (19295 octets)





  • Vous devez telecharger le typon en cliquant ici tout en appuyant sur la touche MAJUSCE.
    Je rappelle qu'il faut telecharger le logiciel ARES Lite qui est gratuit. Il est disponible sur le site suivant: http://www.mtipower-fr.com
    ~ Ouvrez le logiciel ARES Lite
    ~ Cliquez sur File, puis sur Import Region.



  • Essais:

    Lorsque vous branchez le montage: IL doit aussitôt afficher "0000,0".
    En marche continue, j'ai mesuré une erreur de 1 seconde sur 24 heures (sans arrêt du montage).
    Le clignotement bref toutes les deux minutes et normal, il correspond à l'enregistrement.

    Aucun commentaire:

    Enregistrer un commentaire