Bienvenue aux nouveaux arrivants sur FantasPic !

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

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

Modérateur : mazertoc

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

#1 Message par JJE » jeu. 13 déc. 2018 05:25

Le sujet lancé par adede5000 il y a quelque temps m'avait plu et je m'y suis collé. Pour rappel, pas mal de posts sur ce sujet en faisant une recherche de DCF77 sur ce site.
Ayant eu quelques soucis j'ai décidé de regarder de plus près les signaux reçus et j'ai écrit le programme donné ci dessous qui affiche successivement toutes les 5 secondes, sur 8 afficheurs 7 segments en hexa
toutes les durées sont en ms (ou plutôt en kilo-cycles)
[list=]
la durée min du pulse interprété comme un 0 (strictement moins de 150ms)
la durée max du pulse interprété comme un 0 (strictement moins de 150ms)
la durée min du pulse interprété comme un 1 (plus de 150ms)
la durée max du pulse interprété comme un 1 (plus de 150ms)
[/list]
puis
[list=]
l’intervalle min entre deux fronts montants (sur 4 chiffres)
l’intervalle max entre deux fronts montants (sur 4 chiffres)
[/list]
puis l'heure, jour, heure, minutes (en décimal)
puis la date jour, quantième, mois, année (en décimal)

Si une perte de synchro ou une erreur de parité est détectée, les deux derniers affichages ne se font pas, ils sont remplacés par des "-". Ce qui m'a permis de constater que cela arrivait . J'ai même envie d'ajouter un compteur de tels événements ce ne sera pas pour cette version

J'ai mis un filtre bas à 32 sur la durée des pulses, tout pulse de durée strictement inférieur est ignoré.

Voici les résultats obtenus sur une longue session plus de quinze heures

Min d'un pulse interprété comme un bit 0 : 0x20 (32), on ne pouvait pas faire moins
Max d'un pulse interprété comme un bit 0 : 0x95 (149), on ne pouvait pas faire plus
Min d'un pulse interprété comme un bit 1 : 0x96 (150), on ne pouvait pas faire moins
Max d'un pulse interprété comme un bit 1 : 0xFF (255), on ne pouvait pas faire plus

C'est assez décevant, on a bien sûr des résultats plus intéressants sur des sessions plus courtes

Pour l'intervalle inter pulses , c'est guère mieux
Min d'un intervalle inter-pulse : 0x100 (256)
Max d'un intervalle inter-pulse : 0x875 (1474)

Ce programme tourne sur un 12F675, c'est un de mes challenges, 8 7 segmenrts et ce récepteur sur ce petit pic et il me reste encore 2 pins :sifflotte:

Je crois qu'il faudrait améliorer le filtrage mais je ne sais pas trop comment. Si quelqu'un a une idée je suis preneur.

Pour ce qui est du programme, il faut préciser qu'il utilise 3 fichier à inclure, j'appelerai ça des modules, qui feront l'objet de posts à venir
l'un est un ensemble de macros facilitant le codage et améliorant la lisibilité de test dans un programme
un deuxième s'occupe de l'affichage, l'utilisateur se contente d'écrire dans l'un des 8 octets associés aux 8 afficheurs la configuration de segments qu'il souhaite allumer. Ce module accepte des anodes ou cathode commune pour les 7 segments
Le troisième s'occupe du décodage des signaux CDF77
Le programme gère lui-même l'IT GPIO pour calculer les valeurs nécessaires aux deux premiers affichages, mais utilise le module DCF77 pour les valeurs nécessaires aux deux derniers.

Je pense avoir été suffisamment généreux dans les commentaires pour ne pas en ajouter ici mais si des questions se posent .../...
Malgrè ses 900 et quelques lignes, il ne fait que 430 octets (sans les modules)

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 :
;
       Version1.0 :  12/12/2018
;
;******************************************************************
;
;
    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
;
;******************************************************************


        #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-= 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
relais_DCF77_DébutTrame
    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


Tout a été réalisé sur platine d'essais, le schéma sera donné dans le post qui parlera de la gestion de l'affichage, j'espère avant 2019 mais pas sur je vais entrer dans une période mouvementée.
Cordialement

JJE

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

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

#2 Message par JJE » jeu. 13 déc. 2018 05:39

Complément
Par respect pour mes pauvres yeux, ce programme est mis en page pour une fonte écran en 26 points et imprimante 12 points pour un A4 en mode portrait
Cordialement

JJE

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

Retour sur DCF77
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#3 Message par paulfjujo » jeu. 13 déc. 2018 11:07

bonjour JJE,

je me posais la question, à savoir si le multiplexage d'affichage ne fout pas la pagaille
sur le signal DCF77 ?
(je n'ai pas ce type de module pour faire un test .)
mais je sa
Aide toi, le ciel ou FantasPic t'aidera

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

#4 Message par JJE » jeu. 13 déc. 2018 18:35

Bonsoir paulfjujo,
quelques chiffres pour te rassurer :
le programme de multiplexage est appelé sous IT timer0 toutes les 1000 micro-cycles (1ms environ) il appelle le sous-programme qui fait le travail une fois sur 4, avec 8 afficheurs ça ne pose pas de problèmes de clignotement, on tourne à un pu plus de 31 images par seconde. Le sous-programme lui même consomme environ 460 micro-cycles, le temps nécessaire au remplissage de 2 registres à décalage 8 bits. Comme le module DCF77 travaille sur la même IT, il lui reste largement le temps pour incrémenter un compteur, même de 16 bits comme c'est le cas dans la phase de synchronisation.
Cordialement

JJE

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

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

#5 Message par JJE » dim. 16 déc. 2018 10:19

Bonjour à tous,
Comme dit ici, j' ai complété le programme cité ci-dessus pour lui faire afficher le nombre de pertes de synchro du module DCF77. Sur une session d'une douzaine d'heures, j'arrive à 0x44 (68), c'est beaucoup je trouve. Cette nouvelle session confirme les mauvais résultats des différentes mesures effectuées. Dommage que adeade5000 soit aux abonnés absents, il semble que ce soit le seul de ce forum qui s'intéresse à la gestion du DCF77 :cry:
Cordialement

JJE

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

Retour sur DCF77
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#6 Message par paulfjujo » dim. 16 déc. 2018 20:27

JJE a écrit :Bonsoir paulfjujo,
quelques chiffres pour te rassurer :
le programme de multiplexage est appelé sous IT timer0 toutes les 1000 micro-cycles (1ms environ) il appelle le sous-programme qui fait le travail une fois sur 4, avec 8 afficheurs ça ne pose pas de problèmes de clignotement, on tourne à un pu plus de 31 images par seconde. Le sous-programme lui même consomme environ 460 micro-cycles, le temps nécessaire au remplissage de 2 registres à décalage 8 bits. Comme le module DCF77 travaille sur la même IT, il lui reste largement le temps pour incrémenter un compteur, même de 16 bits comme c'est le cas dans la phase de synchronisation.


je ne parlais pas du temps MCU necessaire pour gerer le multiplexage, mais plutot
des emissions "parasites" CEM dues à la commutation de courant vers les afficheurs.
Rayonnement pouvant interferer avec la frequence porteuse de reception du signal DCF77

ou la presence proche d'un moniteur video PC ...
Aide toi, le ciel ou FantasPic t'aidera

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

#7 Message par JJE » lun. 17 déc. 2018 16:41

Ok, j'avais mal compris la question,
Globalement, c'est assez satisfaisant mais les chiffres données dans ce post laissent à penser que ce devrait être amélioré. Depuis, j'ai fait afficher, dans la période d'une perte de synchro, le nombre de pertes depuis le début de session, je n'ai pris qu'un compteur 8 bits et en, peut-être 24h., il déborde. Ce n'est pas très grave pour ce que je voulais faire mais pour une horloge, c'est plus fâcheux, la reprise en main pouvant atteindre 2'. Dommage que adede5000 ne réponde plus.
Reste à savoir si c'est le multiplexage ou l'environnement :?:
Cordialement

JJE

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

Retour sur DCF77
adede5000
Débutant
Débutant
Messages : 62
Âge : 60
Enregistré en : août 2017
Localisation : Sart Saint Laurent (BE)

#8 Message par adede5000 » mer. 26 déc. 2018 20:07

JJE a écrit :Bonjour à tous,
Comme dit ici, j' ai complété le programme cité ci-dessus pour lui faire afficher le nombre de pertes de synchro du module DCF77. Sur une session d'une douzaine d'heures, j'arrive à 0x44 (68), c'est beaucoup je trouve. Cette nouvelle session confirme les mauvais résultats des différentes mesures effectuées. Dommage que adeade5000 soit aux abonnés absents, il semble que ce soit le seul de ce forum qui s'intéresse à la gestion du DCF77 :cry:


Bonjour JJE,

Je suis de retour et je suis prêt à t'aider ou du moins te renseigner selon mes modestes connaissances. :wink:

adede5000

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

#9 Message par JJE » ven. 28 déc. 2018 18:34

Bonjour adede50000, et tous,
Ayant rencontré quelques problèmes dans mes premiers pas avec le DCF77, j'ai écrit le programme décrit ci-dessus.
J'ai acheté sur le site que tu avais donné le même décodeur que le tien, les actuelles versions sont alimentées en 3.3V mais il ne semble pas y avoir d'importance sauf à faire attention, une étourderie m'en a coûté un.
le programme mesure la durée des pulses et affiche les min et max des pulses interprétés comme des bits à 0 et ceux des bits interprétés comme des 1. j'ai choisi le seuil de différenciation égal à 150ms. Un tout petit progrès par rapport à ce qui est écrit plus haut, le max des bits à 1 n'est "plus que" de 0xF8 (248), c'est quand même loin des 200ms attendues.Les autres résultats sont aussi aberrants.
de la même manière, le programme calcule la durée qui sépare deux fronts montants (en éliminant le bit 59), et affiche le min et le max, je trouve 256ms et 1515ms, assez loin des 1000ms attendues. Ces max et min sont calculés sur plusieurs jours
Ensuite, il affiche l'heure puis la date. les 4 infos sont affichées les unes après les autres toutes les 5".
Ces résultats peuvent expliquer les pertes de synchro fréquentes observées (ou les erreurs de parité que je gère comme des pertes de synchro). Je ne te donne pas le nombre car je n'ai mis en oeuvre qu'un compteur 8 bits certainement beaucoup trop court pour la situation
Ma question toute simple est :
As-tu observé de telles pertes de synchro et/ou as-tu une idée d'où elles peuvent provenir ?
C'est dommage parce que, à part ça, tout marche bien, ce n'est en fait pas très gênant mais la reprise en main pouvant atteindre 2', c'est fâcheux quand on veut lire l'heure.
Cordialement

PS réponse tardive par overbooking de fête de famille.
Cordialement

JJE

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

Retour sur DCF77
adede5000
Débutant
Débutant
Messages : 62
Âge : 60
Enregistré en : août 2017
Localisation : Sart Saint Laurent (BE)

#10 Message par adede5000 » sam. 29 déc. 2018 11:55

Bonjour JJe et le forum,

J'ai examiné le programme ASM qui je l'avoue est costaud et me déroute mais si le fonctionnement est bon,c'est l'essentiel.
Un schéma serait le bienvenu et lorsque le temps te le permettra de le publier,j'y verrai certainement plus clair.
En ce qui concerne mon horloge,les pertes de synchro sont relativement rares mais les conditions sont assez strictes.
J'alimente avec un bloc secteur à découpage réglable de 3 à 12V;curieusement,la position 12V est la seule qui me donne un résultat stable.Pourquoi ?
L'alimentation de l'horloge se fait en 5V via un 7805.Un condo de 100µF en entrée du régulateur et un condo de 100nF en sortie.
L'antenne doit être dégagée d'au moins quelques centimètres du circuit de l'horloge et bien entendu l'orientation de l'antenne doit être optimale.
Eviter la proximité immédiate d'appareils qui pourraient rayonner.
L'environnement extérieur peut également perturber le fonctionnement;les ondes longues sont très sensibles aux parasites engendré par des machines mal déparasitées même éloignées.
Dans la config du 12F675,je remarque que tu utilises l'oscillateur interne et là,j'ai un doute pour la précision du calcul des bits reçus;pour ma part,j'utilise un quartz de 4MHz.
Il faut rester conscient qu'une horloge purement DCF77 ne saurait être aussi stable qu'une horloge conventionnelle mais le concept me plait.La mienne fonctionne depuis le 06/04/2018.
La dernière modification que j'avais apportée a été de monter l'antenne sur un jack de 3.5 mm afin de pouvoir l'orienter selon l'endroit où je la dispose.
Voilà.Donc,je pense qu'il est possible de régler au mieux ton problème de perte de synchro et je reste à ton écoute.

Cordialement
adede5000


Retourner vers « Langage ASM »

Qui est en ligne

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