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 2 de Retour sur DCF77
Bonsoir à tous,
Dans ce post, j' avais annoncé en préparer quelques autres sur les ourils utilisés dans ce programme.Voici le deuxième qui commente le module de multiplexage.
Quelques mots d'abord sur ce que j'appelle dans ces posts "module". Il s'agit pour moi d'une présentation d'un bloc de programme et de ses annexes (variables) cherchant à en faciliter la réutilisation dans le contexte le plus large possible. Formellement, c'est un fichier à inclure qui ne contient que des macros. Invoquer l'une d'elles dans son application revient à faire un copier/coller de son contenu dans le code de l'application avec l' avantage supplémentaire de pouvoir passer des paramètres. L'idéal, pour un tel module est qu'il soit totalement indépendant des contextes hard et soft. Hard, sur quel pic s'execute-it, comment les périphériques sont-ils mis en oeuvre. Soft : problèmes de banque mémoire et de pages de code. Il ne devrait être connu que par ses fonctionnalités et sa procédure de mise en oeuvre.
Je décris dans les lignes suivantes le cas de ce module de multiplexage qui prend en charge l'affichage sur 3 à 8 afficheurs 7 segments en n'utilisant que trois ports du processeur qui l'utilise.
Il utilise 3 ports en sortie du processeur qui va le faire tourner. Il serait très restricteur de les imposer à l'utilisateur.
Les 3 macros
permettent à l'utilisateur de préciser au module MPX quels sont les ports qu'il a prévu d'utiliser, Le module ne les connaissant que par l'intermédiaire de la constante définie par le #DEFINE.
Ce module, comme la plupart qu'on est amené à écrire, nécessite ses propres variables. Pour les insérer dans l'application, il suffit d'invoquer la macro
MPX_VAR comme on utilise une directive CBLOCK dans son code ; MPASM interdit d'invoquer une macro dans un CBLOCK, la macro développe donc un CBLOCK complet, sans adresse de départ qui est donc celle où on en est arrivé dans le précédent CBLOCK écrit, 0 par défaut. Remarquez que je ne connais pas de moyen avec MPASM de déclarer ces variables privées, par exemple, dans le cas présent, toutes le sont sauf, une MPX_Tampon. C'est une des raisons qui m'ont incité à préfixer leur étiquette de MPX_, a priori, l'utilisateur doit s'interdire d'utiliser ces étiquettes sauf celle qui est explicitement autorisée.
De la même manière, il n'est pas rare que des variables nécessitent une valeur initiale non nulle. C'est le rôle de la macro MPX_INIT_VAR qui d'une part permet de préciser le nombre d'afficheurs mis en oeuvre et d'autre part la fréquence de rafraîchissement. En passant, elle vérifie que l'application a bien défini l'une des constantes précisant le type d'afficheur utilisé (anode ou cathode commune). Le module MPX a bien sûr besoin de le savoir et ce n'est pas à lui d'en décider.
Bien que ce ne soit pas toujours le cas ce module nécessite un "démarrage". C'est le rôle de la macro MPX_InitMultiplex qui va lancer l'interruption timer0 sur laquelle repose le fonctionnement de ce module et qui sera appelée toutes les ms. A partir de ce moment, le tampon est affiché octet par octet, sans que l'utilisateur ait à s'en soucier. Pour modifier l'affichage, il suffit d'écrire dans l'octet du tampon visé la configuration de bits que l'utilisateur veut voir allumés.
C'est bien sûr à l'application de prendre en charge la gestion de l'interruption timer0, en particulier parcequ'elle peut avoir des traitements à faire en parallèle de MPX, avant ou après. Charge à elle d'appeler le module MPX en appelant le sous-programme MPX_IT_TIMER0 toutes les ms (1000micro-cycles)
C'est le rôle de la macro MPX_CODE d'installer dans l'application le code nécessaire à ce module, il doit résider dans une même page de code. Comme on n'y accède que par un call, PCLATH<4;3> sera initialisé sur la bonne page t, a priori, le module n'aura pas à s'en soucier.
Problème de banques mémoire : Si l'application utilise plusieurs banques, les variabless du modules doivent résider dans une même banque. J'ai trouvé préférable de laisser l'application gérer ce problème car elle seule connaît, au moment de l'exécution, la banque active et la banque où sont les variables de MPX, ce serait assez lourd, bien que plus sécuritaire de gérer ce problème au niveau du module, surtout si on veut rester indépendant du type de Pic. Dans l'exemple proposé, je n'utilise, bien que ce soit juste, qu'une seule banque mémoire
Le module utilise le registre FSR, il est donc nécessaire de le sauvegarder dans la routine d'interruption avant l'appel de MPX_IT_TIMER0. Dans l'exemple donné d'une utilisation de ce module, PCLATH est aussi sauvegardé, c'est parceque le troisième module utilisé en a besoin. Si seul MPX l'était, ce ne serait pas nécessaire
Voici le code de ce module
En rédigeant ce papier, j'ai apporté quelques modification sur la version utilisée dans le premier post qui rend le programme programme donné dans ce post incohérent avec la nouvelle version de MPX. Voici donc ce programme mis à niveau, ce sont des modifications de détail.
Dans ce post, j' avais annoncé en préparer quelques autres sur les ourils utilisés dans ce programme.Voici le deuxième qui commente le module de multiplexage.
Quelques mots d'abord sur ce que j'appelle dans ces posts "module". Il s'agit pour moi d'une présentation d'un bloc de programme et de ses annexes (variables) cherchant à en faciliter la réutilisation dans le contexte le plus large possible. Formellement, c'est un fichier à inclure qui ne contient que des macros. Invoquer l'une d'elles dans son application revient à faire un copier/coller de son contenu dans le code de l'application avec l' avantage supplémentaire de pouvoir passer des paramètres. L'idéal, pour un tel module est qu'il soit totalement indépendant des contextes hard et soft. Hard, sur quel pic s'execute-it, comment les périphériques sont-ils mis en oeuvre. Soft : problèmes de banque mémoire et de pages de code. Il ne devrait être connu que par ses fonctionnalités et sa procédure de mise en oeuvre.
Je décris dans les lignes suivantes le cas de ce module de multiplexage qui prend en charge l'affichage sur 3 à 8 afficheurs 7 segments en n'utilisant que trois ports du processeur qui l'utilise.
Il utilise 3 ports en sortie du processeur qui va le faire tourner. Il serait très restricteur de les imposer à l'utilisateur.
Les 3 macros
Code : Tout sélectionner
; définition des broches utilisées
MPX_Strobe macro port, pin
#DEFINE MPX_IO_Strobe port, pin
endm
MPX_Data macro port, pin
#DEFINE MPX_IO_Data port, pin
endm
MPX_Clock macro port, pin
#DEFINE MPX_IO_Clock port, pin
endm
permettent à l'utilisateur de préciser au module MPX quels sont les ports qu'il a prévu d'utiliser, Le module ne les connaissant que par l'intermédiaire de la constante définie par le #DEFINE.
Ce module, comme la plupart qu'on est amené à écrire, nécessite ses propres variables. Pour les insérer dans l'application, il suffit d'invoquer la macro
MPX_VAR comme on utilise une directive CBLOCK dans son code ; MPASM interdit d'invoquer une macro dans un CBLOCK, la macro développe donc un CBLOCK complet, sans adresse de départ qui est donc celle où on en est arrivé dans le précédent CBLOCK écrit, 0 par défaut. Remarquez que je ne connais pas de moyen avec MPASM de déclarer ces variables privées, par exemple, dans le cas présent, toutes le sont sauf, une MPX_Tampon. C'est une des raisons qui m'ont incité à préfixer leur étiquette de MPX_, a priori, l'utilisateur doit s'interdire d'utiliser ces étiquettes sauf celle qui est explicitement autorisée.
De la même manière, il n'est pas rare que des variables nécessitent une valeur initiale non nulle. C'est le rôle de la macro MPX_INIT_VAR qui d'une part permet de préciser le nombre d'afficheurs mis en oeuvre et d'autre part la fréquence de rafraîchissement. En passant, elle vérifie que l'application a bien défini l'une des constantes précisant le type d'afficheur utilisé (anode ou cathode commune). Le module MPX a bien sûr besoin de le savoir et ce n'est pas à lui d'en décider.
Bien que ce ne soit pas toujours le cas ce module nécessite un "démarrage". C'est le rôle de la macro MPX_InitMultiplex qui va lancer l'interruption timer0 sur laquelle repose le fonctionnement de ce module et qui sera appelée toutes les ms. A partir de ce moment, le tampon est affiché octet par octet, sans que l'utilisateur ait à s'en soucier. Pour modifier l'affichage, il suffit d'écrire dans l'octet du tampon visé la configuration de bits que l'utilisateur veut voir allumés.
C'est bien sûr à l'application de prendre en charge la gestion de l'interruption timer0, en particulier parcequ'elle peut avoir des traitements à faire en parallèle de MPX, avant ou après. Charge à elle d'appeler le module MPX en appelant le sous-programme MPX_IT_TIMER0 toutes les ms (1000micro-cycles)
C'est le rôle de la macro MPX_CODE d'installer dans l'application le code nécessaire à ce module, il doit résider dans une même page de code. Comme on n'y accède que par un call, PCLATH<4;3> sera initialisé sur la bonne page t, a priori, le module n'aura pas à s'en soucier.
Problème de banques mémoire : Si l'application utilise plusieurs banques, les variabless du modules doivent résider dans une même banque. J'ai trouvé préférable de laisser l'application gérer ce problème car elle seule connaît, au moment de l'exécution, la banque active et la banque où sont les variables de MPX, ce serait assez lourd, bien que plus sécuritaire de gérer ce problème au niveau du module, surtout si on veut rester indépendant du type de Pic. Dans l'exemple proposé, je n'utilise, bien que ce soit juste, qu'une seule banque mémoire
Le module utilise le registre FSR, il est donc nécessaire de le sauvegarder dans la routine d'interruption avant l'appel de MPX_IT_TIMER0. Dans l'exemple donné d'une utilisation de ce module, PCLATH est aussi sauvegardé, c'est parceque le troisième module utilisé en a besoin. Si seul MPX l'était, ce ne serait pas nécessaire
Voici le code de ce module
Code : Tout sélectionner
;******************************************************************
;
; NOM: Module Multiplex
; Date création : 15/11/2018
; Circuit: sans objet
; Auteur: JJE
;
;******************************************************************
;
; Historique
; Version 1.0 : 22/11/2018
; Version 1.1 : 26/11/2018
; Version 2.0 : 09/12/2018
; NON compatible avec V1.1
; l'application prend en charge la sauvegarde et la
; restauration des registres spéciaux nécessaires ce qui
; facilitera l'utilisation des IT de plusieurs modules
; Suppression de MPX_EQU ce qu'elle faisait et renvoyé
; dans MPX_INIT_VAR
; L'application prend en charge la variable Timer0VAL
;
;******************************************************************
;
; Ressources utilisées
; 12 octets de données
; 34 octets de programme
; l'interruption timer0
; 2 niveaux de pile + le niveau nécéssaire à l'IT
; 3 ports en sortie du processeur utilisé
;
;******************************************************************
; MACROS
; utiles à ce module
;******************************************************************
; initilise le numéro d'afficheur à utiliser comme afficheur 0
MPX_INITAFFICHEUR macro
ifndef ANODECOMMUNE
ifndef CATHODECOMMUNE
error ""
error "L'une des constantes ANODECOMMUNE ou CATHODECOMMUNE doit être définie"
error ""
endif
endif
ifdef ANODECOMMUNE
ifdef CATHODECOMMUNE
error ""
error "Une seule des constantes ANODECOMMUNE ou CATHODECOMMUNE doit être définie"
error ""
endif
endif
ifdef ANODECOMMUNE
movlw 0xfe
else
movlw 0x01
endif
movwf MPX_masqueAfficheur
endm
; incrémente le numéro d'afficheur actif modulo NbAfficheurs
MPX_PROCHAINAFFICHEUR macro
if NbAfficheurs == 8
ifdef ANODECOMMUNE
bsf STATUS,C
rlf MPX_masqueAfficheur, f
btfsc STATUS, C
goto ici
else
bcf STATUS,C
rlf MPX_masqueAfficheur, f
btfss STATUS, C
goto ici
endif
else
ifdef ANODECOMMUNE
bsf STATUS,C
rlf MPX_masqueAfficheur, f
btfsc MPX_masqueAfficheur, NbAfficheurs
goto ici
else
bcf STATUS,C
rlf MPX_masqueAfficheur, f
btfss MPX_masqueAfficheur, NbAfficheurs
goto ici
endif
endif
MPX_INITAFFICHEUR
local ici
ici
endm
;******************************************************************
; MACROS
; utiles à l'Application utilisant ce module
;******************************************************************
; définition des broches utilisées
MPX_Strobe macro port, pin
#DEFINE MPX_IO_Strobe port, pin
endm
MPX_Data macro port, pin
#DEFINE MPX_IO_Data port, pin
endm
MPX_Clock macro port, pin
#DEFINE MPX_IO_Clock port, pin
endm
; définition des variables de ce modules
MPX_VAR macro
CBLOCK ; Début de la zone des variables du module
MPX_DATA : 0
; compteur utile à déclencher MPX_jobMultiplex
MPX_dojobMultiplex : 1
; variables servant au transfert des valeurs du tampon dans
; les afficheurs
MPX_masqueAfficheur : 1 ; masque de l'afficheur exploité
MPX_NuChiffre : 1 ; rang dans MPX_Tampon du chiffre
; à afficher
MPX_Tampon : 8 ; les 8 octets en cours d'affichage
; variables du ssp de sortie MPX_SetRegWithW appelé
; par MPX_jobMultiplex
MPX_CmptBits : 1 ;compte les bits sortis
MPX_HC4094Temp : 1 ;rangement temporaire de la valeur
; à écrire
MPX_FINDATA :0
ENDC
if (MPX_DATA && 0xf10) != (MPX_FINDATA && 0xf10)
error "La zone de variables de MPX doit résider dans une meme banque."
endif
endm
; initialisation des variables de ce module
MPX_INIT_VAR macro W, NBAFFICHEURS
ifndef ANODECOMMUNE
ifndef CATHODECOMMUNE
error ""
error "L'une des constantes ANODECOMMUNE ou CATHODECOMMUNE doit être définie"
error ""
endif
endif
ifdef ANODECOMMUNE
ifdef CATHODECOMMUNE
error ""
error "Une seule des constantes ANODECOMMUNE ou CATHODECOMMUNE doit être définie"
error ""
endif
endif
dojobMultiplexVAL EQU W ; pour simuler unr IT toutes les
; W*1000 microcycles
; définition du nombre d'afficheurs en service
NbAfficheurs EQU NBAFFICHEURS
; vérification
if NbAfficheurs<2 || NbAfficheurs>8
error "Le nombre d'afficheurs doit être compris ente 3 et 8"
endif
endm
MPX_InitMultiplex macro
; on commence par l'affichage de l'octet 0 du tampon
; sur l'afficheur 0
MPX_INITAFFICHEUR
clrf MPX_NuChiffre
movlw dojobMultiplexVAL
movwf MPX_dojobMultiplex
movwf TMR0
bsf INTCON, PEIE ; autoriser les IT périphériques
bsf INTCON, T0IE ; autoriser l'IT Timer0
endm
MPX_CODE macro
;******************************************************************
; IT Timer0
;******************************************************************
MPX_Début_Code
; doit être appelée par l'application toutes les 1ms
; (1000 micro-cycles)
MPX_IT_TIMER0
decfsz MPX_dojobMultiplex,f
return
;******************************************************************
; MPX_jobMultiplex
;******************************************************************
; MPX_dojobMultiplex s'annule toutes les 4ms par le ssp d'IT Timer0
; active l'afficheur défini par MPX_masqueAfficheur
; et lui fait afficher l'octet MPX_NuChiffre du tampon
; transfère les bonnes valeurs dans les HC4094
; MPX_masqueAfficheur et MPX_NuChiffre sont mis à jour
; en vue du prochain affichage
; consomme environ 460 microcycles
;MPX_jobMultiplex
movlw dojobMultiplexVAL
movwf MPX_dojobMultiplex
bcf MPX_IO_Strobe
movf MPX_masqueAfficheur, w
call MPX_SetRegWithW
MPX_PROCHAINAFFICHEUR
movlw MPX_Tampon
addwf MPX_NuChiffre,w
movwf FSR
movf INDF,w
call MPX_SetRegWithW
bsf MPX_IO_Strobe
; incrémente MPX_NuChiffre modulo NbAfficheurs
incf MPX_NuChiffre,f
movf MPX_NuChiffre, w
sublw NbAfficheurs
btfsc STATUS, Z
clrf MPX_NuChiffre
return
;******************************************************************
; ROUTINES DE SORTIE
;******************************************************************
; transfère le contenu de W dans le HC4094
; entrée :
; W valeur à transférer
; sortie :
; le registre est chargé mais le Strobe n'a pas été fait
; pour permettre d'utiliser ce sous-propgramme
; pour charger plusieurs registres chaînés.
; W n'est pas modifié
; variables locales utilisées
; MPX_HC4094Temp
; MPX_CmptBits
; variables globales utilisées
; néant
; durée
; 186 cycles en comptant l'appel et le retour
MPX_SetRegWithW
movwf MPX_HC4094Temp ; 2
movlw .8 ; nombre de bits à sortir
movwf MPX_CmptBits ; 3
MPX_SetRegWithW_1
rlf MPX_HC4094Temp, F ; 4 + 20*nb bits sortis
btfss STATUS, C ; 5 + 20*nb bits sortis
goto MPX_SetRegWithW_2 ; 6 + 20*nb bits sortis
bsf MPX_IO_Data ; 7 + 20*nb bits sortis
goto MPX_SetRegWithW_3 ; 8 + 20*nb bits sortis
MPX_SetRegWithW_2
bcf MPX_IO_Data ; 8 + 20*nb bits sortis
nop ; 9 + 20*nb bits sortis pour
; équilibrer les deux cas
MPX_SetRegWithW_3
bsf MPX_IO_Clock ; 10 + 20*nb bits sortis
goto $+1 ; 11 + 20*nb bits sortis
goto $+1 ; 13 + 20*nb bits sortis
bcf MPX_IO_Clock ; 15 + 20*nb bits sortis
goto $+1 ; 16 + 20*nb bits sortis
goto $+1 ; 18 + 20*nb bits sortis
decfsz MPX_CmptBits, F ; 20 + 20*nb bits sortis
goto MPX_SetRegWithW_1 ; 21 + 20*nb bits sortis
return ; 182
MPX_Fin_Code
if (high(MPX_Fin_Code) && 0xf8) != (high(MPX_Début_Code) && 0xf8)
error ""
error "Le code du module MPX doit résider dans une même page"
error ""
endif
endm
En rédigeant ce papier, j'ai apporté quelques modification sur la version utilisée dans le premier post qui rend le programme programme donné dans ce post incohérent avec la nouvelle version de MPX. Voici donc ce programme mis à niveau, ce sont des modifications de détail.
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 : 14/12/2018
; - suppression du relais relais_DCF77_DébutTrame qui ne
; faisait rien et était resté là par erreur
; - compléter quelques commentaires
; Version 2
; - Prise en charge de TIMER0VAL
; - l'invocation de MPX_EQU et supprimée
; - MPX_INIT_VAR prend en charge ce qu'elle faisait
; - prise en compte du changement de MPX_InitMultiplex
; de sous-programme en macro
; - ajouté le comptage des pertes de synchronisation
;******************************************************************
;
; 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
TIMER0VAL EQU .9
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
cmpt_Perte_Synchro : 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
TamponPerte_Synchro 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
dojob6 EQU 6 ; set dès que DCF77 dit être
; synchronisé
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 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
; préciser la durée en ms d'affichage des afficheurs.
; pour une fréquence de 4MH, prescaler de 4
; pour 8 afficheurs,.4 est bon pour le premier
; .8 est le nombre d'afficheurs utilisés
MPX_INIT_VAR .4, .8
; 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
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
bsf dojob, dojob6
return
relais_DCF77_jobPerteSynchro
bcf dojob, dojob5
incf cmpt_Perte_Synchro, f
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
goto affiche3_2
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
affiche3_2
btfss dojob, dojob6
; s'il ne l'a pas encore été, ne rien faire d'autre
return
; s'il l'a déjà été, afficher le nombre de perte de synchro
SORT8 cmpt_Perte_Synchro, TamponPerte_Synchro
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 43 invités