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 ---
- 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 ---
Modérateur : mazertoc
suite 3 de Retour sur DCF77
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
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 :
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 :
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é.
Pour un exemple de proamme exploitant se module, se reporter ici en supprimant la ligne 653, invocation de DCF77_INIT_VAR.
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
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é.
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.
Retourner vers « Langage ASM »
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 52 invités