Faire une horloge avec un PIC
Répondre à la discussion
Affichage des résultats 1 à 28 sur 28

Faire une horloge avec un PIC



  1. #1
    invitef1e74cb6

    Smile Faire une horloge avec un PIC


    ------

    Bonjour à tous. Je souhaite réaliser une horloge grâce à mon PIC 16F877A. J'aimerai avoir vos avis et vos suggestions d'améliorations sur ce programme.

    Je programme mon pic en langage C avec mikroC.

    Il est cadencé avec un quartz de 8Mhz. Cela donne 2 millions de cycles par seconde. On déduit donc qu'un cycle d'horloge dure 500ns. A partir de cela on sait que l'on aura une interruption toutes les 128µs. Jusque la je pense avoir bon.

    On utilise TMR0 en timer donc on met le bit T0CS à 0. Ensuite je choisi 32 comme prédiviseur donc je met le bit PS2 à 1.
    Ce qui nous donne:
    * une interruption toute les 4096µs
    * 244 interruptions nous donnerons une base de temps de 999424µs
    * il nous manque donc 576µs

    Cela est-il correct?

    Voici mon programme:

    unsigned char cpt=0; //compteur d'interruption
    unsigned char sec=0; //variable pour stocker les secondes
    unsigned char txt[7]; // variable pour afficher les secondes

    void interrupt() {
    cpt++; // incrémentation du compteur de dépassement
    INTCON.F2=0; //on remet à 0 le bit TMROIF
    }


    int main (void){

    INTCON = 0xA0; //GIE à 1, PEIE à 1, TMROIE à 1
    OPTION_REG = 0x04; //tmr0 réglé en oscillation interne et prédiviseur=32
    LCD_Init(&PORTD); // Iinitialisation de l'ecran LCD connecté au portD
    LCD_Cmd(LCD_CLEAR); // ecran lcd effacer
    LCD_Cmd(LCD_CURSOR_OFF); // pas de curseur d'afficher


    do {
    if (cpt>243) { // cpt > 243 ??
    IntToStr(sec,txt); // conversion de sec (int) en chaine de caracteres
    LCD_Out(1,1,txt); // affichage des secondes
    sec++; // on incrémente les secondes
    cpt=0; // remise à 0 du compteur
    }

    } while(1);

    return (0);
    }

    Voila! Donc pour chaque seconde on a une erreur de -576µs. Il est possible de la corriger en ajoutant par exemple une seconde au bout d'un certain temps. Sinon y a t-il un autre moyen pour corriger cela? Y a t-il autre chose a prendre en compte (qui modifie la précision)?

    Merci a ceux qui ont suivi.

    -----

  2. #2
    Gérard

    Re : Faire une horloge avec un PIC

    Bonjour,
    Je vois 2 options :
    1_ RTC en I2C + quartz 32,768KHz
    2_ quartz de 32,768KHz sur l'entrée Timer1

    Dans les 2 cas, il n'y a que la dérive du quartz qui génèrera des erreurs (faibles).

  3. #3
    Gérard

    Re : Faire une horloge avec un PIC


  4. #4
    invitef1e74cb6

    Re : Faire une horloge avec un PIC

    Ok pour le DCF 77 et/ou RTC mais j'aimerai dans un premier temps faire cette horloge uniquement avec le PIC de la manière la plus optimum.

  5. A voir en vidéo sur Futura
  6. #5
    invitea3c675f3

    Re : Faire une horloge avec un PIC

    Pourquoi ne pas pendre le 50Hz du réseau comme référence, il n’est pas diaboliquement stable (aux heures de point la fréquence baisse un peu mais est rattrapée la nuit) Je ne sais pas trop sur quoi la fréquence moyenne journalière du réseau est pilotée, mais on peut sans grande erreur être sur que dans 24H il y aura 4320000 cycles (qui a jamais remis à l’heure son vidéo?).
    Si tu veux de la stabilité, fais-toi une PLL pilotée sur le réseau avec une constante de temps (faite par ton PIC) de 24H.

  7. #6
    invitef1e74cb6

    Re : Faire une horloge avec un PIC

    Citation Envoyé par louloute/Qc Voir le message
    Pourquoi ne pas pendre le 50Hz du réseau comme référence, il n’est pas diaboliquement stable (aux heures de point la fréquence baisse un peu mais est rattrapée la nuit) Je ne sais pas trop sur quoi la fréquence moyenne journalière du réseau est pilotée, mais on peut sans grande erreur être sur que dans 24H il y aura 4320000 cycles (qui a jamais remis à l’heure son vidéo?).
    Si tu veux de la stabilité, fais-toi une PLL pilotée sur le réseau avec une constante de temps (faite par ton PIC) de 24H.

    Cela pourrait être très interessant mais mon but est d'utiliser cette horloge dans un systeme embarqué. En effet je dois concevoir un parfumeur d'ambiance programmable. (projet pédagogique mettant en oeuvre un pic...)

  8. #7
    Gérard

    Re : Faire une horloge avec un PIC

    Citation Envoyé par Oxion Voir le message
    Ok pour le DCF 77 et/ou RTC mais j'aimerai dans un premier temps faire cette horloge uniquement avec le PIC de la manière la plus optimum.
    Donc post2, idée 2 --> simple, pas cher, efficace
    TMR1 est un 16 bit soit 65536 cas.
    Si tu laisses le QZ sur l'entrée TMR1 sans rien faire (prévoir l'interruption de TMR1 quand même ), tu auras débordement toutes les 2 secondes.
    Si tu veux une interruption toutes les secondes, il faut à chaque IRQ, charger TMR1H avec la valeur 128d ou 80h ou 1000 000b.

  9. #8
    invitef1e74cb6

    Re : Faire une horloge avec un PIC

    Bonjour Gérard. Ton idée 2 est celle qui me convient le mieux. Pour utiliser le timer1 j'ai configurer les registres suivants:

    INTCON = 0xC0; //GIE à 1 et PEIE à 1

    PIE1 =0x01; //TMR1IE à 1

    T1CON = 0x0F; //TMR1ON à 1, TMR1CS à 1, \T1SYNC à 1 et T1OSCEN à 1.

    Cela te semble t'il correct?

  10. #9
    Gérard

    Re : Faire une horloge avec un PIC

    Citation Envoyé par Oxion Voir le message
    Bonjour Gérard. Ton idée 2 est celle qui me convient le mieux. Pour utiliser le timer1 j'ai configurer les registres suivants:

    INTCON = 0xC0; //GIE à 1 et PEIE à 1

    PIE1 =0x01; //TMR1IE à 1

    T1CON = 0x0F; //TMR1ON à 1, TMR1CS à 1, \T1SYNC à 1 et T1OSCEN à 1.

    Cela te semble t'il correct?
    Avec ces valeurs pour INTCON et PIE1, tu n'utilises que l'interruption de TMR1.
    Si tu mets un Qz sur l'entrée de TMR1, c'est bon.
    Il faudra maintenant écrire la routine d'interruption.
    Si tu as une question, n'hésite pas.

  11. #10
    invitef26bdcba

    Re : Faire une horloge avec un PIC

    Salut,

    Sinon, autre solution sans quartz annexe mais avec le timer2, si le programme ne sert qu'a faire une horloge.

    Prédiviseur timer2 à 4 -> compte toutes les 2µsec
    diviseur inttimer2 à 10 -> une interruption tous les dix débordement.
    PR2 initialisé à 250 -> soit une interruption toutes les 5mSec (2uSec x 250 x 10)

    Ensuite initialisation du PWM et des INT pour pouvoir utiliser PR2, compter 200 interruptions et on se retrouve avec exactement 1 seconde en négligeant la dérive du quartz.

    David.

  12. #11
    RISC

    Re : Faire une horloge avec un PIC

    Bonjour,

    Pour éviter toute erreur du à la reprogrammation d'un timer à chaque interruption, il existe 2 solutions mentionnées dans les posts précédents :

    1/ TIMER1
    Utiliser un quartz 32768 Hz et interruption toutes les 2s. L'astuce est que l'horloge est divisée par 65536 et donc aucun rechargement du timer1 = aucune erreur.
    Eventuellement toutes les secondes mais il faut alors faire TRES attention au bug du timer1 dans tous les PIC 8 bits car il est la cause de la dérive des horloges temps-réel...voir errata sheet, la solution est très bien expliquée.

    2/ TIMER2
    C'est le meilleur TIMER à utiliser car il est du type auto-reload donc aucune erreur lors du rechargement de la valeur d'origine car c'est fait par HW.
    Pour une horloge temps-réel précise à partir de l'oscillateur principal non dépendante du temps d'exécution du soft, c'est la meilleure méthode.

    a+

  13. #12
    invitef1e74cb6

    Re : Faire une horloge avec un PIC

    Mon programme ne sert pas juste a faire une horloge mais il a besoin de celle-ci pour fonctionner car tout est basé autour d'elle. Merci à vous tous pour vos différentes solutions.
    J'utilise donc le TIMER1 avec un quartz de 32,768kHz.

    J'ai connecté mon quartz aux broches T1OSO T1OSI puis jai connecté mes 2 condensateurs (33pF). Mais cela ne fonctionne pas. Le comptage ne démarre pas. Voici le programme:

    unsigned char sec=0, cpt=0;
    unsigned char txt[7];

    void interrupt() {

    sec++;
    PIR1.TMR1IF = 0; //on remet à 0

    }

    int main (void){
    INTCON = 0xC0; //GIE à 1, PEIE à 1
    PIE1 =0x01; //TMR1IE à 1
    T1CON = 0x0F;
    PIR1.TMR1IF = 0;

    LCD_Init(&PORTD); // Iinitialisation de l'ecran LCD connecté au portD
    LCD_Cmd(LCD_CLEAR); // ecran lcd effacer
    LCD_Cmd(LCD_CURSOR_OFF); // pas de curseur d'afficher

    do {
    IntToStr(sec, txt);
    Lcd_Out(1,1,txt);

    } while(1);
    }

  14. #13
    invitef26bdcba

    Re : Faire une horloge avec un PIC

    Salut,

    Citation Envoyé par Oxion Voir le message
    Mon programme ne sert pas juste a faire une horloge mais il a besoin de celle-ci pour fonctionner car tout est basé autour d'elle.
    Oui, je l'avais compris...

    Mais pour utiliser le timer2 comme compteur avec une valeur de préchargement, il ne faut pas devoir utiliser le module PWM du pic, c'est juste cela que je voulais te dire par le fait que "tu ne fais qu'une horloge".

    David.

  15. #14
    invitef1e74cb6

    Re : Faire une horloge avec un PIC

    Citation Envoyé par DavidDB Voir le message
    Salut,



    Oui, je l'avais compris...

    Mais pour utiliser le timer2 comme compteur avec une valeur de préchargement, il ne faut pas devoir utiliser le module PWM du pic, c'est juste cela que je voulais te dire par le fait que "tu ne fais qu'une horloge".

    David.
    Aucun problème . Merci de tes conseils qui me sont très utiles et qui me permettent d'accroitre mes connaissances sur les pics.

  16. #15
    RISC

    Re : Faire une horloge avec un PIC

    Oxion,

    Il faut faire les choses dans un ordre différent :
    a/ initialiser le Timer1 (timer1 arrêté)
    b/ nettoyer le flag d'interruption et initialiser les interruptions
    c/ lancer le timer1

    De plus il faut aussi bien faire attention aux bits de configuration. Je te conseille de les initialiser dans le programme principal :

    exemple (en Hitech C) :
    __CONFIG( HS & WDTDIS & PWRTDIS & BORDIS & LVPDIS & WRTEN & UNPROTECT );

    Cà donne qqchose comme (C Hitech) :

    int main (void){
    TMR1ON = 0; // arrêter Timer1
    TMR1H = 0x00; //charger TMR1H/L à 0000 (1 INT / 2s)
    TMR1L = 0x00; //charger TMR1H/L à 0000 (1 INT / 2s)

    // prescaler 00, OSCEN=1, T1SYNC~=1, TM1CS = 1 (ext), TIM1=0 (OFF)
    T1CON = 0x0E ;

    TMR1IF = 0; // nettoyer flag interruption TMR1
    TMR1IE = 1; // autoriser interruption TMR1
    PEIE = 1; // autoriser Peripheral Interrupts
    GIE = 1; // autoriser Global Interrupts

    TMR1ON = 1; // lancer le timer1

    Attention, dans mon exemple il faudra incrémenter 2 fois dans l'interruption car elle aura lieu toutes les 2secondes. Si tu veux toutes les secondes, il faudra recharger TMR1 à 0x8000 dans l'interruption en tenant compte de l'erratasheet :
    http://ww1.microchip.com/downloads/e...Doc/80329a.pdf

    Met un point d'arrêt sur ton interruption pour voir si tout ce passe bien.

    Quel compilateur utilises-tu ?
    Quel outil de développement (ICD2,...) ?

    a+

  17. #16
    invitef1e74cb6

    Re : Faire une horloge avec un PIC

    Désolé pour l'absence mais j'etais très occupé ces derniers temps. Alors comme compilateur j'utilise MikroC qui, je trouve, fonctionne très bien (pas de plantage ni rien...) avec une platine easypic4.

    J'ai essayer de mettre en pratique ce que tu m'as conseillé mais cela ne fonctionne toujours pas . En effet on dirait que j'ai une interruption environ toute les 15 sec (en moyenne cela varie un peu). Je ne sais pas si cela est dû a du bruit ou autre chose. J'ai essayer de changer mon quartz mais c'est pareil .

    voici mon programme:

    unsigned char sec=0;


    void interrupt() {
    if (PIR1.F0==1){
    sec++;
    sec++; // incrémentation du compteur
    PIR1.F0 = 0; //on remet à 0 le bit TMROIF
    }
    }



    void main (void){
    INTCON = 0xC0; //GIE à 1, PEIE à 1
    T1CON = 0x0E; //T1oscen, T1sync,TMR1CS à 1 et timer arreter
    PIR1.F0 = 0; //flag remis à zero
    TMR1H = 0x00;
    TMR1L = 0x00;
    PIE1 =0x01; //TMR1IE à 1
    T1CON = 0x0F; //timer lancé

    LCD_Init(&PORTD); // Iinitialisation de l'ecran LCD connecté au portD
    LCD_Cmd(LCD_CLEAR); // ecran lcd effacer
    LCD_Cmd(LCD_CURSOR_OFF); // pas de curseur d'afficher

    do
    {
    //gestion de l'affichage du temps
    Lcd_Chr(1,1,(sec/100)+48);
    Lcd_Chr(1,2,(sec/10)+48);
    Lcd_Chr(1,3,(sec%10)+48);

    } while(1);
    }

  18. #17
    RISC

    Re : Faire une horloge avec un PIC

    Oxion,

    Mon exemple est basé sur l'oscillateur à 32.768 kHz.

    Relis bien mon post ci-dessus....Fais les choses dans l'ordre que j'ai indiqué

    et surtout ne confond pas les Timer 0 et 1 ....

    Le quartz 32768 Hz est branché sur le TIMER1 et pas sur le TIMER0. Corrige ton programme principal ET ta routine d'interruption qui apparemment s'occupent du mauvais TIMER (flag d'interruption)...

    a+
    Dernière modification par RISC ; 12/01/2008 à 14h45. Motif: correction

  19. #18
    invitef1e74cb6

    Re : Faire une horloge avec un PIC

    RISC,

    Ton exemple qui est basé sur l'oscillateur à 32.768 kHz correspond exactement à mes quartzs de cette même valeur. Ce quartz étant connecté aux pattes de RC0/T1OSO/T1CKI et RC1/T1OSI/CCP2 accompagné de 2 condensateurs (avec la valeur donnée dans datasheet qui est de 33pF pour un quartz de 32Khz).

    J'ai relu ton post et placé les instructions dans l'ordre que tu as donné: aucun changement.

    Pour la routine d'interruption il s'agit bien du bon flag. C'est une erreur de commentaire du à la recopie. Le bit 0 du registre PIR1 (traduit par PIR1.F0) correspond bien à TMR1IF.

    Je n'arrive pas à trouver d'où cela peut venir. En plus chose étrange si je change le quartz qui cadence le PIC (8MHz par un 16MHz) les interruptions sont plus rapide.

    Tu as une idée?

    Voici le programme modifié:

    void main (void){
    T1CON.F0 = 0; //Timer 1 arrete => TMR1ON = 0
    TMR1H = 0x00; //initialisation de TMR1H/L à 0
    TMR1L = 0x00;
    T1CON = 0x0E; //T1oscen, T1sync,TMR1CS à 1 et timer arreter
    PIR1.F0 = 0; //flag remis à 0
    PIE1.F0 = 1; //interruption timer1 autorisée
    INTCON.F6 = 1; //Peripheral Interrupt autorisée
    INTCON.F7 = 1; //Global Interrupt autorisée
    T1CON.F0= 1; //timer 1 lancé

  20. #19
    RISC

    Re : Faire une horloge avec un PIC

    Salut,

    D'après ce que tu dis, il y a toujours un problème de sélection d'oscillateur pour le TIMER1 ou dans la routine d'interruption. Le changement d'oscillateur principal ne devrait provoquer aucune différence sur la fréquence des interruptions.

    Utilises-tu un ICD2 pour déboguer ?
    Si oui, ouvre une fenêtre de WATCH, sélectionnes INTCON, PIR1, PIE1 et met un point d'arrêt dans la routine d'interruption et regardes les valeurs des registres pour voir si tu as bien la configuration prévue.
    Vérifie en particulier le bit TMR1CS.

    Une autre chose. : mets un else dans l'interruption avec une boucle sans fin dedans pour être sur que tu ne rentres pas en interruption par une autre source

    Peux-tu faire voir ton code d'initialisation des bits de configuration ?

    Je te propose de mettre l'equivalent de cela (en Hitech C) :
    __CONFIG( XT & WDTDIS & PWRTDIS & BORDIS & LVPDIS & WRTEN & UNPROTECT );

    a+

    PS : j'ai un peu de mal à lire ton code au niveau registres et flags car j'utilises le compilateur C Hitech...

  21. #20
    invitef1e74cb6

    Re : Faire une horloge avec un PIC

    Citation Envoyé par RISC Voir le message
    PS : j'ai un peu de mal à lire ton code au niveau registres et flags car j'utilises le compilateur C Hitech...
    Il y a aucun problème. Je comprend tout à fait car je suis dans le même cas quand je lis tes lignes de codes .

    Je vais essayer de déboguer par l'ICD2 et faire les vérifications que tu proposes.

  22. #21
    invitef1e74cb6

    Re : Faire une horloge avec un PIC

    J'ai debugué. Le bit TMR1CS est bien à 1 et sa valeur ne change pas. Pour le reste tout semble ok. J'ai aussi fait ce que tu m'as conseillé pour l'interruption mais elle fonctionne aussi.
    Pour ma part le code d'initialisation est générée à partir des options que je coche (cf l'image jointe). J'ai un peu de mal à trouver les correspondances avec ton code car les noms ne sont pas identiques. Moi j'utilise l'oscillateur en HS (quartz 8MHz).



    La configuration te semble correcte? Il s'agit de celle par défaut.

  23. #22
    RISC

    Re : Faire une horloge avec un PIC

    Salut,

    La seule chose ( à laquelle je pense) et qui reste à vérifier est que tes initialisations sont faites dans les bonnes banques RAM.
    Ton code ne s'ocupe pas de changer les banques. J'imagine donc quand tu programmes les registres SFR du micro que ton compilateur génère la sélection des banques ou se trouve chaque registre.
    Fais du pas à pas en mode disassembly et vérifie la banque et les registres.

    La note d'application ci-dessous montre comment faire une interruption toutes les secondes plutot que toutes les 2 secondes :

    http://ww1.microchip.com/downloads/e...tes/00649a.pdf

    a+

  24. #23
    RISC

    Re : Faire une horloge avec un PIC

    Re,

    De même vérifie que ton compilateur C sauvegarde (au début) et restaure (à la fin) du code de l'interruption W, STATUS, PCLATH (voir le mode disassembly listing dans le menu VIEW).

    a+

  25. #24
    invite265e7c0b

    Re : Faire une horloge avec un PIC

    bonjour

    voila j'ai besoin d'aide sur ce sujet vu que je dois faire une horloge avec un pic pour mon projet tute

    ma question est la suivante : pourquoi un quartz de 8Mhz Cela donne t-il 2 millions de cycles par seconde?
    vu qu'un cycle correspond a une période donc 1 seconde correspond a 8 millons de cycles d'horloge non?
    cordialment

  26. #25
    Laboum

    Re : Faire une horloge avec un PIC

    Bonsoir saralala, bienvenue sur Futura,

    Quel beau déterrage de topic
    Ta question est tellement basique, que je te conseille de consulter d'urgence, les cours du Professeur Bigonoff.
    Bon courage

  27. #26
    invite265e7c0b

    Re : Faire une horloge avec un PIC

    ça aurait été juste plsu simple si t'y avait répondu surtout si elle est aussi basique que tu le prétends.

  28. #27
    Gérard

    Re : Faire une horloge avec un PIC

    Et toi, si tu avais lu les docs, tu saurais qu'il faut 4 coups d'horloge pour faire 1 cycle.

    Autre question basique ?

  29. #28
    bobflux

    Re : Faire une horloge avec un PIC

    Ah, le Cortex-M0 à 1€ et ses timers 32 bits... mais passons.

    Je précise que je ne connais pas les PIC en général ni le tien en particulier.

    2 MHz, prédiviseur 32 => 62500 Hz donc on obtient 1 Hz avec un seul timer 16 bits. On a du 1 Hz.

    Avec un timer 8 bits (lol) il faudra laisser filer le timer de 0 à 255 pendant 244 tours puis le paramétrer pour 1 tour pour qu'il compte de 0 à 35. Comme 244*256 + 36 = 62500 on a de nouveau du 1 Hz.

Discussions similaires

  1. Résoudre une équation avec une fraction rationnelle, comment faire?
    Par invite0c5534f5 dans le forum Mathématiques du collège et du lycée
    Réponses: 8
    Dernier message: 30/09/2007, 00h33
  2. Comment brancher deux CI 4010 avec une horloge
    Par inviteffed58af dans le forum Électronique
    Réponses: 6
    Dernier message: 12/06/2006, 21h42
  3. comment faire une horloge a quartz
    Par invitec35bc9ea dans le forum Électronique
    Réponses: 7
    Dernier message: 03/06/2006, 16h09
  4. Horloge avec PIC 16F84
    Par invitee45b5732 dans le forum Électronique
    Réponses: 16
    Dernier message: 14/04/2006, 00h32
  5. une horloge avec une autre base de temps ?
    Par invite45d38ce7 dans le forum Logiciel - Software - Open Source
    Réponses: 4
    Dernier message: 25/01/2005, 13h58
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...