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 1 de Retour sur DCF77
Bonjour à tous,
Dans ce post, j'avais annoncé en préparer quelques autres sur les ourils utilisés dans ce programme. Voici le premier qui reprend en fait un travail ancien fait suite à ce post de ducran lapoigne Je lui avait suggéré de faire ce travail mais il n'a pas donné suite.
Le fichier ci-dessous, à utiliser comme fichier à inclure dans votre code, il y a toute une batterie de macros dont seules les deux dernières sont utiles
La première Si,
équivalent du Basic if V1>V2 then goto Là
; s'invoque par exemple par
; Si V1, StrictSup, V2, jump, Là
si V1 et V2 sont des char (1 octet non signés)
; ou
; Si V1, StrictSup+Signé, V2, jump, Là
si V1 et V2 sont des signed char (1 octet signés)
La deuxième Si16 est la même chose mais les variables sont des 16 bits signés ou non (int ou unsigned integer en Basic je crois); elle n'est pas complète, en fait, j'en avais un peu mare et j'ai décidé de laisser ce fichier incomplet et de le compléter à chaque fois que nécessaire.
Pour l'exemple, a première est utilisée plusieurs fois dans le programme cité ci-dessus.
Je crois, comme ducran lapoigne que tout commentaire est superflus.
Il est probable que ce fichier aurait sa place dans la boîte à outils qui vivote
Mode d'emploi (j'appelle ce fichier MacrosTest) : dans votre fichier source, avant tout usage de l'une de ses macros bien sur, écrire la ligne
où le ../ sera remplacé par le répertoire contenant le fichier.
Dans ce post, j'avais annoncé en préparer quelques autres sur les ourils utilisés dans ce programme. Voici le premier qui reprend en fait un travail ancien fait suite à ce post de ducran lapoigne Je lui avait suggéré de faire ce travail mais il n'a pas donné suite.
Le fichier ci-dessous, à utiliser comme fichier à inclure dans votre code, il y a toute une batterie de macros dont seules les deux dernières sont utiles
La première Si,
équivalent du Basic if V1>V2 then goto Là
; s'invoque par exemple par
; Si V1, StrictSup, V2, jump, Là
si V1 et V2 sont des char (1 octet non signés)
; ou
; Si V1, StrictSup+Signé, V2, jump, Là
si V1 et V2 sont des signed char (1 octet signés)
La deuxième Si16 est la même chose mais les variables sont des 16 bits signés ou non (int ou unsigned integer en Basic je crois); elle n'est pas complète, en fait, j'en avais un peu mare et j'ai décidé de laisser ce fichier incomplet et de le compléter à chaque fois que nécessaire.
Pour l'exemple, a première est utilisée plusieurs fois dans le programme cité ci-dessus.
Je crois, comme ducran lapoigne que tout commentaire est superflus.
Il est probable que ce fichier aurait sa place dans la boîte à outils qui vivote
Mode d'emploi (j'appelle ce fichier MacrosTest) : dans votre fichier source, avant tout usage de l'une de ses macros bien sur, écrire la ligne
Code : Tout sélectionner
#include "../MacrosTest.inc"
où le ../ sera remplacé par le répertoire contenant le fichier.
Code : Tout sélectionner
;******************************************************************
; PROGRAMME affiche la durée des pulses d'un module DCF77
;******************************************************************
;
; NOM : Affiche durées pulses
; Date : 02/12/2018
; Circuit : Platine d'essais
; Auteur : JJE
;
;******************************************************************
;
; Fichier requis:
; p12F675.inc
; MacrosTest.inc
; Module Multiplex.inc
; Module DCF77.inc
;
;******************************************************************
;
; Historique :
; Version 1.0 : 12/12/2018
; Version 1.1
; - suppression du relais relais_DCF77_DébutTrame qui ne
; faisait rien et était resté là par erreur
; - compléter quelques commentaires
;
;******************************************************************
;
; Notes: Ce programme affiche successivement, toutes les 5ms,
; 1 - en hexa la fourchette des durées des pulses lus
; b0min, b0max, b1min, b1max (4 fois deux chiffres)
; 2 - en hexa la fourchette des intervales entre deux fronts
; montants
; durée min durée max (deux fois quatre chiffres)
; 3 - le jour et l'heure tels que donnés par le module DCF77
; jour(1 à 7), tiret, heure, minutes, tiret, tiret
; 4 - le jour et la date tels que donnés par le module DCF77
; jour(1 à 7), tiret, quantième, mois, année (2 chiffre de
; droite)
;
; Tant que le module DCF77 ne s'est pas synchronisé, les affichages
; 3 et 4 ne sont pas effectués (affichent des tirets médians)
;
;******************************************************************
#include "p12F675.inc"
#include "../MacrosTest.inc"
#include "../Module Multiplex/Programme/V2/Module Multiplex.inc"
#include "../Module DCF77/Programme/Module DCF77.inc"
;******************************************************************
; préciser ici les directives __CONFIG nécessaires
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _INTRC_OSC_NOCLKOUT
;******************************************************************
; Les ports utilisés
;******************************************************************
; Renseigner le module Multiplexeur des ports utilisés
MPX_Strobe GPIO, 0
MPX_Data GPIO, 1
MPX_Clock GPIO, 2
; Renseigner le module DCF77 du port utilisé
DCF77_Port GPIO, 5
;******************************************************************
; conserver une et une seule des lignes suivantes, en fonction
; du hard
#define ANODECOMMUNE
; #define CATHODECOMMUNE
; brochage sur la platine d'essai
#DEFINE segmenta 0x08 ; 0x1
#DEFINE segmentb 0x01 ; 0x2
#DEFINE segmentc 0x80 ; 0x4
#DEFINE segmentd 0x04 ; 0x80
#DEFINE segmente 0x02 ; 0x40
#DEFINE segmentf 0x40 ; 0x20
#DEFINE segmentg 0x20 ; 0x10
#DEFINE segmentDP 0x10 ; 0x8
;******************************************************************
; commandes des 7 segments
ifdef ANODECOMMUNE
Segmenta EQU segmenta^0xff
Segmentb EQU segmentb^0xff
Segmentc EQU segmentc^0xff
Segmentd EQU segmentd^0xff
Segmente EQU segmente^0xff
Segmentf EQU segmentf^0xff
Segmentg EQU segmentg^0xff
SegmentDP EQU segmentDP^0xff
; pour améliorer la mise en page du listing
Segmentsab EQU Segmenta & Segmentb
Segmentsac EQU Segmenta & Segmentc
Segmentsbc EQU Segmentb & Segmentc
Segmentsef EQU Segmente & Segmentf
Segmentsabc EQU Segmenta & Segmentb & Segmentc
Segmentsefg EQU Segmente & Segmentf & Segmentg
else
Segmenta EQU segmenta
Segmentb EQU segmentb
Segmentc EQU segmentc
Segmentd EQU segmentd
Segmente EQU segmente
Segmentf EQU segmentf
Segmentg EQU segmentg
SegmentDP EQU segmentDP
; pour améliorer la mise en page du listing
Segmentsab EQU Segmenta + Segmentb
Segmentsac EQU Segmenta + Segmentc
Segmentsbc EQU Segmentb + Segmentc
Segmentsef EQU Segmente + Segmentf
Segmentsabc EQU Segmenta + Segmentb + Segmentc
Segmentsefg EQU Segmente + Segmentf + Segmentg
endif
ifdef ANODECOMMUNE
chiffre0 EQU Segmentsab & Segmentc & Segmentd & Segmentsef
chiffre1 EQU Segmentb & Segmentc
chiffre2 EQU Segmentsab & Segmentd & Segmente & Segmentg
chiffre3 EQU Segmentsab & Segmentc & Segmentd & Segmentg
chiffre4 EQU Segmentb & Segmentc & Segmentf & Segmentg
chiffre5 EQU Segmentsac & Segmentd & Segmentf & Segmentg
chiffre6 EQU Segmenta & Segmentc & Segmentd & Segmentsefg
chiffre7 EQU Segmenta & Segmentb & Segmentc
chiffre8 EQU Segmentsabc & Segmentd & Segmentsefg
chiffre9 EQU Segmentsab & Segmentc & Segmentf & Segmentg
chiffreA EQU Segmentsab & Segmentc & Segmentsefg
chiffreB EQU Segmentc & Segmentd & Segmentsefg
chiffreC EQU Segmenta & Segmentd & Segmente & Segmentf
chiffreD EQU Segmentsbc & Segmentd & Segmente & Segmentg
chiffreE EQU Segmenta & Segmentd & Segmentsef & Segmentg
chiffreF EQU Segmenta & Segmentsefg
chiffreVide EQU 0xff
point EQU SegmentDP
tiretB EQU Segmentd
tiretM EQU Segmentg
tiretH EQU Segmenta
else
chiffre0 EQU Segmentsab + Segmentc + Segmentd + Segmentsef
chiffre1 EQU Segmentb + Segmentc
chiffre2 EQU Segmentsab + Segmentd + Segmente + Segmentg
chiffre3 EQU Segmentsab + Segmentc + Segmentd + Segmentg
chiffre4 EQU Segmentb + Segmentc + Segmentf + Segmentg
chiffre5 EQU Segmentsac + Segmentd + Segmentf + Segmentg
chiffre6 EQU Segmenta + Segmentc + Segmentd + Segmentsefg
chiffre7 EQU Segmenta + Segmentb + Segmentc
chiffre8 EQU Segmentsabc + Segmentd + Segmentsefg
chiffre9 EQU Segmentsab + Segmentc + Segmentf + Segmentg
chiffreA EQU Segmentsab + Segmentc + Segmentsefg
chiffreB EQU Segmentc + Segmentd + Segmente + Segmentsefg
chiffreC EQU Segmenta + Segmentd + Segmente + Segmentf
chiffreD EQU Segmentsbc + Segmentd + Segmente + Segmentg
chiffreE EQU Segmenta + Segmentd + SegmentSef + Segmentg
chiffreF EQU Segmenta + Segmente + Segmentf + Segmentg
chiffreVide EQU 0x00
point EQU SegmentDP
tiretB EQU Segmentd
tiretM EQU Segmentg
tiretH EQU Segmenta
endif
;
;******************************************************************
; quelques constantes pour MPX
; préciser la durée en ms d'affichage des afficheurs.
; pour une fréquence de 4MH, prescaler de 4
; .9 est bon pour le premier paramètre, qui produit une IT
; toutes les ms
; pour 8 afficheurs,.4 est bon pour le deuxième
; .8 est le nombre d'afficheurs utilisés
MPX_EQU .9, .4, .8
Nb_ITVAL EQU .20 ; pour simuler unr IT toutes les
; 20.000 microcycles (20ms)
Cmpt_SecondeVAL EQU .50 ; pour simuler une IT toutes les secondes
job0VAL EQU .5 ; pour simuler une IT toutes les 5"
; changement du type d'affichage
errorlevel -302
;******************************************************************
; valeurs initiales des registres spéciaux
OPTIONVAL EQU B'10000001' ; bit 7 = 1 : GPIO pull-ups disabled
; bit 6 = 0 : sans objet
; bit 5 = 0 : internal cycle clock
; bit 4 = 0 : sans objet
; bit 3 = 0 : prescaler is assigned
; to TIMER0 module
; bit 2-0 = 001 : prescaler rate 1:4
; cf page 14 du DataSheet
TRISIOVAL EQU B'00110000' ; GPIO4 et 5 en entrée
IOCVAL EQU B'00100000' ; IOC sur GP5
ANSELVAL EQU B'00000000' ; ADCS<2:0> = 000 sans objet
; ANS3: ANS0 = 0000 pas d'analogique
; cf page 46 du DataSheet
INTCONVAL EQU B'11000000' ; bit 7 = 1 : Enables unmasked
; interrupts
; bit 6 = 1 : Enables all
; peripheral interrupts
; bit 5 = 0 : disables TMR0
; interrupt
; bit 4 = 0 : disables GPIO port
; change interrupt
; bit 3-0 = 0 sans objet
; cf page 15 du DataSheet
;******************************************************************
; MACROS
;******************************************************************
BANK1 macro
bsf STATUS,RP0
endm
BANK0 macro
bcf STATUS,RP0
endm
ADD_POINT macro
ifdef ANODECOMMUNE
andlw point
else
iorlw point
endif
endm
; convertit le contenu de V,
; en ce qu'il faut mettre dans add et add+1, supposés 2 octets du
; tampon, pour afficher sa valeur en hexa
SORT8 macro V, add
movf V, w
andlw 0x0f
call convertir
movwf add + 1
swapf V, w
andlw 0x0f
call convertir
movwf add
endm
; idem V variable 16 bits Bas poids en tête
SORT16 macro V, add
SORT8 V, add+2
SORT8 V+1, add
endm
; met A à 0, A variable 16 bits
CLRF16F macro A
clrf A
clrf A+1
endm
; copie A dans AA, variables 16 bits
MOV16F macro A, AA
movf A, w
movwf AA
movf A+1, w
movwf AA+1
endm
; incrémente A, variable 16 bits bas poids en tête
; retourne Z armé si dépassement de capacipé (résultat nul),
; clear sinon
INCF16 macro A
incf A, f
btfsc STATUS, Z
incf A+1, f
endm
; call SSP avec gestion éventuelle de PCLATH
; sans intérêt pour un 12F675 qui n'a qu'une page programme
; utile pour les pics à plusieurs pages de programme
MYCALL macro SSP
; Dans ce programme, ON SAIT QUE L'APPELANT EST EN PAGE 0
if ((HIGH SSP) & 0x18)!= .0 ; on est en page 0
; si SSP n'y est pas, il faut renseigner PCLATH
movlw HIGH SSP
movwf PCLATH
call SSP
clrf PCLATH
else
call SSP
endif
endm
;******************************************************************
; DECLARATIONS DE VARIABLES
;******************************************************************
CBLOCK 0x020 ; Début de la zone des variables
; sauvegardes pour l'IT
w_temp : 1 ; W
status_temp : 1 ; STATUS
FSR_temp : 1
PCLATH_temp : 1
endc
; réserve l'espace nécessaire au module Multiplex
MPX_VAR
; réserve l'espace nécessaire au module DCF77
DCF77_VAR
CBLOCK
; les variables de ce programme
Nb_IT : 1 ; compteur d'IT pour Nb_ITVAL ms
Cmpt_Seconde : 1 ; compteur pour IT 1"
; variables pour déclencher les actions requises
; dans la boucle principale
dojob : 1 ; ensemble de flags pour job0 à job2
Cmpt_job0 : 1 ; décompteur pour déclencher job0
TypeAffichage : 1 ; type d'affichage à mettre en oeuvre
; au prochain appel de job0 (<1;4>
Cmpt_Inter_FM : 0 ; compteur 16 bits utile pour compter
; la durée inter fronts montants
Cmpt_Inter_FM_BP : 1
Cmpt_Inter_FM_HP : 1
Cmpt_Inter_FM_Min : 2 ; mini de Cmpt_Inter_FM
Cmpt_Inter_FM_Max : 2 ; maxi de Cmpt_Inter_FM
Cmpt_Inter_FM_tmp : 0 ; la durée inter fronts montants
; en cours
Cmpt_Inter_FM_BP_tmp : 1 ; bas poids
Cmpt_Inter_FM_HP_tmp : 1 ; haut poids
Cmpt_DuréePulse : 1 ; Compteur durée d'un pulse
Cmpt_DuréePulse_tmp : 1 ; Compteur durée d'un pulse en cours
Cmpt_DuréePulse0Min : 1 ; mini de Cmpt_DuréePulse bit 0
Cmpt_DuréePulse0Max : 1 ; maxi de Cmpt_DuréePulse bit 0
Cmpt_DuréePulse1Min : 1 ; mini de Cmpt_DuréePulse bit 1
Cmpt_DuréePulse1Max : 1 ; maxi de Cmpt_DuréePulse bit 1
;******************************************************************
; variables locales aux sous-programmes
;******************************************************************
; variables du ssp de sortie SetRegWithW appelé par Job1
CmptBits : 1 ; compe les bits sortis
HC4094Temp : 1 ; rangement temporaire de la valeur
; à écrire
; variables utilisées uniquement par convertDCB
convert_tempHP : 1
convert_tempBP : 1
; compteur du ssp wait
wait_temp : 1
; variables utilisées uniquement par le remplissage du tampon
RemplirTampon_temp : 1
cmpt_remplirTampon : 1
lastData : 1
ENDC ; Fin de la zone
if lastData>=0x60
error "les variables doivent être en banque 0"
endif
; si l'application utilise la banque mémoire 1
; les lignes suivantes sont nécessaires
; ici, ce n'est pas le cas
; CBLOCK 0xA0
; sauvegardeIT : 2
; ENDC
;******************************************************************
; constantes facilitant l'accès au tampon
; et la lecture du code
;******************************************************************
; des valeurs en cours d'affichage
TamponOsccalHP EQU MPX_Tampon+2
TamponOsccalBP EQU MPX_Tampon+3
TamponDuréePulse0Min EQU MPX_Tampon
TamponDuréePulse0Max EQU MPX_Tampon+2
TamponDuréePulse1Min EQU MPX_Tampon+4
TamponDuréePulse1Max EQU MPX_Tampon+6
TamponInterFMMin EQU MPX_Tampon
TamponInterFMMax EQU MPX_Tampon+4
TamponJour EQU MPX_Tampon
TamponHeure EQU MPX_Tampon+2
TamponMinute EQU MPX_Tampon+4
TamponQuantième EQU MPX_Tampon+2
TamponMois EQU MPX_Tampon+4
TamponAnnée EQU MPX_Tampon+6
; les flags pour marquer les tâches à faire
dojob0 EQU 0 ; flag utile à déclencher job0
dojob1 EQU 1 ; flag utile à déclencher job1
dojob2 EQU 2 ; flag utile à déclencher job2
dojob3 EQU 3 ; clear tant que pas vu de front
; montant
dojob4 EQU 4 ; set pour traiter Cmpt_DuréePulse
; après avoir reçu le premier
; front montant sur PortDCF77
dojob5 EQU 5 ; set pour afficher heure et date
; dès que DCF77 le dit
; reset dès que perte de synchro
errorlevel -302
;******************************************************************
; DEMARRAGE SUR RESET
;******************************************************************
org 0x000 ; Adresse de départ après reset
goto init
;******************************************************************
; ROUTINE INTERRUPTION
;******************************************************************
;sauvegarder registres
;---------------------
ORG 0x004 ; adresse d'interruption
; interruption reçue toutes les 1ms
movwf w_temp ; 1 sauver registre W
swapf STATUS,w ; 2 swap status avec résultat dans w
movwf status_temp ; 3 sauver status swappé
BANK0
movf FSR, w ; 4
movwf FSR_temp ; 5
movf PCLATH, w ; 6
movwf PCLATH_temp ; 7
clrf PCLATH ; 8
BANK0
btfsc INTCON,T0IE ; 4/5 tester si interrupt timer autorisée
btfss INTCON,T0IF ; 5/6 oui, tester si interrupt timer en cours
goto IT_1 ; 7 non, c'est une autre interrupt
bcf INTCON,T0IF ; 7 effacer flag interrupt timer
movlw MPX_TIMER0VAL ; 9
movwf TMR0 ; 10
; à ce moment, TIMER0 va compter 988 [(256-9)*4] micro-cycles
; et reviendra au début de ce sous-programme de gestion des IT
; ce qui compte tenu des instructions qui précèdent et des deux
; non décomptées après l'initialisation de TMR0 ammène bien à
; 1000 micro-cycles, soit 1000 microsecondes
; fait le travail du module MPX
MYCALL MPX_IT_TIMER0
; fait le travail du module DCF77
MYCALL DCF77_IT_TIMER0
; fait le travail local de ce programme
call IT_Timer0
goto restaurereg
IT_1
btfsc INTCON,GPIE ; tester si IT GPIO autorisée
btfss INTCON,GPIE ; oui, tester si IT GPIO en cours
goto IT_2
movf GPIO, w
bcf INTCON,GPIF
; fait le travail du module DCF77
MYCALL DCF77_IT_GPIO
; fait le travail local de ce programme
call intgpio ; aller la traiter
; pas d'autre IT à gérer dans ce programme
; si IT_3 est utile, il faut garder les deux instructions suivantes
; clrf PCLATH
; goto restaurereg
IT_2
; restaurer lesregistres
restaurereg
movf FSR_temp, w ; 4 restaurer FSR avant STATUS
movwf FSR ; 5
movf PCLATH_temp, w ; 6
movwf PCLATH ; 7
swapf status_temp,w ; 2 swap ancien status
movwf STATUS ; 3 restaurer status
swapf w_temp,f ; 6 Inversion L et H de l'ancien W
; sans modifier Z
swapf w_temp,w ; 7 Réinversion de L et H dans W
; W restauré sans modifier status
retfie ; 8 return from interrupt
;******************************************************************
; TABLES DE CONVERSION
; placées ici pour ne pas avoir de soucis avec PCLATH
;******************************************************************
; convertir la valeur présente dans W <0:15> en la valeur à envoyer
; au HC4094 pour un affichage de ce chiffre sur le TDS0316
convertir
addwf PCL,f
retlw chiffre0
retlw chiffre1
retlw chiffre2
retlw chiffre3
retlw chiffre4
retlw chiffre5
retlw chiffre6
retlw chiffre7
retlw chiffre8
retlw chiffre9
retlw chiffreA
retlw chiffreB
retlw chiffreC
retlw chiffreD
retlw chiffreE
retlw chiffreF
fintables
if high(fintables-1) != high(convertir)
error "Les tables franchissent une frontière de bloc."
endif
;******************************************************************
; INTERRUPTION TIMER 0
;******************************************************************
; Cette routine est appelée toutes les 1ms
IT_Timer0
INCF16 Cmpt_Inter_FM_tmp
btfsc dojob, dojob4
incf Cmpt_DuréePulse_tmp, f
decfsz Nb_IT, f
return
; ici, on passe toutes les Nb_ITVAL ms (20ms)
; on réinitialise le compteur de passages
movlw Nb_ITVAL
movwf Nb_IT
decfsz Cmpt_Seconde, f
return
; ici, on passe toutes les Nb_ITVAL*Cmpt_SecondeVAL ms
; (20*50=1000ms), on réinitialise le compteur de passages
movlw Cmpt_SecondeVAL
movwf Cmpt_Seconde
; décrémenter wait_temp si besoin, pour sortir du SSP wait
movf wait_temp, f
btfss STATUS, Z
decf wait_temp, f
; décrémenter Cmpt_job0 si besoin,
; pour lancer job0 toutes les 5ms
movf Cmpt_job0, f
btfss STATUS, Z
decfsz Cmpt_job0, f
return
; ici, on passe toutes les job0VAL s (5")
; on réinitialise le compteur de passages
movlw job0VAL
movwf Cmpt_job0
bsf dojob, dojob0
return
;******************************************************************
; INTERRUPTION GPIO
;******************************************************************
intgpio
btfsc PortDCF77
goto intgpio_1
; front descendant
; arrêter de mesurer la durée du pulse
bcf dojob, dojob4
; sauve la valeur mesurée
movf Cmpt_DuréePulse_tmp, w
movwf Cmpt_DuréePulse
; et réinitialise la variable
clrf Cmpt_DuréePulse_tmp
bsf dojob, dojob1
return
intgpio_1
; front montant
bsf dojob, dojob4
btfss dojob, dojob3
goto intgpio_1_1 ; si c'est le premier front montant
; sauve la valeur mesurée
MOV16F Cmpt_Inter_FM_tmp, Cmpt_Inter_FM
; et réinitialise la variable
CLRF16F Cmpt_Inter_FM_tmp
bcf dojob, dojob3
bsf dojob, dojob2
return
intgpio_1_1
bsf dojob, dojob3
; et réinitialise la variable
CLRF16F Cmpt_Inter_FM_tmp
return
;******************************************************************
; PROGRAMME PRINCIPAL
;******************************************************************
; Initialisations
; ---------------
init
clrf GPIO ; Sorties à 0
BANK1 ; sélectionner banque 1
; calibrer l'oscilateur interne
; -----------------------------
; sur mon PIC, le call 0x3ff plante !
; movlw 0x40
; movlw 0x44
; movlw 0x2C
; movlw 0x5C
; movlw 0x6C
; movlw 0x64
; movlw 0x60
movlw 0x4c
movwf OSCCAL
; initialiser les registres spéciaux
; -----------------------------------
movlw OPTIONVAL ; charger masque
movwf OPTION_REG ; initialiser registre option
movlw TRISIOVAL
movwf TRISIO
movlw ANSELVAL
movwf ANSEL
movlw IOCVAL
movwf IOC ; initialise IOC
BANK0
movlw INTCONVAL
movwf INTCON ; initialise INTCON
; Effacer RAM banque 0
; --------------------
; on se contente d'effacer les @ de 0x20 à 0x5f
; puisque l'on n'utilise pas la banque 1
movlw 0x020 ; initialisation pointeur
movwf FSR ; pointeur d'adressage indirect
init1
clrf INDF ; effacer ram
incf FSR,f ; pointer sur suivant
btfss FSR,6 ; tester si fin zone atteinte (>=40)
goto init1 ; non, boucler
btfss FSR,5 ; tester si fin zone atteinte (>=60)
goto init1 ; non, boucler
; initialisations spécifiques
; ---------------------------
; la doc du module Multiplex indique que certaines variables
; doivent être initialisées, laissons le faire
MPX_INIT_VAR
; idem pour le module DCF77
DCF77_INIT_VAR
; des variables exigeant un valeur initiale non nulle
movlw Nb_ITVAL
movwf Nb_IT
; pour mesurer les secondes
movlw Cmpt_SecondeVAL
movwf Cmpt_Seconde
; initialise le compteur de durée d'affichage
movlw job0VAL
movwf Cmpt_job0
; des minima improbables
movlw 0xff
movwf Cmpt_Inter_FM_Min
movwf Cmpt_Inter_FM_Min+1
movwf Cmpt_DuréePulse0Min
movwf Cmpt_DuréePulse1Min
; nettoyer le tampon
call RemplirTamponAvec_chiffreVide
; c'est MPX_InitMultiplex qui lance l'IT timer0
MYCALL MPX_InitMultiplex
call Tests_Affichage ; affiche des 8.
movlw .2
call wait
; affichage OSCCAL pour info
call RemplirTamponAvec_tiretM
BANK1
movf OSCCAL, w
BANK0
movwf RemplirTampon_temp
SORT8 RemplirTampon_temp, TamponOsccalHP
movlw .5
call wait
; on autorise l'IT GPIO
bsf INTCON, GPIE
; pour commencer par l'affichage 0
movlw 0xff
movwf TypeAffichage
movlw job0VAL
movwf Cmpt_job0
;******************************************************************
; Boucle principale
; -----------------
;******************************************************************
bcl0
btfsc dojob, dojob0
call job0
btfsc dojob, dojob1
call job1
btfsc dojob, dojob2
call job2
goto bcl0
;******************************************************************
; Appels du module DCF77
;******************************************************************
relais_DCF77_jobDate
bsf dojob, dojob5
return
relais_DCF77_jobPerteSynchro
bcf dojob, dojob5
return
;******************************************************************
; JOB0
;******************************************************************
; transfère dans le tampon, les valeurs à afficher
; en fonction de la valeur de TypeAffichage <0 ; 3>
; TypeAffichage est incrémenté modulo 4 avant l'appel pour
; faciliter la codage du goto calculé
job0
bcf dojob, dojob0
; nettoyer le tampon
call RemplirTamponAvec_tiretM
; incrémenter le type d'affichage modulo 4
incf TypeAffichage, f
movlw 0x03
andwf TypeAffichage, w
; et appeler le ssp associé
movwf TypeAffichage
addwf PCL, f
goto affiche0
goto affiche1
goto affiche2
goto affiche3
affiche0
; affiche DuréePulseMin et Max
SORT8 Cmpt_DuréePulse0Min, TamponDuréePulse0Min
SORT8 Cmpt_DuréePulse0Max, TamponDuréePulse0Max
SORT8 Cmpt_DuréePulse1Min, TamponDuréePulse1Min
SORT8 Cmpt_DuréePulse1Max, TamponDuréePulse1Max
return
affiche1
; affiche Cmpt_Inter_FM_Min et Max
SORT16 Cmpt_Inter_FM_Min, TamponInterFMMin
SORT16 Cmpt_Inter_FM_Max, TamponInterFMMax
return
affiche2
btfss dojob, dojob5
goto affiche2_1
; affiche le jour et l'heure
; jour, tiret, heure, minutes
movf DCF77_Précédent_jour, w
call convertir
movwf TamponJour
movlw TamponHeure
movwf FSR
movf DCF77_Précédent_heure, w
call convertDCB
; ici, FSR = TamponMinute
movf DCF77_Précédent_minute, w
call convertDCB
return
affiche2_1
; DCF77 n'est pas synchronisé
call RemplirTamponAvec_tiretH
return
affiche3
btfss dojob, dojob5
goto affiche3_1
; affiche la date
; jour, tiret, quantième, mois, année(2 chiffres bas poids)
movf DCF77_Précédent_jour, w
call convertir
movwf TamponJour
movlw TamponQuantième
movwf FSR
movf DCF77_Précédent_quantième, w
call convertDCB
; ici, FSR = TamponMois
movf DCF77_Précédent_mois, w
call convertDCB
; ici, FSR = TamponAnnée
movf DCF77_Précédent_année, w
call convertDCB
return
affiche3_1
; DCF77 n'est pas synchronisé
call RemplirTamponAvec_tiretB
return
;******************************************************************
; JOB1
;******************************************************************
; une nouvelle DuréePulse vient d'être mesurée,
; mettre à jour Cmpt_DuréePulse0Min et Cmpt_DuréePulse0Max
; et Cmpt_DuréePulse1Min et Cmpt_DuréePulse1Max
; en conséquence. L'affichage sera mis à jour en son temps
job1
bcf dojob, dojob1
Si Cmpt_DuréePulse, StrictInfLit, .150, jump, job1_bit0
Si Cmpt_DuréePulse, StrictInf, Cmpt_DuréePulse1Min, jump, job1_bit1_1
Si Cmpt_DuréePulse, StrictSup, Cmpt_DuréePulse1Max, jump, job1_bit1_2
return
job1_bit1_1
; filtre les valeurs supérieures à 240
Si Cmpt_DuréePulse, StrictSupLit, .240, jump, job1_bit0_3
movf Cmpt_DuréePulse, w
movwf Cmpt_DuréePulse1Min
return
job1_bit1_2
movf Cmpt_DuréePulse, w
movwf Cmpt_DuréePulse1Max
return
job1_bit0
; filtre les valeurs inférieures à 32 (valeur choisie un peu
; au hazard sert de filtre soft des parasites
Si Cmpt_DuréePulse, StrictInfLit, .32, jump, job1_bit0_3
Si Cmpt_DuréePulse, StrictInf, Cmpt_DuréePulse0Min, jump, job1_bit0_1
Si Cmpt_DuréePulse, StrictSup, Cmpt_DuréePulse0Max, jump, job1_bit0_2
return
job1_bit0_1
movf Cmpt_DuréePulse, w
movwf Cmpt_DuréePulse0Min
return
job1_bit0_2
movf Cmpt_DuréePulse, w
movwf Cmpt_DuréePulse0Max
job1_bit0_3
return
;******************************************************************
; JOB2
;******************************************************************
; une nouvelle Cmpt_Inter_FM vient d'être mesurée,
; mettre à jour Cmpt_Inter_FM_Min et Cmpt_Inter_FM_Max
; en conséquence. L'affichage sera mis à jour en son temps
job2
bcf dojob, dojob2
; filtrer les valeurs inférieures à 0x100 (Cmpt_Inter_FM_HP==0)
movf Cmpt_Inter_FM_HP, f
btfsc STATUS, Z
goto job2_3
; et les valeurs supérieures à 0x600 (bit 59 d'une trame)
Si Cmpt_Inter_FM_HP, SupOuEgalLit, .6, jump, job2_3
Si16 Cmpt_Inter_FM, StrictInf, Cmpt_Inter_FM_Min, jump, job2_1
Si16 Cmpt_Inter_FM, StrictSup, Cmpt_Inter_FM_Max, jump, job2_2
return
job2_1
MOV16F Cmpt_Inter_FM, Cmpt_Inter_FM_Min
return
job2_2
MOV16F Cmpt_Inter_FM, Cmpt_Inter_FM_Max
job2_3
return
;******************************************************************
; convertDCB
;******************************************************************
; convertit le contenu de W, nombre écrit en DCB
; en ce qu'il faut mettre dans les TDSO316
; pour afficher sa valeur dans les octets pointés
; par FSR haut poids puis bas poids
; en sortie FSR pointe l'octet suivant
convertDCB
movwf convert_tempHP
movlw 0x0f
andwf convert_tempHP,w
movwf convert_tempBP
swapf convert_tempHP,w
andlw 0x0f
movwf convert_tempHP
movf convert_tempHP, w
call convertir
movwf INDF
incf FSR, f
movf convert_tempBP, w
call convertir
movwf INDF
incf FSR, f
return
;******************************************************************
; ROUTINE DE TEMPORISATION
;******************************************************************
; Cette routine introduit un retard de environ w secondes
; pendant lequel l'affichage courant est maintenu si l'IT Timer0
; est active. wait_temp est décrémenté dans cette IT.
wait
movwf wait_temp
wait_1
movf wait_temp, f
btfss STATUS,Z
goto wait_1
return
; initialise le tampon pour la phase de test d'affichage
; tous les segment et le point doivent s'allumer
Tests_Affichage
call RemplirTamponAvec_8
movlw .2
call wait
return
;******************************************************************
; Routines de remplissage du tampon
;******************************************************************
RemplirTamponAvec_chiffreVide
movlw chiffreVide
goto RemplirTampon
RemplirTamponAvec_tiretB
movlw tiretB
goto RemplirTampon
RemplirTamponAvec_tiretM
movlw tiretM
goto RemplirTampon
RemplirTamponAvec_tiretH
movlw tiretH
goto RemplirTampon
RemplirTamponAvec_8
movlw chiffre8
ADD_POINT
RemplirTampon
movwf RemplirTampon_temp
movlw MPX_Tampon
movwf FSR
movlw NbAfficheurs
movwf cmpt_remplirTampon
movf RemplirTampon_temp, w
RemplirTampon_1
movwf INDF
incf FSR,f
decfsz cmpt_remplirTampon, f
goto RemplirTampon_1
return
Fin_Code
; introduire le code des deux modules utilisés
MPX_CODE
org 0x200 ; pour assurer que le code de DCF77 soit dans une
; seule page
DCF77_CODE
END
Retourner vers « Langage ASM »
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 126 invités