Répondre à la discussion
Page 1 sur 2 1 DernièreDernière
Affichage des résultats 1 à 30 sur 44

Programmation en C avec Timer 0 et Timer 1



  1. #1
    Groundation

    Programmation en C avec Timer 0 et Timer 1


    ------

    Bonjour,

    voilà je réalise un projet de fin d'études qui comporte une partie programmation.
    Le programme doit compter le nombre de front d'un signal carré en entrée pendant un temps défini afin de calculer sa fréquence.
    Je souhaite utiliser les Timers.
    Mon problème est que les timers se configure soit en compteur, soir en timer alors que je dois utiliser les deux modes.
    M'est il possible d'utiliser le timer0 en mode counter et le timer1 en mode timer et ce en même temps ?

    J'utilise un pic 16f876A à 20Mhz et je programme en C.
    Merci

    -----

  2. Publicité
  3. #2
    Seb.26

    Re : Programmation en C avec Timer 0 et Timer 1

    Citation Envoyé par Groundation Voir le message
    M'est il possible d'utiliser le timer0 en mode counter et le timer1 en mode timer et ce en même temps ?
    Oui, et c'est même une bonne idée

    Le premier Timer va compter les fronts et le second donnera la base de temps pour savoir combien de fronts tu as en combien de temps ... pense juste à remettre le compteur de front à 0 à chaque période, et ça roule !

    Tu auras donc la fréquence des fronts.
    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  4. #3
    vede

    Cool Re : Programmation en C avec Timer 0 et Timer 1

    Bonsoir,

    moi je n'utiliserais qu'un Timer (Timer1) ceci afin de créer la "fenêtre de temps"...
    puis l'interruption sur l'entrée RB0 (INT RB0) pour "recevoir" et compter (inc(c))
    les impulsions/fronts pendant la période/fenêtre définie par le Timer1...

    vede
    ;O]
    __________________________
    ...

  5. #4
    magnum0001

    Re : Programmation en C avec Timer 0 et Timer 1

    Je ne suis pas certain, mais le plus avantageux (optimisation des ressources), ce serait pas de compter le temps entre deux fronts montants via un timer et une interruption sur front montant (reset du timer)?

  6. A voir en vidéo sur Futura
  7. Comparatifs

    Gagnez du temps et de l'argent grâce à nos comparatifs de produits. Parmi nos sujets :
  8. #5
    vede

    Cool Re : Programmation en C avec Timer 0 et Timer 1

    re ;O]

    en fait c'est toujours pareil...

    la meilleure solution dépendra :
    -de la plage de fréquence "à mesurer"...
    -ainsi que de la précision désirée/espérée...

    vede
    ;O]
    ______________________________ _________
    Joyeuses Pâques et vive les cloches...

  9. #6
    Seb.26

    Re : Programmation en C avec Timer 0 et Timer 1

    Citation Envoyé par vede Voir le message
    Bonsoir,
    moi je n'utiliserais qu'un Timer (Timer1) ceci afin de créer la "fenêtre de temps"...
    puis l'interruption sur l'entrée RB0 (INT RB0) pour "recevoir" et compter les impulsions/fronts pendant la période/fenêtre définie par le Timer1...
    Oui, tu économise 1 Timer comme ça (par contre, tu auras bien plus d'IT) ... mais c'est probablement mieux !
    << L'histoire nous apprend que l'on apprend rien de l'histoire. >>

  10. Publicité
  11. #7
    Groundation

    Re : Programmation en C avec Timer 0 et Timer 1

    Merci pour vos réponses, la plage de fréquence à mesurer est de 50 à 400Hz, c'est pourquoi je veux utiliser le timer 1 qui est plus precis.

  12. #8
    vede

    Cool Re : Programmation en C avec Timer 0 et Timer 1

    re-re ;O]

    Les 2 méthodes :

    1/ compter le temps entre chaque fronts
    2/ compter les fronts pendant une période/fenêtre

    Chacune à ses inconvénients et avantages
    selon la plage de fréquence et la précision
    désirée...

    Pour compter les fronts (impulsions), la
    méthode commune, est d'utiliser l'interruption
    INT RB0 sur l'entrée RB0, disponible sur tous les 16Fxxx

    Pour compter le temp ou définir une période, la
    méthode commune est d'utiliser un Timer, et son
    interruption, assisté d'un compteur (une variable)
    si l'on veut créer des périodes supérieures aux
    limites de ci-celui...

    exemples en "pseudo-code"...

    Méthode 1:
    Code:
    interruption 
    ( 
       temp = TMR1
       TMR1 = 10  // ... à "affiner"... 
       re-active INT RB0
    )
    
    main 
    (
     active TMR1
     active INT RB0
     while true
     (   
       freq = 1 000 000 / temp  // @4Mhz et Prescaler Timer1 =1
       affiche(freq)
     )
    )

    Méthode 2:
    bon là faut commencer par définir 1s (fenêtre)
    bon comme aucun timer n'arrive à 1s, on rajoute
    un compteur, et on règle le timer sur 100ms (x10)
    Code:
    interruptions 
    ( 
       si INT RB0
       (
         inc(fronts)
         re-active INT RB0
       )   
       si INT TMR1
       (
         inc(compteur_t1)
         if compteur_t1>9
         (
           freq = fronts
           fronts = 0
           compteur_t1 = 0
         )
         TMR1 = xxx //100ms (xxx = période de 100ms)
         re-active INT TMR1
       )
    )
    
    main 
    (
     active TMR1
     active INT TMR1
     active INT RB0
     while true
     (   
       affiche(freq)
     )
    )
    bon c'est vraiment du "pseudo-code"...
    car déjà TMR1 est sur 16 bits...
    mais c'est la base...

    vede
    ;O]
    _____________________
    ...
    Dernière modification par vede ; 05/04/2010 à 04h28.

  13. #9
    vede

    Cool Re : Programmation en C avec Timer 0 et Timer 1

    Edit :

    ...bon comme aucun timer n'arrive à 1s...

    avec FOsc (quartz...) > 1Mhz (en gros...)

    ----
    Chacune à ses inconvénients et avantages
    selon la plage de fréquence et la précision
    désirée...

    et selon les calculs engendrés (optimisation)...
    Dernière modification par vede ; 05/04/2010 à 04h48.

  14. #10
    vede

    Cool Re : Programmation en C avec Timer 0 et Timer 1

    ps :

    pour 40 @ 400Hz //@20Mhz

    avec la méthode 1, tu auras une précision
    au millième de hertz(au moins) mais nécessitant
    des calculs 32bits pour afficher la "vraie" valeur (ex: 51,4532Hz)...

    avec la méthode 2, beaucoup moins de précision (1Hz)
    mais ne nécessitant pas de calculs 32 bits avec un pov'pic 8bits...

    vede
    ;@]

    ps : il faudrait des pages d'explications à ces sujets... rien que pour l'étalonnage...
    et les choix timer/prescaler/compteur... ou pas...
    la précision finale...etc...

  15. #11
    vede

    Cool Re : Programmation en C avec Timer 0 et Timer 1

    nota :
    précisions "relatives"...
    pour avoir une "vraie" précision, il faut étalonner
    quartz/pic/timer avec un fréquencemètre...
    sans ça, la valeur/précision citée "51,4532Hz" est très très utopique...

  16. #12
    Groundation

    Re : Programmation en C avec Timer 0 et Timer 1

    Une précision au hertz prés sera suffisant, donc je vais opter pour la méthode 2 (je ne suis pas très bon en programmation, je vais éviter les complications...)
    Je ne comprends pas bien la doc du pic pour le timer1, quel registre dois-je modifier pour un prescaler de 100ms?? TMR1L, TMR1H, les deux, ou T1CON ?

  17. Publicité
  18. #13
    vede

    Cool Re : Programmation en C avec Timer 0 et Timer 1

    Citation Envoyé par Groundation Voir le message
    Une précision au hertz prés sera suffisant, donc je vais opter pour la méthode 2 (je ne suis pas très bon en programmation, je vais éviter les complications...)
    Je ne comprends pas bien la doc du pic pour le timer1, quel registre dois-je modifier pour un prescaler de 100ms?? TMR1L, TMR1H, les deux, ou T1CON ?
    les 3 ;O]

    je t'envoie qq précisions avec un exemple dans les prochaines heures...

  19. #14
    vede

    Cool Re : Programmation en C avec Timer 0 et Timer 1

    re ;O]

    bon on voit que par défaut la période max du timer @20Mhz
    est de 65536 * 0.2us = 13,1ms

    pour arriver à 100ms il faut donc activer son Prescaler
    à son maximum (8), ce qui donne 13,1 * 8 = 104ms

    bon maintenant les calculs pour s'approcher de 100ms
    disent qu'il faut positionner le timer sur 62500 (* 8 * 0.2us = 100ms)

    65536 - 62500 = 3036

    3036 = (11 * 256) + 220

    d'où :
    TMR1L = 220
    TMR1H = 11
    et ne pas oublier de positionner le Prescaler sur 8 dans le registre T1CON

    le pseudo-code final :
    Code:
    word fronts, freq
    byte compteur_t1
    
    interruptions 
    ( 
       si INTCON.INTF = 1 // si INT RB0
       (
         inc(fronts)
         INTCON.INTF = 0  // re-active INT RB0
       )   
       si PIR1.TMR1IF = 1 // si INT TMR1
       (
         inc(compteur_t1)
         if compteur_t1>9
         (
           freq = fronts
           fronts = 0
           compteur_t1 = 0
         )
         TMR1L = 220     // période de 100ms @ 20Mhz
         TMR1H = 11      // période de 100ms @ 20Mhz     
         PIR1.TMR1IF = 0 // re-active INT TMR1
       )
    )
    
    main 
    (
     ADCON0 = %00000000  // ADC OFF
     ADCON1 = %00000111  // ADC OFF
     TrisB  = %00000001  // port RB0 en entrée
     T1CON  =   %110001  // activation du TMR1, avec PreScaler=8
     INTCON = %11010000  // activation INT RB0 + Périphs
     PIE1   = %00000001  // activation INT TMR1
     while true
     (   
       affiche(freq)
     )
    )
    vede
    ;O]
    _______________________
    ...

    et dans la vraie vie on se rend compte qu'il faut souvent légérement
    augmenter TMR1L (221...222...225...) pour être réellement précis...
    nécessite un fréquencemétre pour "ajustage"...
    Dernière modification par vede ; 05/04/2010 à 17h01.

  20. #15
    vede

    Cool Re : Programmation en C avec Timer 0 et Timer 1

    ps : et dans la vraie vie on se rend compte qu'il faut souvent légérement
    augmenter TMR1L (221...222...225...) pour être réellement précis...
    nécessite un fréquencemétre pour "ajustage"...

    Edit :

    "décalage" du notamment au temps de sauvegarde des registres
    avant les interruptions, et dans une moindre mesure aux tolérances
    des composants (quartz, pic...)...

    enfin dans notre cas (précision 1Hz/400) on peut largement estimer
    que c'est négligeable...

  21. #16
    vede

    Cool Re : Programmation en C avec Timer 0 et Timer 1

    Bonjour,

    pour information les valeurs pour faire fonctionner mon code du post #14
    avec un quartz @ 4Mhz :

    T1CON = %010001 // activation du TMR1, avec PreScaler=2

    et

    TMR1L = 176 // période de 100ms @ 4Mhz
    TMR1H = 60 // période de 100ms @ 4Mhz

    vede
    ;O]
    ________________________
    ...
    Dernière modification par vede ; 06/04/2010 à 06h30.

  22. #17
    Groundation

    Re : Programmation en C avec Timer 0 et Timer 1

    Merci beaucoup vede, une dernière petite question, est ce que je peux appliquer directement sur RB0 un signal carré 0-5v venant d'une source analogique ou est ce que je dois passer par un ADC?

  23. #18
    vede

    Cool Re : Programmation en C avec Timer 0 et Timer 1

    Hi ;O]

    théoriquement oui...
    si t'es vraiment sur que le signal ne dépasse jamais 5V...

    faudrait voir le générateur...
    car on pourrait aussi filtrer (rc)...
    ou ajouter une R de pull-on ou off...
    ou ...

    vede
    ;O]
    ___________________________
    ...

  24. Publicité
  25. #19
    Groundation

    Re : Programmation en C avec Timer 0 et Timer 1

    Le signal arrive depuis un amplificateur opérationnel en comparateur alimenté en 0-5v, donc en théorie pas de problème, maintenant la théorie et la pratique...
    En tout cas merci pour toutes les infos que tu m'as donné

  26. #20
    velayg

    Re : Programmation en C avec Timer 0 et Timer 1

    Bonjour,
    Je suis depuis 1 semaine le sujet du forum car je développe moi aussi un circuit équivalent. C'est pour réaliser un accordeur de guitare (je vous passe les détails mais le signal en entrée de mon PIC est un signal carré 0-5V).

    J'ai suivi et comparé à ma config la configuration et la démarche expliquée dans ce topic... Mais j'ai un souci! Mon programme ne supporte pas lorsque je place le bit d'interruption PEIE de INTCON à 1.
    Lorsque je le mets à 0 le programme continu mais je ne peux pas configurer le comptage (PIE1 a besoin de PEIE à1).

    Peut être est-ce un problème des pins T1OSO/T1CKI et T1OSI où j'ai branché un afficheur 7 segments. Faut il mettre un quartz ici?
    Je vous joins le prototype de mon prog.

    Merci de votre aide!
    Et bon courage à toi Groundation!

    Code:
    void main()
    {	init();
    	test();
    		//Parametres Compteur
    	OPTION_REG = 0b11000111;
     	ADCON0 = 0b00000000;  // ADC OFF
     	ADCON1 = 0b00000111;  // ADC OFF
    	T1CON  = 0b00110001;  // activation du TMR1, avec PreScaler=8	
    	INTCON = 0b11010000;  // activation INT RB0 + Périphs
    	// le bit num 6 crée un reset lorsqu'il est a 1
            PIE1   = 0b00000001;  // activation INT TMR1
    
    while(1)
    	{
    	compteur();
    	traitement(freq);
    	}		
    }
    
    void init()
    {	
    	TRISA=0xFF;
    	TRISB=0b00000001;  // port RB0 en entrée
    	TRISC=0x00;
    	TRISD=0x00;
    	TRISE=0x00;
    
    	PORTB=0;
    	PORTC=0;
    	PORTD=0;
    
    }

  27. #21
    Groundation

    Re : Programmation en C avec Timer 0 et Timer 1

    Salut velayg,

    je réalise aussi un accordeur de guitare
    Par contre je suis débutant en programmation, donc je sais pas trop pour ton problème...

    Peut être que tu devrais mettre un delay entre la config du registre INTCON et celle du registre PIE1 (peut être que PIE1 n'a pas le temps de se rendre compte que les interruptions périphériques sont activés...)

    Quel pic tu utilises ? Parfois les noms des registres et des bits changent selon les pics...

    Tiens moi au courant si tu trouves la solution, je n'ai pas encore eu les moyens de tester mon programme donc je sais pas si il marche

  28. #22
    vede

    Cool Re : Programmation en C avec Timer 0 et Timer 1

    Citation Envoyé par velayg Voir le message
    (...)Peut être est-ce un problème des pins T1OSO/T1CKI et T1OSI où j'ai branché un afficheur 7 segments. Faut il mettre un quartz ici?
    Je vous joins le prototype de mon prog.(...)
    Hi velayg,

    non c'est pas un problème de pins...
    car le quartz est sur les pins OSC1/OSC2...

    et dans ton code je vois pas celui de l'interruption...
    tu l'actives... mais faut après la "coder"...
    envoyes le code complet...

    et c'est quoi ton PIC?

    vede
    ;O]
    _______________________
    ...

  29. #23
    velayg

    Re : Programmation en C avec Timer 0 et Timer 1

    Salut tout le monde!

    @Groundation: aha projet aventureux que de faire un accordeur... On m'avait prévenu de la difficulté de réaliser ça mais je veux y arriver! Et le fait de rajouter un delay ne change rien désolé...
    Tu en es où de ton projet?

    @Vede:
    J'utilise un PIC 16F877, similaire au 16F876.
    J'avais oublier de mettre la 2eme partie du code avec l'interruption... Mais je ne suis pas sur de ce que j'ai fais...
    Merci de m'éclairer là dessus!

    Le code complet, dis moi ce que tu en penses:
    Code:
    void main()
    {	init();
    	test();
    		//Parametres Compteur
    	OPTION_REG = 0b11000111;
     	ADCON0 = 0b00000000;  // ADC OFF
     	ADCON1 = 0b00000111;  // ADC OFF
    	T1CON  = 0b00110001;  // activation du TMR1, avec PreScaler=8	
    	INTCON = 0b11010000;  // activation INT RB0 + Périphs
            PIE1   = 0b00000001;  // activation INT TMR1
     	
            while(1)
    	{
    	compteur();
    	traitement(freq);
    	}		
    }
    
    void init()
    {	
    	TRISA=0xFF;
    	TRISB=0b00000001;  // port RB0 en entrée
    	TRISC=0x00;
    	TRISD=0x00;
    	TRISE=0x00;
    
    	PORTB=0;
    	PORTC=0;
    	PORTD=0;
    }
    
    void compteur()
    {
       if(INTF=1) // si INT RB0
       {
         fronts ++;
         INTF = 0;  // re-active INT RB0
       }  
       if(TMR1IF = 1) // si INT TMR1
       {
         compteur_t1 ++;
         if(compteur_t1>9)
         {
           freq = fronts;
           fronts = 0;
           compteur_t1 = 0;
         }
         TMR1L = 220;     // période de 100ms @ 20Mhz
         TMR1H = 11;      // période de 100ms @ 20Mhz     
         TMR1IF = 0; // re-active INT TMR1
       }
    	
    }
    Merci de votre aide

  30. #24
    vede

    Cool Re : Programmation en C avec Timer 0 et Timer 1

    Hi,

    il faut re-nommer la "fonction" void compteur() en void interrupt()

    ensuite dans le "programme principal"
    Code:
    while(1)
    	{
    	compteur();
    	traitement(freq);
    	}
    supprimer la ligne compteur();
    et ne rien mettre d'autre ...
    surtout pas interrupt();

    car void interrupt() est "appelé" automatiquement toutes les 100ms (TMR1) ...
    c'est le principe des interruptions sur Timer...
    elles se déclenchent seules... à une fréquence prédéfinie (ici 10Hz)...

    vede
    ;O]

  31. Publicité
  32. #25
    velayg

    Re : Programmation en C avec Timer 0 et Timer 1

    Merci pour tout je vais tester ce soir!!
    Je vous tiens au courant!!

  33. #26
    velayg

    Re : Programmation en C avec Timer 0 et Timer 1

    Bonjour tout le monde,
    Depuis hier soir je teste tout le programme... Mais chose bizarre le programme repart du début après la configuration de PIE1. Je teste le moment où il y a rebouclage grâce à l'allumage de 2 LEDS.

    Code:
    void main()
    {	init();
    	test();
    		//Parametres Compteur
    	OPTION_REG = 0b11000111;
     	ADCON0 = 0b00000000;  // ADC OFF
     	ADCON1 = 0b00000111;  // ADC OFF
    	T1CON  = 0b00110001;  // activation du TMR1, avec PreScaler=8
    	INTCON = 0b11010000;  // activation INT RB0 + Périphs
    	PIE1   = 0b00000001;  // activation INT TMR1
    	
            C0=1;  //allumage des 2 LED en C0 et D0 pendant 2 secondes
    	D0=1;
    	delay_ms(2000);
    while(1)
    	{
    	traitement(freq);
    	}
    }
    Après je ne sais plus mon cerveau commence à beaucoup chauffer!
    Merci pour l'aide

  34. #27
    vede

    Cool Re : Programmation en C avec Timer 0 et Timer 1

    Bonjour,

    tu as bien désactivé le WatchDog (WDT)??? (dans MicroC : Edition Projet > WatchDog : Disasbled )...

    et il faut connecter la broche 1 (MCLR/Vpp) au +5VDC (Vdd) via une résistance 4.7@10K...

    c'est sûrement ça que tu as oublié...
    ces 2 "paramètres" sont indispensables au bon fonctionnement...
    sans eux le programme s'"auto-reset" en permanence ...

    vede
    ;O]
    __________________
    ...

  35. #28
    velayg

    Re : Programmation en C avec Timer 0 et Timer 1

    Salut Vede!
    Non ce n'est pas Watchdog (sur OFF depuis le début) ni la broche 1 (résistance de 10K sur le 5V)... J'avais déja vérifié ces problèmes!

    Alors une autre idée?

    J'ai fait des essais, comme ceci cela ne fait pas de reset:
    j'ai supprimé le prog de test des 7 segments et ca passe directement à l'analyse de fréquences!

    Code:
    void main()
    {	init();
    		//Parametres Compteur
    	OPTION_REG = 0b11000111;
     	ADCON0 = 0b00000000;  // ADC OFF
     	ADCON1 = 0b00000111;  // ADC OFF
    	T1CON  = 0b00110001;  // activation du TMR1, avec PreScaler=8
    	INTCON = 0b11010000;  // activation INT RB0 + Périphs
    	PIE1   = 0b00000001;  // activation INT TMR1
    
    while(1)
    	{
    	traitement(freq);
    	}
    }
    Surement que le programme de test était trop long pour le pic, je ne sais pas...

  36. #29
    vede

    Cool Re : Programmation en C avec Timer 0 et Timer 1

    Bonjour,

    >Surement que le programme de test était trop long pour le pic, je ne sais pas...
    -ya pas de raisons que ce soit trop long... surtout si le compilo compile....
    (sinon il signale un dépassement de capacité mémoire)

    >j'ai supprimé le prog de test des 7 segments et ca passe directement à l'analyse de fréquences!
    -c'est normal... et d'où sortait C0 et D0???

    il me faut tout le code, en entier (tel que tu le compiles), pour me faire une idée...

    et supprimes cette ligne : OPTION_REG = 0b11000111;
    ici elle sert à rien...

    tu devrais partir de mon exemple fonctionnel POST #14... pour bien "démarrer"...


    vede
    ;O]
    __________________
    ...

  37. #30
    vede

    Cool Re : Programmation en C avec Timer 0 et Timer 1

    re ;O]

    je me rends compte que je suis allé trop vite avec mes exemples...
    pour assilimer les principes (timer, int...), il faut commencer par
    un programme simple afin de les maîtriser... avant d'aller plus loin...

    donc le "hello world" électronique, c'est de faire clignoter une led...
    à différentes fréquences...et ici en utilisant timer et interruptions...
    c'est comme ça que je fais pour comprendre...

    un de mes récents exemples dans le post #18 de ce fil:
    http://forums.futura-sciences.com/el...pic16f690.html

Page 1 sur 2 1 DernièreDernière

Discussions similaires

  1. Timer : programmation et PIC débutant
    Par joey57 dans le forum Bricolage et décoration
    Réponses: 1
    Dernier message: 21/03/2010, 20h58
  2. Programmation Timer renesas M16C
    Par Noxtox dans le forum Électronique
    Réponses: 2
    Dernier message: 12/06/2009, 07h39
  3. timer avec buzzer
    Par technotron dans le forum Électronique
    Réponses: 2
    Dernier message: 23/10/2008, 14h19
  4. Interruption Timer avec PIC16F876A
    Par black_is_beautiful dans le forum Électronique
    Réponses: 9
    Dernier message: 28/07/2007, 21h57
  5. problème de programmation de timer keeper MK48T08
    Par fildelo dans le forum Électronique
    Réponses: 0
    Dernier message: 25/04/2006, 07h43
Découvrez nos comparatifs produits sur l'informatique et les technologies.