Mesure période signal en entrée d'un microcontrôleur pic
Répondre à la discussion
Page 1 sur 2 1 DernièreDernière
Affichage des résultats 1 à 30 sur 36

Mesure période signal en entrée d'un microcontrôleur pic



  1. #1
    adrienc45

    Mesure période signal en entrée d'un microcontrôleur pic


    ------

    Bonsoir a tous

    Je vous expose ma problématique :

    j ai besoin de calculer en temps réel l évolution de la période d ' un signal créneau de tension entre 0 et 5 volt applique sur une entrée déclare comme entrée logique sur un microcontrôleur plus précisément pic 16f877

    muni de la datasheet et d un dictionnaire anglais français je me suis lance a la recherche de méthodes pour arriver a mes fins ...

    j hésite entre utiliser juste le registre du timer tmr1h et tmr1l directement en le démarrant et le stoppant puis remise a zéro après stockage de la valeur pour exploitation dans chaque cycle de boucle ( boucle infini car mesure de la période en continu )

    ou utiliser le mode capture si j envoie mon signal en entrée de ccp1 ou ccp2

    j ai touche au registres t1con pour tenter de paramétrer et gérer la marche et arrêt de celui ci , mais sans résultats .


    si quel qu un pouvait m expliquer avec quelques détails de plus , ou un exemple de programme en c déjà existant et je m adapterais ... c est en se cassant la tété que l on assimile

    PS : j effectue en parallèle un test des programmes sur mon circuit simule sous proteus , pratique avant la fabrication matériel .

    j attend vos réponse avec impatience

    merci d avance de votre lecture

    bonne soirée

    -----

  2. #2
    antek

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Donne une plage de durée des périodes à mesurer.
    Tu utilises quel langage ?

  3. #3
    adrienc45

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Bonjour

    la fréquence de mon signal d entrée mis en forme correspond a l information de régime moteur
    donc celui ci étant de 0 a 13000 rpm , pour avoir un peu de marge une fréquence de 1 a 300 hz me parait correcte histoire d avoir un peu de marge en cas de sur-régime .

    Donc une période du signal d entrée a mesurer qui va osciller entre 1 seconde et 2.5 millisecondes .

    La ou j ai besoin de plus de précision que possible c' est sur la plage régime moteur entre 500 et 8000 rpm, don entre 80 et 140 hz donc une mesure de période correct entre 7 ms et 13 ms


    je programme avec mikroc

    ensuite j' utilise le fichier .hex compilé par ce logiciel que je rentre dans le modèle de mon microcontrôleur sur proteus pour lancer la simulation sous Isis .

    Merci de votre considération pour mon problème

    Bonne journée

  4. #4
    DAUDET78

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Citation Envoyé par adrienc45 Voir le message
    Donc une période du signal d entrée a mesurer qui va osciller entre 1 seconde et 2.5 millisecondes .
    Irréaliste ! Ton moulin ne tourne pas à 60 tr/mn . C'est 80ms ( 750 tr/mn) à 4,6ms(13000 tr/mn)
    La ou j ai besoin de plus de précision que possible
    La précision dépend de la période du signal (plus elle est grande, plus tu as une bonne précision)
    c' est sur la plage régime moteur entre 500 et 8000 rpm, don entre 80 et 140 hz donc une mesure de période correct entre 7 ms et 13 ms
    500 tr/mn-> 120ms
    8000 tr/mn-> 7,5ms

    Pour améliorer la précision aux vitesses élevées, tu peux dire que tu fais la mesure sur 2 ou 3 ou 4 périodes. Le temps de mesure est plus long, mais c'est plus précis . Ce genre d'amélioration est à envisager une fois que ton programme de base est au point !


    Exemple :
    Tu as un timer 16 bits qui utilise une horloge interne de 10Khz (je ne sais pas si c'est possible, mais c'est une hypothèse d'école) , donc une résolution 100µs .
    Tu reçois un top, tu lances le timer.
    Tu reçois un nouveau top
    Deux cas se présentent :
    - Le timer est à 1200 . La période est de 120,0 ms, donc la vitesse= 500,0 tr/mn (+-0,4) . Tu resetes le timer
    - Le timer est à 46 . La période est de 4,6 ms, donc la vitesse= 13043 tr/mn (+-277)
    Donc , dans le deuxième cas, tu as une mesure toutes les 4,6ms mais avec une précision de +-2% . Si ça ne te convient pas, tu incrémentes un compteur de boucle (Cpt) et tu laisses tourner le timer. Au top suivant, le timer est à 92 . La mesure est de 9,2 ms . Donc la vitesse (60*(Cpt+1))/0,0092= 13043 tr/mn (+-138). tu as une mesure toutes les 9,2ms mais avec une précision de +-1%
    J'aime pas le Grec

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

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    D' accord , je comprends bien le principe du programme

    registre 16 bit a utiliser pour moi c est bien celui du TIMER1 ?

    la mesure sur une seule période me suffira au vu de la précision apparente , ce sera facilement changeable si besoin .

  7. #6
    DAUDET78

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Citation Envoyé par adrienc45 Voir le message
    registre 16 bit a utiliser pour moi c est bien celui du TIMER1 ?
    J'en sais rien ... je ne m'occupe plus de µC depuis 2005 .
    J'aime pas le Grec

  8. #7
    RISC

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Salut,

    Regardes la datasheet...l'unité CCP utilise le timer2 pour le mode capture
    Il est possible d'utiliser aussi le Timer1 mais pas en mode capture. Il faut alors gérer les interruptions pour compter.
    La mesure de temps avec CCP a été discutée des centaines de fois sur ce forum. Si tu cherches CCP PIC futura-sciences ou CCP PIC18 futura-sciences tu trouveras sans doute pas mal de liens et des exemples de code.

    a+

  9. #8
    antek

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Citation Envoyé par adrienc45 Voir le message
    registre 16 bit a utiliser pour moi c est bien celui du TIMER1 ?
    TMR1 affecte 2 registres TMR1L et TMR1H de 8 bits chacun.
    Je ne sais pas comment c'est géré en MikroC.

    Vérifier s'il ne serait pas préférable d'utiliser un timer 8 bit en fonction des fréquences d'horloge utilisées.

  10. #9
    DAUDET78

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Citation Envoyé par RISC Voir le message
    Il est possible d'utiliser aussi le Timer1 mais pas en mode capture.
    le mode capture? C'est le signal externe qui incrémente le timer ? Alors, ce n'est pas le fonctionnement souhaité ici.
    J'aime pas le Grec

  11. #10
    paulfjujo

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Citation Envoyé par antek Voir le message
    Je ne sais pas comment c'est géré en MikroC.

    Quelques exemples mode capture CCP ICI
    avec mikroC et 16F ou 18F

    Le mode CCP ne permet pas une tres large dynamique de mesure , si on ne gere pas les debordemnts de compteurs.
    On peut aussi jouer sur le nombre de front accumulés ( valable sur certains PIC seulement)
    pour garder une bonne résolution.
    voir les test realises .. avec un generateur à quartz comme source de frequence.

    Le mode Frequencemetre serait mieux adpaté au grandes vitesses (Freq elevée)
    le timer compte le nombre de front du signal pendant un temps defini
    Le mode Periodmetre CCP aux basses Frequence
    le nombre de pulses FOSC (élevé) est compté entre le(s) front(s) du signal

  12. #11
    ilyasse192

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Bonsoir a tous,
    pour récupérer la période d'un signal délivrer par un capteur (tachy, optique..)
    tu peux utiliser l'interruption externe RB0 comme détecteur des fronts et le timer1 pour compter la différence entre entre deux front ==> donc "T"
    voici un exemple :

    Code:
       void interrupt(){
    
       if (INTF_bit){
          INTF_bit=0 ;
       if (!premier_front){
           TMR1H =0x00;  // reseter le timer pour une nouvelle periode
           TMR1L =0x00;
           premier_front =1;} // desactive la condition du 1èr front
           
       else {periode =(TMR1L + TMR1H *256);premier_front=0; }}
    
      
       if (TMR1IF_bit){  //si le timer est déborder... 
          TMR1IF_bit =0;
          TMR1H =0x00;
          TMR1L =0x00;}}
    N.B : La valeur du periode =(TMR1L + TMR1H *256) ne comporte pas la durée réel du signal, il faut prendre en considération le prescaler et l'osc

    par exp: on a un quartz de Fosc=4Mhz <==> Tosc=1us ;
    avec un prescaler 1:1 le timer incrément 1 chaque 1us...
    avec ces params "periode =(TMR1L + TMR1H *256) " représente la durée en us
    bn courage
    Dernière modification par Antoane ; 08/10/2015 à 18h56. Motif: Remplacement des balises quote par code

  13. #12
    ilyasse192

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    pour info la Période maximal est limité a 65,535 ms <==> 15,25 Hz

  14. #13
    adrienc45

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    cela dépend de quel horloge on prend pour " alimenter " le timer1 non ?

    je prends une horloge externe pour mon microcontrolleur de 20 mhz grâce a un quartz .

    donc la frequence d execution du timer est celle de l horloge divisé par 4 si on prend prescaler pleine echelle ?
    Dernière modification par adrienc45 ; 08/10/2015 à 17h22.

  15. #14
    ilyasse192

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    absolument
    pour 20 MHz la periode max est de 13,107 ms ==> Fmin 76,29 Hz

  16. #15
    adrienc45

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    ça ne me suffit de cette manière

    vu que ma plage de mesure est de 80ms ( 750 tr/mn) à 4,6ms(13000 tr/mn)

    Donc je dois paramétrer le prescaler alors ?
    Dernière modification par adrienc45 ; 08/10/2015 à 17h44.

  17. #16
    ilyasse192

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    y'a une applic qui fais ce genre de travail
    http://www.mikroe.com/timer-calculator/

  18. #17
    adrienc45

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    je prefererais l écrire en code classique , plus instructif a mon gout

    mais merci quand même , je passe par le code quand même

  19. #18
    paulfjujo

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Citation Envoyé par ilyasse192 Voir le message
    pour info la Période maximal est limité a 65,535 ms <==> 15,25 Hz
    sauf si on gere (compte) les debordement du compteur ..
    X fois 65,53 ms

  20. #19
    adrienc45

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    donc soit je gère le débordement du compteur timer1 ( tmr1h et tmr1l)

    soit je joue avec le prescaler a appliquer sur l horloge avant de l utiliser pour le timer1

    c est bien ça ?

  21. #20
    ilyasse192

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Citation Envoyé par paulfjujo Voir le message
    sauf si on gere (compte) les debordement du compteur ..
    X fois 65,53 ms
    tout a fait raison

  22. #21
    ilyasse192

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Citation Envoyé par adrienc45 Voir le message
    donc soit je gère le débordement du compteur timer1 ( tmr1h et tmr1l)

    soit je joue avec le prescaler a appliquer sur l horloge avant de l utiliser pour le timer1

    c est bien ça ?
    si on augmente le prescaler on baisse la résolution de mesure (temps de hachage) a toi de choisir les bons carac

  23. #22
    adrienc45

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Apres une meilleure analyse de mon problème je remarque que la précision nécessaire sur la mesure est la suivante :

    J ai besoin d une information régime moteur issu de ce signal précise a 50 rpm près ;

    soit une information de frequence issu de ce signal precise a 0.833 Hz pres

    soit un calcul sur la période du signal analyse qui doit être précis au pire des cas de 1.20 ms ; mais ceci étant le pire que je peux accepter d un tel montage

    donc je pense que j ai de la marge ...

  24. #23
    adrienc45

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Citation Envoyé par ilyasse192 Voir le message
    Bonsoir a tous,
    pour récupérer la période d'un signal délivrer par un capteur (tachy, optique..)
    tu peux utiliser l'interruption externe RB0 comme détecteur des fronts et le timer1 pour compter la différence entre entre deux front ==> donc "T"
    voici un exemple :

    Code:
       void interrupt(){
    
       if (INTF_bit){
          INTF_bit=0 ;
       if (!premier_front){
           TMR1H =0x00;  // reseter le timer pour une nouvelle periode
           TMR1L =0x00;
           premier_front =1;} // desactive la condition du 1èr front
           
       else {periode =(TMR1L + TMR1H *256);premier_front=0; }}
    
      
       if (TMR1IF_bit){  //si le timer est déborder... 
          TMR1IF_bit =0;
          TMR1H =0x00;
          TMR1L =0x00;}}
    N.B : La valeur du periode =(TMR1L + TMR1H *256) ne comporte pas la durée réel du signal, il faut prendre en considération le prescaler et l'osc

    par exp: on a un quartz de Fosc=4Mhz <==> Tosc=1us ;
    avec un prescaler 1:1 le timer incrément 1 chaque 1us...
    avec ces params "periode =(TMR1L + TMR1H *256) " représente la durée en us
    bn courage

    je ne comprends pas tout de ce programme

    a quoi correspond premier_front?

    et if (INTF_bit)
    {
    }

    et premier_front =1 entre autres ?

    merci

  25. #24
    adrienc45

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    j ai tente de mettre en place un code pour mon utilisation , je ne sais pas si cela peut fonctionner , la structure est logique mais le reste je ne sais pas trop ...

    Code:
    //*CHAINE*DE*MESURE
    
    */*PROGRAMME*qui*as*pour*but*de*calculer*la*periode*d*'*un*signal*applique*sur*ra4/t0ck1
    **d*ou*l*utilisation*du*timer1*pour*calculer*le*temps*entre*deux*fronts*montant*donc*de*la*periode*du*signal*envoyé*en*entrée***/
    /**avec*cette*configuration*prescaler*1*et*horloge*ext*(20*mhz/4)*pour*timer0*,*temps*entre*deux
    incrementations*du*timer0*=*0.2*microsceondes**/
    
    
    void*main()
    {
    
    
    **************TRISA.B0*=0;***//*pin*0*du*port*A*est*declare*en*entree*pour*l*acquisition*du*signal
    **************unsigned*int*periode*=*0;
    **************unsigned*int*temps*=*0;
    **************unsigned*int*tempstotal*=*0;
    **************int*a=0*;*********//***variable*qui*sert*de*condition*test*sortie*de*boucle*des*que*l*on*as*acqui*notre*periode
    **************int*dep=0;*******//*variable*qui*stocke*le*nombre*de*depassements*ayant*eue*lieu*durant*le*comptage*durant*une*periode
    **************float*per_tim0*=*0.0000002;*//*temps*entre*deux*incrementations*du*timer0*=*0.2*microsceondes
    
    **************TMR1CS_bit*=*1;***//*utilisation*pour*le*timer0*de*horloge*externe*a**quartz
    **************T1SYNC_bit*=*0;***//*synchro*entre*l*incremenattion*du*timer*0*et*de*l*horloge*externe
    **************T1OSCEN_bit*=*0;**//*oscillateur*interne*off*/*normal*(*on*s*en*sert*pas*)
    **************T1CKPS1_bit*=*T1CKPS0_bit*=*0;****//*prediviseur*a*1*entre*timer0*et*horloge*externe*utilisé
    **************
    **************TMR1L*=*TMR1H*=*0;**********//*initialisation*du*timer0
    
    **************do
    **************{
    ************************if(PORTA.B0*=0)
    ************************{
    *************************************a=0;****//*le*comptage*de*la*periode*commance*seulement*des*que*l'*on*detecte*le*premier*front*montant*si*non*on*reboucle*tant*que
    ************************}
    ************************if(PORTA.B0*=1)******//*le*comptage*de*la*periode*peut*commencer*car*on*as*detecte*le*premier*front*montant
    ************************{
    ************************************TMR1ON_bit*=*1;***//*mise*en*marche*de*l*incrementation*du*timer1
    ************************************do
    ************************************{
    *************************************************if(TMR1IF_bit*=*1)****//**boucle*quidurant*le*comptage*de*la*periode*,*comptabilise*les*debordement*du*timer0
    *************************************************{
    **********************************************************dep=dep+1;
    **********************************************************TMR1IF_bit*=*0;
    *************************************************}
    ************************************}while(PORTA.B0*=1);
    ************************************TMR1ON_bit*=*0;***//*arret*de*l*incrementation*du*timer1
    ************************************temps*=*TMR1H*256+TMR1L;******//*calcul*de*la*valeur*contenu*si*on*accole*les*deux*registres*accolés*sans*compter*le*nombre*de*debordements
    ************************************tempstotal*=*dep*1024+temps;***//*calcul*nombres*d*incrementations*en*tout*durant*la*periode*,*debordements*multiples*compris
    ************************************periode*=*tempstotal*per_tim0;*//*calcul*periode*du*signal
    ************************************
    ************************************a=1;
    *************************}
    
    ***************}*while(a=0);
    
    *****PORTD*=*periode;*********//*On*envoie*les*8*bits*de*points*faibles*sur*le*port*D
    *****PORTC*=*periode*>>*8;*//*On*fait*un*décalage*des*8*bits*de*poids*faibles*pour*faire*apparaitre*les*2*bits*de*poids*fort*restant*sur*le*PORTC
    
    }*

  26. #25
    adrienc45

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Citation Envoyé par ilyasse192 Voir le message
    y'a une applic qui fais ce genre de travail
    http://www.mikroe.com/timer-calculator/

    je n ai pas saisi l' utilité de cette " chose " , surtout le lien avec le besoin que j ' ai

    si sa peut alléger mon code , pourquoi pas au final ?

  27. #26
    adrienc45

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    j ai eue le temps de réfléchir a un autre programme a base du timer0 cette fois ci et tout en comptabilisant les dépassements en plus et affichant la fréquence sur le port c et d ( fréquence en nombre binaire 16 bit ) et en faisant en sorte que le drapeau d interruption se lève au front montant du signala plique sur int/rbo

    voici :

    Code:
    //*CHAINE*DE*MESURE
    
    */*PROGRAMME*qui*as*pour*but*de*calculer*la*periode*d*'*un*signal*applique*sur*l*entree*int/rb0
    **d*ou*l*utilisation*du*timer1*pour*calculer*le*temps*entre*deux*fronts*montant*donc*de*la*periode*du*signal*envoyé*en*entrée***/
    /**avec*cette*configuration*prescaler*1*et*horloge*ext*(20*mhz/4)*pour*timer0*,*temps*entre*deux
    incrementations*du*timer0*=*0.2*microsceondes**/
    
    unsigned*int*periode;
    unsigned*int*tempstotal;
    float*per_tim0*=*0.0000002;*//*temps*entre*deux*incrementations*du*timer0*=*0.2*microsceondes
    int*a;*********//***variable*qui*sert*de*condition*test*sortie*de*boucle*des*que*l*on*as*acqui*notre*periode
    int*dep;*******//*variable*qui*stocke*le*nombre*de*depassements*ayant*eue*lieu*durant*le*comptage*durant*une*periode
    unsigned*int*frequence;
    
    void*main()
    {
    
    
    ******ANSEL**=*0;**//*I/O*en*digital.
    ******ANSELH*=*0;**//*I/O*en*digital.
    
    ******TRISB.B0*=1;***//*pin*0*du*port*B*est*declare*en*entree*pour*l*acquisition*du*signal
    ******
    ******TRISC*=0b00000000;**//*portc*decalre*en*sortie*logique*pour*l*affichage*du*resultat
    ******TRISD*=0b00000000;**//*portc*decalre*en*sortie*logique*pour*l*affichage*du*resultat
    ******
    ******OPTION_REG*=*0xC0;**//bit7->*RBPU=1*(off),*bit6*->*INTEDG=1*(front*montant)
    *************************//bit5->*T0CS=0*(fosc/4),*bit4->*TOSE=0
    *************************//bit3->*PSA=0*(prescaler*timer0),*bit<3:0>*000*->*1:1
    *************************//*=>*OPTION_REG=0b11000000=0xC0
    
    ******INTCON*=*0x90;******//bit7->*GIE=1,*bit6->*PEIE=0,*bit5->*T0IE=0
    *************************//bit4->*INTE=1,*bit3->*RBIE=0,*bit2->T0IF=0
    *************************//bit1->*INTF=0,*bit0->*RBIF=0
    *************************//*=>*INTCON=0b10010000=0x90
    ******
    ******for(;;)
    ******{
    **************periode**=*tempstotal*=*frequence*=*a*=*dep*=*0;*//*initialisation*des*variables*de*stockage*avant*prochain*calcul
    **************TMR0*=*0;**********//*initialisation*du*timer0
    **************T0IF_bit*=*0;**********//*initialisation*du*drapeau*d*interruption*du*timer0
    **************INTE_bit*=*0;*********//*active*le*drapeau*d*interruption*t0if*sur*l*entree*externe*rb0/int
    
    **************do
    **************{
    ************************if(INTF_bit=0)
    ************************{
    *************************************a=0;****//*le*comptage*de*la*periode*commance*seulement*des*que*l'*on*detecte*le*premier*front*montant*si*non*on*reboucle*tant*que
    ************************}
    ************************if(INTF_bit=1)******//*le*comptage*de*la*periode*peut*commencer*car*on*as*detecte*le*premier*front*montant
    ************************{***********
    ************************************INTF_bit*=*0;
    ************************************INTE_bit*=*1;***//*mise*en*marche*de*l*incrementation*du*timer0
    ************************************do
    ************************************{
    *************************************************if(T0IF_bit*=*1)****//**boucle*quidurant*le*comptage*de*la*periode*,*comptabilise*les*debordement*du*timer0
    *************************************************{
    **********************************************************dep=dep+1;
    **********************************************************T0IF_bit=*0;
    *************************************************}
    ************************************}while(INTF_bit*=*0);
    ************************************INTF_bit*=*0;
    ************************************INTE_bit*=*0;***//*arret*de*l*incrementation*du*timer0
    ************************************tempstotal*=*dep*1024+TMR0;***//*calcul*nombres*d*incrementations*en*tout*durant*la*periode*,*debordements*multiples*compris
    ************************************periode*=*tempstotal*per_tim0;*//*calcul*periode*du*signal
    ************************************frequence=1/periode;
    ************************************a=1;
    *************************}
    
    ***************}*while(a=0);
    
    ***************PORTD*=*frequence;*********//*On*envoie*les*8*bits*de*points*faibles*sur*le*port*D
    ***************PORTC*=*frequence*>>*8;*//*On*fait*un*décalage*des*8*bits*de*poids*faibles*pour*faire*apparaitre*les*2*bits*de*poids*fort*restant*sur*le*PORTC
    *******}
    }
    Qu en pensez vous ?
    Je regarde votre réponse précédemment poste plus tard dans la soirée car je dois m en aller précipitamment !

    PS : J ai besoin d afficher une fréquence dans un premier temps , la vitesse rotation moteur je fais le calcul plus tard dans mon programme principal ..
    a plus tard et merci encore
    la j affiche le résultat sur les port c et d mais c est juste pour la simulation , car après j utiliserais directement la valeur numérique en return d un sous programme dans lequel il y aura le programme ci dessus pour appeler le calcul de frequance quand j aurais besoin


    je met en fichier joint ma simulation sur proteus dans laquelle je lance mon fichier compilé .hex obtenu par mikroC
    Dernière modification par adrienc45 ; 13/10/2015 à 22h29.

  28. #27
    adrienc45

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Bonjour a tous

    je reviens cette fois ci avec un programme qui fonctionne , mais il y as quelques dysfonctionnements dans certaines conditions particulieres

    le programme me calcule la duree d une periode d un signal applique sur l entree rb0/ int et m affiche la valeur de la frequence apres calcul sur un registre 16 bit ( la valeur que prend ce registre est representé par l activation ou non des sorties logiques configures sur le port c et d du pic 16f887.

    voici mon code

    Code:
    // CHAINE DE MESURE
    
     /*PROGRAMME qui as pour but de calculer la periode d ' un signal applique sur l entree int/rb0
      d ou l utilisation du timer0 pour calculer le temps entre deux fronts montant donc de la periode du signal envoyé en entrée  */
    /* avec cette configuration prescaler a 1 pour wdt(  wdt pas utilisee ) donc 1:2 pour timer0 et horloge ext (20 mhz/4) pour timer0 , on aura temps entre deux
    incrementations du timer0 = 0.4 microsecondes */
    
    //
    float per_tim0 = 0.0000004; // temps entre deux incrementations du timer0 =  0.8 microsceondes ( fosc/4 plus prescaler 1:8 )
    int a;         //   variable qui sert de condition test sortie de boucle des que l on as acqui notre periode
    unsigned long dep;       // variable qui stocke le nombre de depassements ayant eue lieu durant le comptage durant une periode
    unsigned int timer0;    // variable qui stocke la valeur du registre tmr0 en sortie de la boucle de mesure de la periode
    unsigned long tempstotal; // variable qui represente le nombre total de fois ou le registre tmr0 s est incrementé entre deux fronts montant sur rb0
    float periode;  // variable qui represente la periode du signal apres multiplication du nombvre d incrementations par le temps entre deux incrementatons d horloge
    unsigned int frequence; // frequence est l inverse de la periode
    
    void main()           // boucle principal pour mesure periode signal sur rb0
    {
    
    
          ANSEL  = 0;  // I/O en digital.
          ANSELH = 0;  // I/O en digital.
    
          TRISB.B0 =1;   // pin rb0/int est declare en entree pour l acquisition du signal
    
          TRISC =0b00000000;  // portc decalre en sortie logique pour l affichage du resultat
          TRISD =0b00000000;  // portc decalre en sortie logique pour l affichage du resultat
    
          OPTION_REG = 0xC0;  //bit7-> RBPU=1 (off), bit6 -> INTEDG=1 (front montant)
                             //bit5-> T0CS=0 (fosc/4), bit4-> TOSE=0
                             //bit3-> PSA=0 (prescaler timer0), bit<3:0> 000 -> timer0 rate 1:2
                             // => OPTION_REG=0b11000000=0xC0
    
          INTE_bit = 1;      // on va utiliser le drapeau qui signale l interruption a chaque front montant du signal appliqué sur int/rb0
          T0IE_bit = 1;      // on va utiliser le drapeau qui signale l interruption a chaque debordement du timer0 ( on les comptabilise dans le programme)
          
          PORTC = 0x00;   //  portc et portd parametres en sortie pour afficher nombre en binaire de la frequence trouvé en fin de programme
          PORTD = 0x00;   //
    
    
    
          
                  INTE_bit = 0;     // initialisation des drapeaux
                  T0IE_bit = 0;     //
                  T0IF_bit = 0;     // initialisation du drapeau du depassement du regsitre TMR0
    
                  periode  = tempstotal = frequence = a = dep = 0; // initialisation des variables de stockage avant le calcul
    
                 Delay_ms(5000);
                 do          // on reste dans cette boucle tant que l on as pas acquis le temps d une periode
                 {
                            if(INTF_bit==0)
                            {
                                         a=0;    // le comptage de la periode commance seulement des que l' on detecte le premier front montant si non on reboucle tant que
                            }
                            if(INTF_bit==1)      // le comptage de la periode peut commencer car on as detecte le premier front montant
                            {
                                        TMR0 = 0;
                                        INTF_bit = 0;
                                        do
                                        {
    
                                                     if(T0IF_bit == 1)    //  boucle quidurant le comptage de la periode , comptabilise les debordement du timer0
                                                     {
                                                              dep=dep+1;
                                                              T0IF_bit= 0;
                                                     }
                                                     
                                        }while(INTF_bit == 0); // on sort des que l on capte le second front montant sur rb0 ; correspond a fin de mesure de periode
                                        timer0 = TMR0;
                                        INTF_bit = 0;
                                        tempstotal = dep * 256 + timer0;   // calcul nombres d incrementations en tout durant la periode , debordements multiples compris
                                        periode = tempstotal*per_tim0; // calcul periode du signal en secondes
                                        frequence = 1 / periode;    // calcul frequance signal en hz
                                        a = 1; // condition de sortie de la boucle de mesure
                             }
    
                  } while(a==0);   // on sort de la boucle de mesure car on est parvenu a acquerir l info de frequence du signal sur rb0
    
                 PORTD = frequence;         // On envoie les 8 bits de points faibles sur le port D
                 PORTC = frequence >> 8;    // On fait un décalage des 8 bits de poids faibles pour faire apparaitre les 2 bits de poids fort restant sur le PORTC
    
    }

    les problèmes sont les suivants :

    par exemple j applique un signal d entrée qui est normalise en amplitude ( 0-5v) de fréquence 250 hz , soit une période de 0.004 s , le programme me retourne en sortie le nombre binaire suivant : 0000000011110101 , ce qui correspond au nombre décimal 245 ;
    soit la période fourni 250 hz et le montage la détectant comme 245 hs , d ou une incertitude sur la mesure qui me parait aberrante non ?

    second problème , le programme refuse de me mesurer les période de signaux a très basse fréquence ( genre inférieur a 10 hz ) il me retourne une valeur complètement farfelu en sortie qui ne correspond pas a un résultat que je devrais avoir logiquement )

    et cela malgré que je gère les dépassement multiples du tmr0

    l incertitude est de 5 hz a 250 hz et de 1 hz a 10 hz .

    qu' en pensez vous ? je ne pense pas que le montage ni le programme soit mauvais en soi , mais peut être que certains paramètres ne sont pas adaptes , ou ce timer ne convient pas a ce genre d' utilisation

    je rappelle que je travaille sur pic 16f887 .

  29. #28
    paulfjujo

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    bonjour,

    Code:
        periode  = tempstotal = frequence = a = dep = 0; // initialisation des variables de stockage avant le calcul
    ce genre d'initialisation est un peu farfelu !
    du fait que toutes tes variables ne sont pas du meme type
    melange entre int ,long et flottant..
    pour etre rigoureux , initialise separement chaque variable:

    dep=0L;
    periode=0.0;
    ..etc..



    une periode de signal c'est la somme des etat bas + etat haut .

    tu armes des interruptions ..sans les gérer !
    et tu fait du pooling sur les flags dedites interruption ..
    c'est un non sens.

    L'armement d'interruptions doit se faire quand toutes les inits sont finies
    D'ailleurs je n'ai pas vu le GIE_bit armé quelque part.

    Si tu ne veux pas suivre nos conseils, (meme topic sur Fantaspic)
    tu n'as pas fini de tourner en rond.
    Dernière modification par paulfjujo ; 23/10/2015 à 11h05.

  30. #29
    adrienc45

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    ok pour l initialisation des variables

    tu armes des interruptions ..sans les gérer !
    et tu fait du pooling sur les flags dedites interruption ..
    c'est un non sens.
    je ne comprends pas

    ma mesure de période repose sur le fait que je mesure le temps entre deux états identiques du signal , donc entre deux front montant successifs , ce que est pareil a mon idée ? non ?

    pour le GIE_bit , je dois le mettre a 1 au début du programme ( initialisation qui autorise les interruptions a avoir lieu si je comprends bien ? )
    c est bien ca ?

  31. #30
    antek

    Re : Mesure période signal en entrée d' un microcontrôleur pic

    Citation Envoyé par adrienc45 Voir le message
    je ne comprends pas
    ma mesure de période repose sur le fait que je mesure le temps entre deux états identiques du signal , donc entre deux front montant successifs , ce que est pareil a mon idée ? non ?
    pour le GIE_bit , je dois le mettre a 1 au début du programme ( initialisation qui autorise les interruptions a avoir lieu si je comprends bien ? )
    pooling -> scrutation permanente d'un état, d'une variable, . . .

    front montant (ou descendant) et état haut (ou bas) sont des évennements différents

    Il reste un autre bit à configurer, fonction de l'interruption à configurer -> voir schéma global des interruptions dans la doc µChip

Page 1 sur 2 1 DernièreDernière

Discussions similaires

  1. Période d'un signal
    Par invite5ed6799c dans le forum Physique
    Réponses: 23
    Dernier message: 24/01/2013, 21h21
  2. période d'un signal
    Par narakphysics dans le forum Mathématiques du supérieur
    Réponses: 4
    Dernier message: 16/11/2012, 16h30
  3. mesure periode signal carré avec pic16f628
    Par rammstein dans le forum Électronique
    Réponses: 0
    Dernier message: 07/09/2009, 17h17
  4. Réponses: 1
    Dernier message: 18/02/2007, 15h52
Découvrez nos comparatifs produits sur l'informatique et les technologies.