Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur l'Assembleur !

Modérateur : mazertoc

suite 3 de Retour sur DCF77
JJE
Passioné
Passioné
Messages : 399
Âge : 83
Enregistré en : novembre 2017
Localisation : Picardie

#1 Message par JJE » dim. 16 déc. 2018 12:10

Bonsoir à tous,
Dans ce post, j' avais annoncé en préparer quelques autres sur les outils utilisés dans ce programme.Voici le troisième qui commente le module gérant le DCF77
Je renvoie le lecteur ici où il trouvera des détails sur ma notion de "module" et sur leur mise en oeuvre. Je me contente de décrire ici la mise en oeuvre du module DCF77 utilisé dans le programme de démonstration. Il peut être utile d'avoir des notions suffisantes sur le protocole DCF77 qu'on peu lire ici

Ma cros définies dans ce module et devant être invoquées par l'application
DCF77_Port macro port, pin définit le port utilisé pour communiquer avec le récepteur DCF77
DCF77_VAR macro macro définissant les variables de ce modules. Doit être invoquée dans la partie du code de l'application qui définit ses variables
Parmi ces variables seules

Code : Tout sélectionner


    DCF77_Précédent_minute         
: 1
    DCF77_Précédent_heure         
: 1
    DCF77_Précédent_quantième     
: 1
    DCF77_Précédent_jour         
: 1
    DCF77_Précédent_mois         
: 1
    DCF77_Précédent_année         
: 1


devraient être utilisées, en cas de besoin, elles donnent l'information correspondante de l'heure et la date actuelle telle que reçue dans la dernière trame valide du récepteur DCF77.
Aucune des variables du module ne nécessite d'initialisation particulière, on n'a donc pas de macro DCF77_INIT_VAR comme dans le module MPX décrit ci-avant.
DCF77_CODE son invocation installe le code de ce module. Elle doit être placée telle que ce code réside dans une même page.

Ce code possède deux points d'entrée
DCF77_IT_TIMER0 qui doit être appelé par l'application toutes les 1000 micro-cycles (1ms) dans son traitement de l'interruption timer0.
DCF77_IT_GPIO qui doit être appelé par l'application dans son traitement de l'interruption GPIO
aucun des autres sous-programmes ne devrait être appelé par l'application.
Ce module développe un mécanisme nouveau par rapport aux modules décrits dans les posts précédents de rappel de l'application. Il m'est apparu utile de pouvoir prévenir l'application de certains événements, par exemple la fin de réception d'une trame ou une perte de syncho.
si l'une des étiquettes suivantes est définie dans l'application :
    relais_DCF77_jobMinutes
    relais_DCF77_jobHeure
    relais_DCF77_jobQuantième
    relais_DCF77_jobJour
    relais_DCF77_jobMois
    relais_DCF77_jobAnnée
    relais_DCF77_jobDate
    relais_jobWaitSynchro
    relais_DCF77_FM
    relais_DCF77_jobPerteSynchro
ce sous-programme est appelé par le module. Les 6 premier à la fin du traitement de l'information spécifiée par le nom, le septième après la réception fructueuse du bit de parité sur la date, le huitième et le neuvième sur réception d'un front montant dès qu'on a reçu le premier, relais_jobWaitSynchro si on n'a pas encore reçu une trame complète, relais_DCF77_FM dans un cycle normal. Le dernier signal à l'application un problème de réception par exemple bit de parité incorrect. Le module DCF77 repart alors dans une phase de synchronisation, attente du bit 59 puis lecture de la date et l'heure à venir ce qui peut durer jusqu'à 3 minutes
Deux macros font ce travail
DCF77_MYCALL macro SSP
DCF77_GOTO macro SSP
voir dans le code ci-dessous

ci-dessous, le code de ce module :

Code : Tout sélectionner

;******************************************************************
;
                                                                   
;    NOM:      Module DCF77
;    Date création : 27/11/2018   
;    Circuit:  sans objet
;    Auteur:   JJE
;                                                                   
;******************************************************************
;
;
    Historique
;    Version 1.0 : 
;
;******************************************************************
;
                                                                   
;    Fichier requis: 
;                     MacrosTest.inc
;                                                                   
;******************************************************************
;
;
    Resources utilisées :
;
       19 octets de données
;       entre 176 et 208 pas de programme, fonction du nombre de
;       relais exploités
;       l'interruption timer0 et l'interruption sur GPIO
;       2 niveaux de pile (dont l'appel aux points d'entrée)
;
         + le niveau nécéssaire aux IT
;       1 port digital en entrée
;                                                                   
;******************************************************************

        #include "../MacrosTest.inc"

;******************************************************************
;
                             MACROS
;                     utiles à l'application
;******************************************************************
; utilisées par l'
application qui exploite ce module
; faire connaître le port utilisé
DCF77_Port    macro port
, pin
    
#DEFINE    PortDCF77    port, pin
    endm

; définir les variables utiles au module
DCF77_VAR macro
    CBLOCK
    
; 6 compteurs 8 bits correspondant aux 6 champs
    
; d’une trame DCF77 tels que lus 
    DCF77_minute    
: 1 
    DCF77_heure        
: 1
    DCF77_quantième    
: 1
    DCF77_jour        
: 1
    DCF77_mois        
: 1
    DCF77_année        
: 1
    DCF77_Bidon        
: 1    ; pour le bit de parité des dates
    DCF77_BitParité 
: 1    ; compteur 8 bits des bits à 1 dans l’unité 
                        
; lue (minutes, heure ou date)
    DCF77_Précédent : 0    ; les 6 octets lus dans la trame précédente
                        
; en cours d'affichage
    DCF77_Précédent_minute         : 1
    DCF77_Précédent_heure         : 1
    DCF77_Précédent_quantième     : 1
    DCF77_Précédent_jour         : 1
    DCF77_Précédent_mois         : 1
    DCF77_Précédent_année         : 1
    DCF77_phase        : 1    ; n° phase en cours
    DCF77             : 0    ; compteur 16 bits 
    DCF77_BP        : 1    ; DCF77_BP incrémenté toutes les ms par le
    DCF77_HP        : 1    ; Timer 0 pour la phase 0
                        ; DCF77_HP incrémenté chaque fois que DCF77
                        ; passe à 0
    DCF77_NbBits     : 1    ; décompteur 8 bits, nombre de bits restant
                        ; à lire dans la phase courante
    DCF77_dojob     : 1
    ENDC

; pas utilisés simultanément à DCF77 
DCF77_DuréeBit EQU    DCF77
; compteur 8 bits durée à 1 du bit lu. Incrémenté toutes les ms par
; le Timer 0. Initialisé à 0 sur front montant, analysé sur front
; descendant. si < 150 bit lu = 0 sinon 1

DCF77_DuréeLow    EQU    DCF77+1    ; Durée de l'
état bas
; initialisé à DCF77_DuréeLowVAL à chaque front descendant hors
; phase 0, il est décrémenté toutes les 20 ms dans le traitement de
; l'IT timer0. S'il s'annule, c'est que l'état bas est resté trop
; longtemps, perte probable de réception, on repart en phase 0

DCF77_DuréeLowVAL    EQU    .150; pour simuler unr IT toutes les
                            ; 3.000.000 microcycles (3")
DCF77_dojobSynchro  EQU .0

    endm
        
;******************************************************************
;                             MACROS
;                        utiles au module
;******************************************************************
; macros utilisées par le code du module
; mettre à 0 le compteur 16 bits DCF77
CLRF_DCF77    macro
    clrf    DCF77_BP
    clrf    DCF77_HP
    endm
    
; incrémenter le compteur 16 bits DCF77 modulo 0x10000
INCF_DCF77    macro
    incf    DCF77_BP,f
    btfsc   STATUS, Z
    incf    DCF77_HP,f
    endm
    
DCF77_INITDuréeLow macro
    movlw    DCF77_DuréeLowVAL
    movwf    DCF77_DuréeLow
    endm
            

RETOUR_SI_NOT_SYNCHRONISE macro
    btfsc    DCF77_dojob, DCF77_dojobSynchro
    return
    endm

;DCF77_INIT_VAR macro
;    CLRF_DCF77
;    clrf    DCF77_phase
;    ; préparer le déclenchement  de la phase 1
;    movlw    .1
;    movwf    DCF77_NbBits
;    endm
    
DCF77_MYCALL macro SSP
    ; appel optionel de SSP (s'
il est défini dans l'application)
    ; avec gestion de PCLATH si utile
    ifdef SSP
        ; si SSP est défini
        if (HIGH SSP & 0x18)!=(HIGH DCF77_DEBUTCODE & 0x18)
            ; si DCF77_DEBUTCODE et SSP ne sont pas
            ; dans la même page, il faut renseigner PCLATH
            movlw    HIGH SSP
            movwf    PCLATH
            call     SSP
            ; et remettre les choses en place
            movlw    HIGH DCF77_DEBUTCODE        
            movwf   PCLATH
        else
            call     SSP
        endif
    endif
    endm

DCF77_GOTO macro SSP
    ; appel optionel de SSP (s'
il est défini dans l'application)
    ; avec gestion de PCLATH si utile
    ; si SSP n'
est pas défini, on se contente d'un return
    ifdef SSP
        ; si SSP est défini
        if (HIGH SSP & 0x18)!=(HIGH DCF77_DEBUTCODE & 0x18)
            ; si DCF77_DEBUTCODE et SSP ne sont pas
            ; dans la même page, il faut renseigner PCLATH
            movlw    HIGH SSP
            movwf    PCLATH
            goto     SSP
        else
            goto     SSP
        endif
    else
        return
    endif
    endm
    
;******************************************************************
;******************************************************************
;                     Code du module DCF77    
;******************************************************************
;******************************************************************
DCF77_CODE macro
DCF77_DEBUTCODE
DCF77_jump_Job
    ; branche sur le sous-programme à effectuer en fin de phase
    ; W contient le numéro de phase active + 1
    ; en phases 0, 1 ou 2, ces relais ne sont pas exploités
    ; d'
où les 4 nop
    addwf    PCL
,f
    nop
    nop
    nop
    nop
    goto    DCFF77_Fin_Minutes
    goto    DCFF77_Fin_Heure
    goto    DCFF77_Fin_Quantième
    goto    DCFF77_Fin_Jour
    goto    DCFF77_Fin_Mois
    goto    DCFF77_Fin_Année
    goto    DCFF77_Fin_Date
DCF77_jump_JobFin
    if    HIGH
(DCF77_jump_JobFin)!=HIGH(DCF77_jump_Job)
        error "La table de DCF77_jump_Job traverse une frontière de bloc"
    endif
DCF77_get_NbBits    
    
; W contient le numéro de phase active
    
; retourne le nombre de bits à lire dans la phase suivante
    addwf    PCL
,f
    retlw    .1
    retlw    .20
    retlw    .8
    retlw    .7
    retlw    .6
    retlw    .3
    retlw    .5
    retlw    .8
    retlw    .1
    retlw    .1
DCF77_get_NbBitsFin
    if    HIGH
(DCF77_get_NbBitsFin)!=HIGH(DCF77_get_NbBits)
        error "La table de DCF77_jump_Job traverse une frontière de bloc"
    endif
;******************************************************************
;******************************************************************
;
                     INTERRUPTION TIMER 0    
;******************************************************************
;******************************************************************
;
 Cette routine doit être appelée toute le 1ms
DCF77_IT_TIMER0
    
; PCLATH est renseigné avant l'appel
    btfss   INTCON,GPIE         ; tester si interrupt GPIO autorisée
    goto    DCF77_inttimer_2    ; si non pas besoin de s'
occuper
                                
; du compteur DCF77
    
; si oui incrémenter le compteur DCF77 si on est en phase 0
    Si DCF77_phase
, NonEgalLit, .0, jump, DCF77_inttimer_1
    INCF_DCF77
    btfss   DCF77_HP
, 2
    goto    DCF77_inttimer_2
    btfss   DCF77_HP
, 1
    goto    DCF77_inttimer_2
    
; on a atteint 1536ms, 0x600 (>800 et 900 et < 1800),
    ; si on est au niveau bas,
    ; on est en réception du bit 59, on passe en phase 1 où on
    
; attend le prochain front montant, début du bit 0
    
; si on est au niveau haut, on ignore (pulse trop long)
    CLRF_DCF77
       btfss   PortDCF77
    incf    DCF77_phase
, f
    return
DCF77_inttimer_1      
    
; dans toutes les autres phases, on compte la durée du bit
    incf    DCF77_DuréeBit
,f    
DCF77_inttimer_2    
    return
;******************************************************************
;******************************************************************
;
                     INTERRUPTION GPIO    
;******************************************************************
;******************************************************************
;
 l'état du port PortDCF77 ne doit pas avoir été modifié depuis le
; debut du traitement de l'
IT
DCF77_IT_GPIO
    
; PCLATH est renseigné avant l'appel
    Si    DCF77_phase, SupOuEgalLit, .3, jump, DCF77_intgpio_1
DébutTable1
    movlw   HIGH DébutTable1
    movwf   PCLATH    
    movf    DCF77_phase, w
    addwf   PCL, f
    goto    DCF77_Phase0
    goto    DCF77_Phase1
    goto    DCF77_Phase2
FinTable1    
    if    HIGH(FinTable1)!=HIGH(DébutTable1)
        error "La table de DCF77_IT_GPIO traverse une frontière de page"
    endif
DCF77_intgpio_1
    ; traitement commun à toutes les phases >= 3
    btfsc   PortDCF77
    goto    DCF77_FM
    goto    DCF77_FD

DCF77_Phase0
    ; attendre le bit 59 d'
une trame
    
; attendre le premier front qui passe 
    
; on annule le compteur DCF77 (16 bits)sur chaque front
    
; il est incrémentés de 1 par IT Timer0 toutes les 1ms
    
; on passera en phase 1 dès que DCF77 aura atteint 0x600
    
; ce qui détecte le bit 59 d'une trame
    CLRF_DCF77          ; reset compeur DCF77
    bsf        DCF77_dojob, DCF77_dojobSynchro
    return

; On passe en phase 1 quand le compteur DCF77 atteint 0x600
; dans le traitement de l'
IT timer0
DCF77_Phase1
    
; traitement du bit 0 d'une trame
    btfsc   PortDCF77
    goto    DCF77_FM
    
DCF77_Phase1_1
    DCF77_INITDuréeLow    ; pour surveiller la perte de réception
    ; ici, front descendant, comparer DCF77_DuréeBit à 150, 
    ; si < bit à 0 si >= bit à 1
    Si    DCF77_DuréeBit, StrictInfLit, .150, jump, DCF77_Phase1_2
    ; au sortir de cette macro C est nul si le jump se fait,
    ; sinon, il vaut 1
    goto    DCF77_Erreur        ; ce bit devrait être à 0,
                                ; revenir en phase 0 
DCF77_Phase1_2
    clrf    DCF77_minute
    clrf    DCF77_heure
    clrf    DCF77_quantième
    clrf    DCF77_jour
    clrf    DCF77_mois
    clrf    DCF77_année
    incf    DCF77_phase, f   ; passer en phase suivante
    movlw   .20             ; 20 bits à lire en phase 2
    movwf   DCF77_NbBits
    return

DCF77_Phase2
    ; lecture des 20 premiers bits inexploités
    btfsc   PortDCF77
    goto    DCF77_FM
    DCF77_INITDuréeLow
    decfsz  DCF77_NbBits,f
    return
    ; les 20 bits sont lus
    ; plus rien à lire dans cette phase
    ; le bit 20 doit être à 1
    Si    DCF77_DuréeBit, StrictInfLit, .150, jump, DCF77_Erreur
    ; au sortir de cette macro C est nul si le jump se fait,
    ; sinon, il vaut 1
    clrf    DCF77_BitParité
    movlw    .8              ; 8 bits à lire en phase 3
    movwf   DCF77_NbBits
    incf    DCF77_phase, f    ; passer en phase suivante
    return

DCF77_FM
    ; Traitement commun à tous les fronts montants de toutes les 
    ; phases sauf 0
    clrf    DCF77_DuréeBit
    btfss    DCF77_dojob, DCF77_dojobSynchro
    goto    DCF77_FM_1
    DCF77_GOTO relais_jobWaitSynchro
DCF77_FM_1
    DCF77_GOTO   relais_DCF77_FM 

DCF77_FD
    ; Traitement commun aux fronts descendants de toutes les
    ; phases sauf 0, 1 et 2
    DCF77_INITDuréeLow
    ;initialise FSR pour pointer sur le compteur de la phase active
    movlw    DCF77_minute-3
    addwf    DCF77_phase, w
    movwf    FSR
    ; ici, front descendant, comparer DCF77_DuréeBit à 150, 
    ; si < bit à 0 si >= bit à 1
    Si    DCF77_DuréeBit, StrictInfLit, .150, jump, DCF77_FD_0
    ; au sortir de cette macro C est nul si le jump se fait,
    ; sinon, il vaut 1
    incf    DCF77_BitParité,f     ; n’affecte pas STATUS,C 
DCF77_FD_0
    ; fait entrer le bit lu dans la variable
    rrf     INDF, f
    decf    DCF77_NbBits, f
    btfss    STATUS, Z
    return          ; lire le bit suivant
    ; pas de bit de parité dans les phases 5 à 8
    Si DCF77_phase, InfOuEgalLit, .4, jump, DCF77_FD_1
    Si DCF77_phase, NonEgalLit, .9, jump, DCF77_FD_2
DCF77_FD_1
    ; teste parité pour les phases 3, 4 et 9
    ; effacer le bit 7
    bcf        INDF, 7
    btfsc    DCF77_BitParité, 0      ; le nombre de bits à 1
                                    ; doit être pair
    goto    DCF77_Erreur               ; erreur de parité
    clrf    DCF77_BitParité
DCF77_FD_2
    movlw   HIGH DCF77_get_NbBits
    movwf   PCLATH
    movf       DCF77_phase, w            
    call    DCF77_get_NbBits
    movwf   DCF77_NbBits
    incf    DCF77_phase, f  ; passer en phase suivante
    movlw   HIGH DCF77_jump_Job
    movwf   PCLATH
    movf       DCF77_phase, w    
    bcf        STATUS, C        ; pour les relais commençant par un rrf
    goto    DCF77_jump_Job        

DCF77_Erreur
    CLRF_DCF77          ; reset compeur DCF77
    clrf    DCF77_phase
    bsf     dojob, DCF77_dojobSynchro
    RETOUR_SI_NOT_SYNCHRONISE
    DCF77_GOTO    relais_DCF77_jobPerteSynchro
    
;******************************************************************
;                les relais vers l'
application
;
;
 fin du traitement du front descendant des phases 3 à 9 avant
; appel éventuel de l'application
;******************************************************************
DCFF77_Fin_Minutes
    DCF77_GOTO  relais_DCF77_jobMinutes
    
DCFF77_Fin_Heure
    rrf        DCF77_heure, f          ; cadrer à droite
    DCF77_GOTO  relais_DCF77_jobHeure
    
DCFF77_Fin_Quantième
    rrf        DCF77_quantième, f         ; cadrer à droite
    rrf        DCF77_quantième, f
    DCF77_GOTO  relais_DCF77_jobQuantième
    
DCFF77_Fin_Jour
    rrf        DCF77_jour,f         ; cadrer à droite le quartet 
                                ; de haut poids
    swapf   DCF77_jour,f         ; puis le déplacer en bas poids
    DCF77_GOTO  relais_DCF77_jobJour
    
DCFF77_Fin_Mois
    rrf     DCF77_mois, f        ; cadrer à droite
    rrf     DCF77_mois, f              
    rrf     DCF77_mois, f 
    DCF77_GOTO  relais_DCF77_jobMois
    
DCFF77_Fin_Année
    DCF77_GOTO  relais_DCF77_jobAnnée
    
DCFF77_Fin_Date
    bcf        DCF77_dojob, DCF77_dojobSynchro    ; on est synchronisé
    ; rectifier le numéro de la prochaine phase
    ; qui vaut 10 à tort
    movlw    .1
    movwf    DCF77_phase
    ; sauve les valeurs lues
    movf    DCF77_minute, w
    movwf    DCF77_Précédent_minute
    movf    DCF77_heure, w
    movwf    DCF77_Précédent_heure
    movf    DCF77_jour, w
    movwf    DCF77_Précédent_jour
    movf    DCF77_quantième, w
    movwf    DCF77_Précédent_quantième
    movf    DCF77_mois, w
    movwf    DCF77_Précédent_mois
    movf    DCF77_année, w
    movwf    DCF77_Précédent_année
    DCF77_GOTO  relais_DCF77_jobDate
    
DCF77_FINCODE    
    if (DCF77_FINCODE && 0x180) != (DCF77_DEBUTCODE && 0x1800)
   error " le code du module DCF77 doit résider dans une même page"
   endif
    endm


ci-dessous, le schéma logique du module multiplex le circuit récepteur se raccorde sur une broche déclarée en entrée numérique du processeur utilisé.

Schéma Multiplex.pdf


Pour un exemple de proamme exploitant se module, se reporter ici en supprimant la ligne 653, invocation de DCF77_INIT_VAR.
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Cordialement

JJE

C'est pas parcequ'on n'a rien à dire qu'il faut fermer sa G....e

Retourner vers « Langage ASM »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 43 invités