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