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

mesure de frequence: CCP.



  1. #1
    mortaurat

    mesure de frequence: CCP.

    Bonjour,
    je suis entrain de faire un programme afin de mesurer une periode en utilisant le module CCP de mon pic 16f876 et j'ai quelques difficultés à le mettre en oeuvre.
    Voici ce que j'ai codé pour l'instant.
    Code:
    int frequence=0, unite=0, dizaine=0, centaine=0, millier=0; // initialisation des variables;
    int tab[10] ; //contient le code pour chaque led
    #int_ccp1
    void isr_ccp1()
    {
       frequence = 1/CCP_1  ; // equivalence periode et frequence
    
    //extraction des unités, centaine, dizaine et millier. % permet d'avoir le reste d'une division
    Unite = frequence%10 ;
    Dizaine = ((frequence%100)/10) ;
    centaine = ((frequence%100)/100);
    millier  = ((frequence%100)/1000);
       set_timer1(0); //clear timer
       clear_interrupt(int_ccp1);
    }
    void main()
    {
    //remplissage tableau
    tab[0]=0b0111111 ;
    tab[1]=0b0000011;
    tab[2]=0b1011011;
    tab[3]=0b1001111;
    tab[4]=0b1100110;
    tab[5]=0b1101101;
    tab[6]=0b1111101;
    tab[7]=000000111;
    tab[8]=0b1111111;
    tab[9]=0b1101111;
    setup_timer_1(T1_internal);
    setup_ccp1(CCP_CAPTURE_RE);
    
    enable_interrupts(global);
    enable_interrupts(int_ccp1);
    while (1)
    {
    // affichage sur BCD/7segments
    output_B(tab[unite]);
    output_low(pin_A1);
    delay_ms(1);
    output_high(pin_A1);
    output_B(tab[dizaine]);
    output_low(pin_A2);
    delay_ms(1);
    output_high(pin_A2);
    output_B(tab[centaine]);
    output_low(pin_A3);
    delay_ms(1);
    output_high(pin_A3);
    output_B(tab[millier]);
    output_low(pin_A4);
    delay_ms(1);
    output_high(pin_A4);
    }
    }
    En fait j'ai un tableau qui contient un code pour afficher vers un 7 segments, l'affichage se fait dans la derniere parti avec le Port B et le port A.
    Le probléme vient je pense des interruptions ou de la conversion (frequence).
    L'interruption se produit sur front montant du signal (j'ai fais une horloge qui tourne à environ 450Hz) et un timer mesure la durée entre les deux fronts montants. La variable CCP_1 est generée automatiquement par le module CCP et est censée contenir la durée de la periode...
    Je ne vois pas ou se trouve l'erreur, quand je programme le pic, les afficheurs indiquent 0000.

    Merci

    -----


  2. Publicité
  3. #2
    simon.

    Re : mesure de frequence: CCP.

    frequence = 1/CCP_1;
    Ca peut pas marcher ça !
    Comme tu travailles en entiers, ca va toujours te donner une fréquence de zéro.
    Change d'echelle, fais plutot un truc du genre:

    frequence_fois_dix_millions = 10000000 / CCP_1;

  4. #3
    mortaurat

    Re : mesure de frequence: CCP.

    si je fais
    Code:
    frequence = 10 000 000/CCP_1 ;
    Je n'obtient plus 0000 mais un truc un peut bizare (8060).

  5. #4
    sdec25

    Re : mesure de frequence: CCP.

    Bonjour,
    En quoi 8060 est-il bizarre ?
    De plus, frequence est un int, donc sur 16 bits (-32k à 32k).

    "frequence = 10000000 / CCP1" peut poser un problème.
    Si le compilateur est bête il va caster 10000000 en int sur 16 bits donc ça ne va pas aller.
    Il faut plutôt définir frequence comme un unsigned long (ou unsigned short long) :
    Code:
    unsigned short long frequence;
    frequence = (unsigned short long) 10000000 / CCP1

  6. #5
    mortaurat

    Re : mesure de frequence: CCP.

    8060 est bizarre car il ne correspond à rien.
    Dans l'ideal je devrais avoir 450...

    avec
    Code:
    unsigned short long frequence;
    frequence = (unsigned short long) 10000000 / CCP1
    j'obtient 0004 sur mon afficheur. Ca a l'air d'être en bonne voit.
    J'ai essayé de multiplié par 100 encore mais ca me donne 0006 sur l'afficheur...

  7. A voir en vidéo sur Futura
  8. #6
    sdec25

    Re : mesure de frequence: CCP.

    A cause du problème de cast on devrait avoir une valeur sous estimée pas l'inverse.

    Code:
    //extraction des unités, centaine, dizaine et millier. % permet d'avoir le reste d'une division
    Unite = frequence%10 ;
    Dizaine = ((frequence%100)/10) ;
    centaine = ((frequence%100)/100);
    millier  = ((frequence%100)/1000);
    Déjà il y a une erreur de copier/coller : (frequence%100) / 100 vaut forcément 0. idem pour /1000. Donc ce n'est pas étonnant d'avoir 0006.
    Et faire des modulo et des divisions prend beaucoup de temps. Si la performance est un critère de ton programme, il y a une façon de faire plus rapide.

    CCP est en quelle unité ? ms ? cycles processeur ? Quelle est la fréquence de l'oscillateur ?
    Dernière modification par sdec25 ; 11/07/2009 à 14h41.

  9. Publicité
  10. #7
    mortaurat

    Re : mesure de frequence: CCP.

    tu as raison, je vais faire une ptite rectification
    CCP est en µs normalement et mon processeur est à 20Mhz

  11. #8
    sdec25

    Re : mesure de frequence: CCP.

    Citation Envoyé par mortaurat Voir le message
    CCP est en µs normalement et mon processeur est à 20Mhz
    Tu en es sûr ? Je ne connais pas CCP mais si tu n'as pas modifié de prescaler en fonction de ta fréquence d'horloge il n'y a pas de raison pour que ce soit en µs.
    Le processeur ne connaît que les cycles comme base de temps.
    A 20 Mhz, 1 cycle = 0.2µs

  12. #9
    mortaurat

    Re : mesure de frequence: CCP.

    CCP ca veut dire Capture Compare and Pwm mode.
    Ca permet de capture, de comparer et de faire des signaux PWM.

    En fait la frequence d'horloge influera normalement juste sur la precision.
    CCP_1 doit être une valeur proportionelle au temps ecoulé entre deux impulsion (front montant ici), cette valeur est censée representer la periode du signal.

    Par exemple (cité dans le livre)
    when the program is run with a 100 Hz signal input, a count of 9963µs is captured (error = 0.4%).

  13. #10
    sdec25

    Re : mesure de frequence: CCP.

    En fait la frequence d'horloge influera normalement juste sur la precision.
    CCP_1 doit être une valeur proportionelle au temps ecoulé entre deux impulsion (front montant ici), cette valeur est censée representer la periode du signal.
    ok, mais vu que le processeur n'a pas de base de temps, comment mesure-t-il le temps ?
    C'est comme pour les timers : un timers compte les cycles processeurs, pas les secondes.
    when the program is run with a 100 Hz signal input, a count of 9963µs is captured (error = 0.4%).
    Ça signifie qu'une période de 9963µs est capturée, pas qu'il y a 9963 dans CCP_1.

    Enfin, ce n'est pas ça qui empêchera le programme de fonctionner mais si tu as une fréquence 5x plus grande que prévue tu sauras pourquoi

  14. #11
    mortaurat

    Re : mesure de frequence: CCP.

    Citation Envoyé par sdec25 Voir le message
    ok, mais vu que le processeur n'a pas de base de temps, comment mesure-t-il le temps ?
    C'est comme pour les timers : un timers compte les cycles processeurs, pas les secondes.
    Ben le µc sait qu'il y a un quartz de 20 MhZ et donc il peut en deduire le temps entre deux fronts. Enfin c'est ce que j'en est conclu.
    Pour moi le timer c'etait sa.
    Sinon je dois faire quoi a ton avis ?

    Ça signifie qu'une période de 9963µs est capturée, pas qu'il y a 9963 dans CCP_1.
    il rajoute aussi
    The captured value is copied automatically into a variable called CCP_1

  15. #12
    sdec25

    Re : mesure de frequence: CCP.

    Citation Envoyé par mortaurat Voir le message
    Sinon je dois faire quoi a ton avis ?
    Pour un timer il faut corriger en fonction de la fréquence. Mais comme je l'ai dit ce n'est pas ça qui va empêcher le programme de fonctionner, donc on verra ça plus tard.
    En corrigeant les modulos ça donne quoi ?

  16. Publicité
  17. #13
    mortaurat

    Re : mesure de frequence: CCP.

    Code:
    frequence = (unsigned long)100000000/CCP_1  ;
    Unite = frequence%10 ;
    Dizaine = ((frequence%100)/10) ;
    centaine = ((frequence%1000)/100);
    millier  = ((frequence)/1000);
    nb: ma frequence depasse pas 9999 Hz

    Ca me donne strictement la même chose que tout à l'heure
    0006

  18. #14
    mortaurat

    Re : mesure de frequence: CCP.

    lorsque je remplace

    Code:
    frequence = (unsigned long)100000000/CCP_1  ;
    par
    Code:
       frequence = (unsigned long)10000000/CCP_1
    ca m'affiche 0004.

  19. #15
    sdec25

    Re : mesure de frequence: CCP.

    Citation Envoyé par mortaurat Voir le message
    nb: ma frequence depasse pas 9999 Hz
    Même si tu en es sûr tu peux faire une vérification, ça ne coûte rien et ça peut éviter bien des problèmes.
    if (CCP_1 == 0 || frequence > 9999) frequence = 9999;

    Si tu es sous MPLAB exécute le programme sur simulateur.
    Sinon essaie d'afficher directement CCP_1.
    Dernière modification par sdec25 ; 11/07/2009 à 16h27.

  20. #16
    mortaurat

    Re : mesure de frequence: CCP.

    Je suis sous CCS compiler et je teste directement sur ma plaquette.
    Code:
    if (CCP_1 == 0 || frequence > 9999)
    {
     frequence = 9999;
    }
    ca m'affiche tjr 0004.

    lorsque je rajoute
    Code:
     frequence = CCP_1  ;
    afin d'afficher CCP_1, si je retire mes impulsion, ca affiche 9999. Sinon lorsque je les places ca affiche 8 puis un chiffre pas complet (les segment A, G et D sont tjr allumés) et les deux derniers afficheur clignotent (rapidement, a la limite de la persistance retinienne) en affichant 8.
    en dirais le chiffre 8688
    Dernière modification par mortaurat ; 11/07/2009 à 16h37.

  21. #17
    sdec25

    Re : mesure de frequence: CCP.

    Citation Envoyé par mortaurat Voir le message
    afin d'afficher CCP_1, si je retire mes impulsion, ca affiche 9999. Sinon lorsque je les places ca affiche 8 puis un chiffre pas complet (les segment A, G et D sont tjr allumés) et les deux derniers afficheur clignotent (rapidement, a la limite de la persistance retinienne) en affichant 8.
    Tu as bien mis :
    Code:
    frequence = CCP_1;
    if (frequence > 9999) frequence = 9999;
    //extraction des unités, centaine, dizaine et millier. % permet d'avoir le reste d'une division
    Unite = frequence%10 ;
    Dizaine = ((frequence%100)/10) ;
    centaine = ((frequence%1000)/100);
    millier  = (frequence/1000);
    ?

    Si ça ne marche toujours pas, essaie en castant en unsigned long :
    Unite = (((unsigned long) frequence%100)/10);
    ou utilise une variable frequence_int en unsigned int et :
    unsigned int Unite = (frequence%100)/10;
    ...
    Dernière modification par sdec25 ; 11/07/2009 à 16h44.

  22. #18
    mortaurat

    Re : mesure de frequence: CCP.

    oui j'ai mis
    Code:
    if (CCP_1 == 0 || frequence > 9999) 
    {
    frequence = 9999;
    }
    Mais c'est normal que ca affiche 9999 puisque si je retire les impulsion pas de timer, donc CCP_1 == 0.

  23. Publicité
  24. #19
    sdec25

    Re : mesure de frequence: CCP.

    J'ai modifié mon message entre temps.
    Il faudrait :
    Code:
    frequence = CCP_1;
    if (frequence > 9999) frequence = 9999;
    //extraction des unités, centaine, dizaine et millier. % permet d'avoir le reste d'une division
    Unite = frequence%10 ;
    ...

  25. #20
    mortaurat

    Re : mesure de frequence: CCP.

    Citation Envoyé par sdec25 Voir le message

    Si ça ne marche toujours pas, essaie en castant en unsigned long :
    Unite = (((unsigned long) frequence%100)/10);
    ou utilise une variable frequence_int en unsigned int et :
    unsigned int Unite = (frequence%100)/10;
    ...
    même resultat.
    8688 et vu que ca à l'air de changer un peu je dois voir que ca clignote.

  26. #21
    mortaurat

    Re : mesure de frequence: CCP.

    Citation Envoyé par sdec25 Voir le message
    J'ai modifié mon message entre temps.
    Il faudrait :
    Code:
    frequence = CCP_1;
    if (frequence > 9999) frequence = 9999;
    //extraction des unités, centaine, dizaine et millier. % permet d'avoir le reste d'une division
    Unite = frequence%10 ;
    ...
    Oui j'ai essayé, avec le cast aussi.
    Même chose.
    A pars quand j'enleve les impulsion du pic je me retrouve avec 9999. curieux...
    Dernière modification par mortaurat ; 11/07/2009 à 16h56.

  27. #22
    sdec25

    Re : mesure de frequence: CCP.

    Donc tu as un CCP_1 de 8688 ?
    Tu es sûr que ton affichage fonctionne bien ?
    Essaie frequence = 9876,
    puis frequence = 5432,
    puis frequence = 1298.
    Et reposte ton programme complet c'est plus simple.

  28. #23
    mortaurat

    Re : mesure de frequence: CCP.

    Code:
    #include "C:\Documents and Settings\mortaurat\Bureau\CCS COMPILER PROJET\frequence\frequence.h"
    
    int unite=0, dizaine=0, centaine=0, millier=0; // initialisation des variables;
    unsigned long frequence ;
    int tab[10] ; //contient le code pour chaque led
    #int_ccp1
    void isr_ccp1()
    {
       frequence = 1234 ; // equivalence periode et frequence
    if (frequence > 9999) frequence = 9999;
    
    //extraction des unités, centaine, dizaine et millier. % permet d'avoir le reste d'une division
    Unite = (frequence%10);
    Dizaine = ((frequence%100)/10) ;
    centaine = ((frequence%1000)/100);
    millier  = ((frequence)/1000);
       set_timer1(0); //clear timer
       clear_interrupt(int_ccp1);
    }
    void main()
    {
    //remplissage tableau
    tab[0]=0b0111111 ;
    tab[1]=0b0000011;
    tab[2]=0b1011011;
    tab[3]=0b1001111;
    tab[4]=0b1100110;
    tab[5]=0b1101101;
    tab[6]=0b1111101;
    tab[7]=000000111;
    tab[8]=0b1111111;
    tab[9]=0b1101111;
    setup_timer_1(T1_internal);
    setup_ccp1(CCP_CAPTURE_RE);
    
    enable_interrupts(global);
    enable_interrupts(int_ccp1);
    while (1)
    {
    // affichage sur BCD/7segments
    output_B(tab[unite]);
    output_low(pin_A1);
    delay_ms(1);
    output_high(pin_A1);
    output_B(tab[dizaine]);
    output_low(pin_A2);
    delay_ms(1);
    output_high(pin_A2);
    output_B(tab[centaine]);
    output_low(pin_A3);
    delay_ms(1);
    output_high(pin_A3);
    output_B(tab[millier]);
    output_low(pin_A4);
    delay_ms(1);
    output_high(pin_A4);
    }
    }
    probléme d'affichage...
    j'utilise la même methode d'affichage pour un controleur de tension
    je viens de voir dans la cablage, les cathodes de mes afficheur sont bien respectivement sur A1, A2, A3 et A4.
    et le segment A sur RB0, B sur RB1, C sur RB2, D sur RB3, E sur RB4, F sur RB5, G sur RB6...

  29. #24
    mortaurat

    Re : mesure de frequence: CCP.

    l'affichage fonctionne correctement lorsque je suprime tout ce qui concerne les interruptions...
    j'arrive à afficher tout ce que je veux...

    #include "C:\Documents and Settings\mortaurat\Bureau\CCS COMPILER PROJET\frequence\frequence.h"

    int unite=0, dizaine=0, centaine=0, millier=0; // initialisation des variables;
    unsigned long frequence ;
    int tab[10] ; //contient le code pour chaque led
    void test()
    {
    frequence = 1234 ; // equivalence periode et frequence
    if (frequence > 9999) frequence = 9999;

    //extraction des unités, centaine, dizaine et millier. % permet d'avoir le reste d'une division
    Unite = (frequence%10);
    Dizaine = ((frequence%100)/10) ;
    centaine = ((frequence%1000)/100);
    millier = ((frequence)/1000);
    }
    void main()
    {
    //remplissage tableau
    tab[0]=0b0111111 ;
    tab[1]=0b0000110;
    tab[2]=0b1011011;
    tab[3]=0b1001111;
    tab[4]=0b1100110;
    tab[5]=0b1101101;
    tab[6]=0b1111101;
    tab[7]=000000111;
    tab[8]=0b1111111;
    tab[9]=0b1101111;
    test() ;
    while (1)
    {
    // affichage sur BCD/7segments
    output_B(tab[unite]);
    output_low(pin_A1);
    delay_ms(1);
    output_high(pin_A1);
    output_B(tab[dizaine]);
    output_low(pin_A2);
    delay_ms(1);
    output_high(pin_A2);
    output_B(tab[centaine]);
    output_low(pin_A3);
    delay_ms(1);
    output_high(pin_A3);
    output_B(tab[millier]);
    output_low(pin_A4);
    delay_ms(1);
    output_high(pin_A4);
    }
    }

  30. Publicité
  31. #25
    mortaurat

    Re : mesure de frequence: CCP.

    EDIT: J'ai trouvé, en fait il ne faut rien mettre d'autre dans la fonction isr_ccp1.
    du coup sa marche.
    Voici le nouveau prog.
    #include "C:\Documents and Settings\mortaurat\Bureau\CCS COMPILER PROJET\frequence\frequence.h"

    int unite=0, dizaine=0, centaine=0, millier=0; // initialisation des variables;
    unsigned long frequence ;
    int tab[10] ; //contient le code pour chaque led
    #int_ccp1
    void isr_ccp1()
    {
    set_timer1(0); //clear timer
    clear_interrupt(int_ccp1);
    }
    void main()
    {
    //remplissage tableau
    tab[0]=0b0111111 ;
    tab[1]=0b0000110;
    tab[2]=0b1011011;
    tab[3]=0b1001111;
    tab[4]=0b1100110;
    tab[5]=0b1101101;
    tab[6]=0b1111101;
    tab[7]=000000111;
    tab[8]=0b1111111;
    tab[9]=0b1101111;
    setup_timer_1(T1_internal);
    setup_ccp1(CCP_CAPTURE_RE);

    enable_interrupts(global);
    enable_interrupts(int_ccp1);
    while (1)
    {
    frequence = 1234 ; // equivalence periode et frequence
    if (frequence > 9999) frequence = 9999;

    //extraction des unités, centaine, dizaine et millier. % permet d'avoir le reste d'une division
    Unite = (frequence%10);
    Dizaine = ((frequence%100)/10) ;
    centaine = ((frequence%1000)/100);
    millier = ((frequence)/1000);
    // affichage sur BCD/7segments
    output_B(tab[unite]);
    output_low(pin_A1);
    delay_ms(1);
    output_high(pin_A1);
    output_B(tab[dizaine]);
    output_low(pin_A2);
    delay_ms(1);
    output_high(pin_A2);
    output_B(tab[centaine]);
    output_low(pin_A3);
    delay_ms(1);
    output_high(pin_A3);
    output_B(tab[millier]);
    output_low(pin_A4);
    delay_ms(1);
    output_high(pin_A4);
    }
    }
    du coup si je fais frequence = CCP_1 ; je me retrouve avec 9999...
    Dernière modification par mortaurat ; 11/07/2009 à 17h27.

  32. #26
    sdec25

    Re : mesure de frequence: CCP.

    Citation Envoyé par mortaurat Voir le message
    l'affichage fonctionne correctement lorsque je suprime tout ce qui concerne les interruptions...
    j'arrive à afficher tout ce que je veux...
    Tu n'as que l'interruption CCP ?
    C'est vrai qu'utiliser frequence dans le main alors qu'elle est constamment modifiée par interruption c'est pas la meilleure chose à faire.
    D'ailleurs pourquoi utiliser les interruptions pour faire ça et ne pas tout faire dans le main ?
    Dernière modification par sdec25 ; 11/07/2009 à 17h25. Motif: orthographe

  33. #27
    mortaurat

    Re : mesure de frequence: CCP.

    Citation Envoyé par sdec25 Voir le message
    Tu n'as que l'interruption CCP ?
    C'est vrai qu'utiliser frequence dans le main alors qu'elle est constamment modifiée par interruption c'est pas la meilleure chose à faire.
    D'ailleurs pourquoi utiliser les interruptions pour faire ça et ne pas tout faire dans le main ?
    Oui j'ai que l'interruption CCP.
    Je ne vois pas comment faire pour mesurer rapidement une frequence sans interruptions.

  34. #28
    sdec25

    Re : mesure de frequence: CCP.

    Citation Envoyé par mortaurat Voir le message
    du coup si je fais frequence = CCP_1 ; je me retrouve avec 9999...
    Je parie que si tu la divises par 5 tu auras à peu près 2222.

    Je ne vois pas comment faire pour mesurer rapidement une frequence sans interruptions.
    Tu peux attendre le flag d'interruption dans le main.
    Sinon il faut synchroniser l'irs et le main. Par exemple attendre que la capture soit terminée dans le main.
    La capture est réactivée automatiquement ou pas ? Si oui, ça ne sert à rien de faire plein de capture si on n'en utilise qu'une pour l'affichage.

  35. #29
    mortaurat

    Re : mesure de frequence: CCP.

    Citation Envoyé par sdec25 Voir le message
    Je parie que si tu la divises par 5 tu auras à peu près 2222.
    ca affiche 2168, mais c'est plutôt instable

    Tu peux attendre le flag d'interruption dans le main.
    Sinon il faut synchroniser l'irs et le main. Par exemple attendre que la capture soit terminée dans le main.
    La capture est réactivée automatiquement ou pas ? Si oui, ça ne sert à rien de faire plein de capture si on n'en utilise qu'une pour l'affichage.
    normalement CCP ne s'arrete jammais, et il mesure à chaque front montant de l'horloge.
    J'ai un peut peur que lorsque je rajouterais la partie mesure de tension, l'affichage soit trop lent... Mais bon je verrais .

  36. #30
    sdec25

    Re : mesure de frequence: CCP.

    ca affiche 2168, mais c'est plutôt instable
    ok, donc ça correspond à peu près à la fréquence de 450Hz.

    Comme tu ne fais plus rien dans la routine d'interruption tu peux désactiver l'interruption.

Sur le même thème :

Page 1 sur 2 1 DernièreDernière

Discussions similaires

  1. mesure de frequence
    Par xlt1200 dans le forum Électronique
    Réponses: 15
    Dernier message: 02/08/2012, 16h43
  2. [Génétique] Mesure de fréquence de recombinaison
    Par Lena87 dans le forum Biologie
    Réponses: 0
    Dernier message: 07/01/2009, 15h50
  3. Mesure de fréquence
    Par Rochal dans le forum Électronique
    Réponses: 4
    Dernier message: 23/04/2008, 16h42
  4. Mesure de frequence de vibration
    Par master-of-sorrow dans le forum Électronique
    Réponses: 6
    Dernier message: 02/02/2008, 10h53
  5. mesure de la fréquence du son
    Par Astro boy dans le forum Physique
    Réponses: 1
    Dernier message: 22/09/2005, 19h25