Pic 18F2455 mesure de fréquence
Répondre à la discussion
Affichage des résultats 1 à 11 sur 11

Pic 18F2455 mesure de fréquence



  1. #1
    invitedf66cb3b

    Pic 18F2455 mesure de fréquence


    ------

    Bonjour!

    Dans le cadre d'un projet de robotique je dois, à l'aide d'un PIC18F2455 mesurer la fréquence d'un encodeur moteur.
    J'ai réussi à programmer quelque chose qui me semble cohérent, mais ça ne marche pas...
    La fréquence voulue est 17kHz (qui est égale au rapport cyclique de 128, 50%). Je fausse la valeur du PWM de départ pour voir qu'il corrige bien.

    Voila mon code:

    Code:
    unsigned int duty_cycle = 0x00;                   // duty_cycle est une variable de type INT
    unsigned long mesure = 0x00;                     // mesure est une variable de type LONG
    unsigned long result = 0x00;                       // result est une variable de type LONG
    
    void PWM1_Init();                                      // Déclaration des fonctions du PWM
    void PWM1_Set_Duty(duty_cycle);
    void PWM1_Start();
    
    void main()                                               // Programme principal
    {
         TRISC.B2=0;                                      // Initialisation des entrées/sorties
         TRISA.B4=1;                                      
    
         duty_cycle=140;                                 // Initialisation du rapport cyclique
    
         INTCON.GIE=0;                                  // Initialisation pour le timer0
         INTCON.TMR0IE=0;
         T0CON.TOSC=1;
         T0CON.TOSE=0;
         T0CON.PSA=1;
         T0CON.T08BIT=0;
         
         PWM1_Init(20000);                          // Initialisation du PWM
         PWM1_Set_Duty(duty_cycle);
         PWM1_Start();
    
         delay_ms(2000);                            // Attente de 2 seconde
         mesure=0.0;
    
         while(1)                                         // Boucle principale
         {
                  TMR0H=0;                            // Mise à 0 des valeurs pour la prochaine mesure
                  TMR0L=0;
    
                  T0CON.TMR0ON=1;               // Mesure sur 10ms
                  delay_ms(10);
                  T0CON.TMR0ON=0;
    
                  delay_ms(200);                      // Attente de 200ms
                  mesure=TMR0H<<8|TMR0L;    // Sauvrgarde de la valeur mesurée 
    
                  mesure*=100;                       // Calcul de la fréquence
                  result=mesure;
    
                  if(result>=17001)                   // SI la fréquence est plus grande que 17kHz
                  {
                       duty_cycle--;                    // ALORS on décrémente le rapport cyclique du PWM
                  }
    
                  if(result<=16999)                  // SI la réquence est plus petite que 17kHz
                  {
                       duty_cycle++;                 // ALORS on incrémente le rapport cyclique du PWM
                  }
    
                  PWM1_Set_Duty(duty_cycle);  // Mise à jour du rapport cyclique
          }
    }
    Mon programme fonctionne ainsi:
    Hormis toutes les initialisation et les déclaration, je lance le timer0 (comme compteur) pour compter le nombre de flanc, venant de l'encodeur, durant 10ms. Ensuite, je multiplie le nombre de flanc que j'ai eu par 100 pour avoir le total en 1 seconde.

    La correction se fait grâce au 2 "if" qui incrémente dans le cas ou la vitesse est inférieur et vice versa.

    Le résultat? Le PWM s'incrémente jusqu'a la vitesse max (255) pour recommencer à 0, remonte jusqu'à 255) et recommence à 0 et ainsi de suite...

    Pourriez-vous m'aider s'il vous plaît ?
    Dites moi si vous n'avez pas assez d'infos pour m'aider...

    Merci et bonne journée!

    Romain.

    -----

  2. #2
    paulfjujo

    Re : Pic 18F2455 mesure de fréquence

    bonjour,


    il y a incoherence entre ta mesure de frequence echantilonnée à 10mS
    et la fourchette de test à +- 1Hz pres.

    17000Hz sur un fenetre de 10mS => 170 points multiplié par 100 17000Hz
    17001Hz 170 points 17000Hz
    17100Hz 171 points 17100Hz

    Pourquoi mettre un delay de 200mS
    Autant mesurer la frequence sur 200ms et multiplier par 5...ou 250ms et multiplier par 4
    Il faut aussi tenir compte des temps de raction mecanique ..et amortier le tout
    Le demarrage se fait à consigne nulle ?



    tu pourrais aussi utiliser une mesure de periode avec CCP et Timer1
    et en deduire la frequence.

  3. #3
    invitedf66cb3b

    Re : Pic 18F2455 mesure de fréquence

    Salut Paulfjujo, et merci pour ta réponse!

    Citation Envoyé par paulfjujo Voir le message
    17000Hz sur un fenetre de 10mS => 170 points multiplié par 100 17000Hz
    17001Hz 170 points 17000Hz
    17100Hz 171 points 17100Hz
    Je comprend. Mais alors comment faire pour améliorer cette incohérence?

    Citation Envoyé par paulfjujo Voir le message

    Pourquoi mettre un delay de 200mS
    Autant mesurer la frequence sur 200ms et multiplier par 5...ou 250ms et multiplier par 4
    Il faut aussi tenir compte des temps de raction mecanique ..et amortier le tout
    Le demarrage se fait à consigne nulle ?
    Le démarrage de fait à un PWM de 140/255, je deverais faire une rampe d'accélération?

    Le temps de réaction ou de traction mécanique? La mon but étant juste de voir si la mesure se fait correctement, si la correction est juste. J'améliorerai par la suite...

    Tu a raison pour la mesure sur 200ms je vais essayer de changer sa. Et directement, le problème de la fourchette sera réglé...

    Citation Envoyé par paulfjujo Voir le message
    tu pourrais aussi utiliser une mesure de periode avec CCP et Timer1
    et en deduire la frequence.
    J'ai peur de ne pas avoir compris se que tu veux dire. Il faut savoir que par la suite, je n'aurai pas un delay de 10ms (ou 200ms) mais un timer qui comptera à la place, pour que je puisse utiliser une interruption dans le cas ou j'en ai besoin...

    Comment mesurer la période avec le CCP et un timer?

    Merci en tout cas!
    Bonne journée

  4. #4
    invitedf66cb3b

    Re : Pic 18F2455 mesure de fréquence

    Re!

    Si j'ai mis un delay de 200ms c'est pour ralentir la progression et pouvoir voir le changement sur l'oscilloscope. C'est une ligne que j'effacerai par la suite...

    Je viens d'essayer avec la mesure sur 200ms, et pas de changement, le moteur commence à 140, monte jusqu'à 255 (pleine vitesse) et tombe à 0 pour remonter jusqu'à 255.

    Ce qui veut dire que le PWM s'incrémente, autrement dit la valeur que je mesure est toujous plus petite ou égale à 16999Hz.
    Comment contrôler? Etant donné que je programme un PIC et que je n'ai pas de moyen pour le débugger in-Circuit ? Comment savoir si la mesure mesure comme il faut (dans les bonne valeur => ~17000) ?

    Merci d'avance!

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

    Re : Pic 18F2455 mesure de fréquence

    Re denouveau!

    J'ai aussi corrigé la déclaration des E/S. J'ai mis:

    TRISA.T0CKI=1;

    pour déclarer la pin d'entrée du timer0, mais ça ne marche toujours pas, il ne mesure rien j'ai l'impression...


  7. #6
    invitedf66cb3b

    Re : Pic 18F2455 mesure de fréquence

    C'est ENCORE moi...

    Je pense que vous aviez deviné que je suis entrain d'essayer de trouver la solution, voila mon avancement:
    J'ai mis sur le PORTB.RB4 et le RB5 deux sortie témoin que j'active si le programme entre dans la condition pour incrémenter ou décrémenter.

    Il faut savoir que je lance le PWM à une valeur supérieur à celle que je veux atteindre, donc il est censé entrer dans la première condition pour décrémenter le PWM. Or il l'incrémente sans arrêt.

    En ce qui concerne mes temoins, celui qui temoigne l'incrémentation est à 1 durant un court instant (je ne saurais pas vous dire combien) et l'autre ne s'active jamais. A croire qu'il n'entre jamais dans la condition de décrémentation.

    Je mesure la fréquence de l'encodeur et il démarre à 18kHz (encodeur sur l'axe du moteur et non sur la roue). Alors selon le programme, si il mesure une valeur plus grande que 17001 il deverait décrémenter le PWM de 1, alors qu'il fait l'inverse. Il incrémente alors que la condition n'est pas remplie.

    Si quelqu'un voit ou je fais une erreur ou pourrait m'aider pour dépanner cette histoire, il serait gentil de me réponde (désolé pour le spam de message...)

    Merci beaucoup

  8. #7
    invitedf66cb3b

    Re : Pic 18F2455 mesure de fréquence

    Personne ne peut m'aider?

  9. #8
    invitedf66cb3b

    Re : Pic 18F2455 mesure de fréquence


  10. #9
    paulfjujo

    Re : Pic 18F2455 mesure de fréquence

    bonjour,

    tu peux rajouter un uart (rs232) et envoyer la mesure
    a chaque tour de boucle sur un terminal.
    ou voir via le pickit2...

  11. #10
    RicounetZap

    Re : Pic 18F2455 mesure de fréquence

    Bonjour

    Personnellement, j'ai un doute sur ta ligne : mesure=TMR0H<<8|TMR0L;
    Vu que tes 2 registres sont sur 8 bits, cela donne un résultat sur 8 bits.
    Du moins je suppose que le compilateur effectue la première opération, c'est à dire la rotation d'un registre 8 bits -> résultat sur 8 bits
    puis il fait le | d'un registre 8 bits avec un autre registre 8 bits -> résultat sur 8 bits
    puis affectation du résultat (8 bits) dans une variable 32 bits

    Vérifies juste en décomposant ton code :
    mesure = TMR0H;
    mesure = mesure << 8;
    mesure = mesure | TMR0L;

    Cordalement
    N'importe quoi, for ever :-)

  12. #11
    paulfjujo

    Re : Pic 18F2455 mesure de fréquence

    bonjour
    Citation Envoyé par Trantor Voir le message
    Il faut savoir que je lance le PWM à une valeur supérieur à celle que je veux atteindre, donc il est censé entrer dans la première condition pour décrémenter le PWM. Or il l'incrémente sans arrêt.

    tu utilises un entier 16 bits Duty-cycle comme variable pour le PWM
    mais je pense qu'il faut un byte pour le limiter dans la fouchette 0 à 255 ,
    tu l'incremente sans gerer de butee, donc quand il passe over 255, il retombe à 0100 (byte=0) et recommence...
    de meme decrementer de 0 à -1 , => FFFF => byte=255

    Fait aussi un essai avec une plus grande fourchette , vu que la resolution est de +-100Hz avec 10mS d'echantionnage

    Rajoute la sortie de ta mesure de frequence sur un UART ..pour etre sur de cette mesure !
    ou teste avec cet exemple de mesure de frequence en utilisant les timers ,
    en gerant les debordements et surtout LE RESTE DU PRESCALER !
    avec sortie sur RS232


    Code:
    //27/12/2011
    
    //MPLAB           8.63.00.00    Certified
    //Windows XP      5.1.2600.2 Service Pack 3n\a
    #include"p18f252.h"
    #define p18f252
    
    // config faite par MPlab C18 , car pas de coche !
    //config du PIC
    #pragma config OSC = HS
    #pragma config PWRT = ON
    #pragma config WDT = OFF
    #pragma config BOR = OFF
    #pragma config BORV = 42
    #pragma config LVP = OFF
    
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <delays.h>
    #include <string.h>
    #include <usart.h>   // pour fonctions UART
    #include <adc.h>
    #include <ctype.h>
    #include <portb.h>
    #include <timers.h>
    #include <math.h>
    #include "../_common/Rs232.h"
    
    /*
    =========== HARDWARE ====================
    PIC 18F252  microchip  avec Bootoader installé en fond de memoire
    27 pf  Q=20Mhz 27pF  ** nota: mettre Q=10Mhz pour bootloader!
    Interface 2T pour liaison UART TTL <-> RS232 38400 bauds
    PortB
    B0  21  Input
    B1  22  input = BP ILS.
    B2  23  RS_PIN  LCD
    B3  24  E_PIN   LCD
    B4  25  DATA    LCD
    B5  26  DATA    LCD
    B6  27  DATA    LCD
    B7  28  DATA    LCD
    
    PORTA
    A0   2
    A1   3
    A2   4  output -> force Freq input impulse to RA4 trough 74HCT to know prescaler value
    A3   5  output  1= mesure  0= stop
    A4   6  input  <--- Freq input from 74HCT132
    A5   7
    
    PORTC
    C0   11
    C1   12
    C2   13  <- CCP1 input  <- sortie monostable 74123
    C3   14
    C4   15
    C5   16  NC
    C6   17  TX  RS232   UART Harware
    C7   18  RX  RS232   UART Hardware
    ====================================================
    */
    
    #ifndef Byte
    #define Byte unsigned char
    #endif
    #define CLS 12
    #define BS 8
    #define TAB 9
    #define CR 13
    #define LF 10
    #define Bell 7
    #define ON 0	// logique inverse avec led tiree au +5V
    #define OFF 1
    #define Quartz 20
    
    rom const char chaine0[]="...";
    rom const char chaine1[]="Port comm 38400 ouvert \r\n"; // String en ROM
    rom const char chaine2[]="Q=20Mhz  \r\n";
    rom const char chaine3[]="Frequencemetre 1Hz .. 999MHz";
    rom const char chaine4[]=" ";
    rom const char chaine5[]="                   ";
    rom const char chaine6[]=" \r\n";
    // Attention sous VB6
    // verifier l'ordre CRLF et non pas LFCR, sinon on voit 2 car non imprimable
    // et pas de changement de ligne
    rom char *RS_Str[]={chaine0,chaine1,chaine2,chaine3,chaine4,chaine5,chaine6,};
    
                       //   1234567890123456
    rom const char nokia00[]="  Freqencemetre ";
    rom const char nokia01[]=" 18F252         ";
    rom const char nokia02[]="  MPLAB C18     ";
    rom const char nokia03[]=" 27 Janv 2012   ";
    rom const char nokia04[]="                ";
    rom const char nokia05[]=" Over !!!       ";
    rom const char nokia06[]="                ";
    rom const char nokia07[]="                ";
    rom const char nokia08[]="                ";
    rom const char nokia09[]="                ";
    
    rom char *Nokia_Str[]={nokia00,nokia01,nokia02,nokia03,nokia04,nokia05,nokia06,
          nokia07,nokia08,nokia09};
    
    char chaine[6];				// pour itoa
    float freq;
    
    #define BP_Start        PORTBbits.RB1
    
    //unsigned char Drapeaux ;     // 8 flags
    struct chbits {
                     unsigned Running:1;
                     unsigned Standby:1;
                     unsigned Elligible:1;
                     unsigned Accumule:1;
                     unsigned Blc:1;
                     unsigned OneShot:1;
                     unsigned Fill:1;
                     unsigned Lcd:1;
                   } Drapeaux;
    
    #define OUT_RS232 Drapeaux.Lcd=0;
    #define OUT_LCD Drapeaux.Lcd=1;
    
    Byte receive;
    char error;
    char EtatCf;
    signed char Ve;
    unsigned int  NbMes;
    Byte Allume_led;
    Byte Dummy;
    unsigned short int i,j,k,l ;
    static unsigned int count_100mS = 0;
    static unsigned long CumulTE;
    unsigned int M;
    unsigned long Periode;
    unsigned long Maxima;
    unsigned long Minima;
    float F1,F2,F3;
    
    unsigned int tWord,tOld, tNew;
    char error;
    char edge = 0;
    char capture = 0;
    char Texte[64];
    char *txt;
    float Freq;
    float Coeff;
    
    /*
    int PutStr_RS(unsigned char *s);
    void Put_RS(unsigned char * untel);
    void CRLF(void);
    */
    void InterruptHandlerHigh (void);
    void Init_Hardware(void);
    void fltToa (float x, unsigned char *str,char precision);
    
    
    //gestionnaire d'interruption
    //------------------------------
    // High priority interrupt vector
    #pragma code InterruptVectorHigh = 0x08
    void InterruptVectorHigh (void)
    {
      _asm
        goto InterruptHandlerHigh //jump to interrupt routine
      _endasm
    }
    
    
    // High priority interrupt routine
    #pragma code
    #pragma interrupt InterruptHandlerHigh
    void InterruptHandlerHigh ()
    {
      static char i ; // doit etre statique pour conserver sa valeur entre les IT
      static char C ;
      static int T;
    //======== SERIAL======================
    // Traitement IT Timer1 16bits
    if(PIR1bits.TMR1IF==1)
    {
     WriteTimer1(3035); // init pour 100mS
     PIR1bits.TMR1IF = 0;
      count_100mS = count_100mS  + 1;
     }
    // Traitement IT Timer0 16bits
    if(INTCONbits.TMR0IF==1)
    {
     INTCONbits.TMR0IF = 0;
     CumulTE++;
     }
    
    if(PIR1bits.RCIF) // si un car arrive
       {
       C =ReadUSART(); // le lire => RAZ  RCIF
       if(RCSTAbits.FERR || RCSTAbits.OERR)
         {
          RCSTAbits.CREN = 0 ; RCSTAbits.CREN= 1 ;
         }
        while(BusyUSART()); // par sécurité
        if (PORTBbits.RB1==0) WriteUSART(C); // echo
         if( C == BS)
            {
             if(i>0){
                 i--;  }
            }
          else {
          if(C != CR && i<MAX_LEN)
          {
            buffer[i++]=C ; // stockage
           }else
           {
             buffer[i]='\0'; // fin de chaîne si CR
             i=0;
             received =1;
           }
        }
     }
    
    //  -- voir Interrupt_CCP1.h----
    
    }
    
    // fin de routine interrupt
    //==========================================
    
    
    
    
    
    void Write_Word(unsigned int M,char Sign,char Bold)
    {
    unsigned int i,k,l;
    unsigned long M1;
     valtxt=&Entree[0];
     if (Sign>1) return;
     if (Sign==0)
      {       M1=M;
            ultoa(M1,valtxt);
      }
      else itoa(M,valtxt);
     if (Drapeaux.Fill)
     {
      k=strlen(Entree);
      for (i=0;i<k;i++) Entree[4+Sign-i]=Entree[k-i-1];
      for (i=0;i<(5+Sign-k);i++)
      {if (Drapeaux.Blc) Entree[i]='0'; else Entree[i]=' ';}
     }
     Entree[5+Sign]=0;
    #ifdef NOKIA
     if (Drapeaux.Lcd==1) nokia_print_str(valtxt,Bold); else k=PutStr_RS(valtxt);
     #else
     k=PutStr_RS(valtxt);
    #endif
    }
    
    void fltToa (float x, unsigned char *str,char precision)
    {
    /* converts a floating point number to an ascii string */
    /* x is stored into str, which should be at least 30 chars long */
    unsigned char *adpt;
    int ie, i, k, ndig;
    double y;
    adpt=str;
    ndig = ( precision<=0) ? 7 : (precision > 22 ? 23 : precision+1);
    ie = 0;
    /* if x negative, write minus and reverse */
    if ( x < 0)
      {
      *str++ = '-';
      x = -x;
      }
    /* put x in range 1 <= x < 10 */
    if (x > 0.0) while (x < 1.0)
      {
      x *= 10.0;		// a la place de =*
      ie--;
      }
    while (x >= 10.0)
      {
      x = x/10.0;
      ie++;
     }
     ndig += ie;				// a la place de =+
    //round. x is between 1 and 10 and ndig will be printed to
    // right of decimal point so rounding is ...
    for (y = i = 1; i < ndig; i++)
      y = y/10.;
    x += y/2.;
    if (x >= 10.0) {x = 1.0; ie++;}
    if (ie<0)
      {
       *str++ = '0'; *str++ = '.';
       if (ndig < 0) ie = ie-ndig;
       for (i = -1; i > ie; i--)  *str++ = '0';
      }
    for (i=0; i < ndig; i++)
      {
      k = x;
      *str++ = k + '0';
      if (i ==  ie ) *str++ = '.';
      x -= (y=k);
      x *= 10.0;
      }
    *str = '\0';
    //return (adpt);
    }
    
    void print_flt(float W,int NbDeci,char Bold)
    {long lWhole;
     unsigned int ulPart;
     Drapeaux.Fill=0;
     lWhole=(long)(W);
     ulPart=(unsigned int)((W*(float)NbDeci)-(float)(lWhole*NbDeci));
     ultoa(lWhole,&Texte[0]);
     #ifdef NOKIA
     if (Drapeaux.Lcd) nokia_print_str(Texte,Bold);else k=PutStr_RS(Texte);
     if (Drapeaux.Lcd) nokia_printchar('.',Bold); else  Put_RS('.');
     #else
     k=PutStr_RS(Texte);
     Put_RS('.');
     #endif
      Write_Word(ulPart,0,Bold);
    }
    
    void Decompile_byte(Byte un) {
    Byte masque;
      masque = 0x80;
      while (masque > 0u )
     {
      if (un & masque)
           Put_RS(49u);  //  '1'
        else
           Put_RS(48u);  //  '0'
    
        masque =masque >>1;
         }
    }
    
    void Octet2Hex(unsigned char number)
    {
    char high,low;
      // high nibble
      high = ((number & 0xF0) >> 4) + 48; // + '0'
      if (high > '9')
        high =high + 7;
     // low nibble
      low = (number & 0x0F) + 48;          // +'0' low nibble
      if (low > '9')                       // '9'= 57u
        low += 7;                         // > '9'
       Put_RS(high);
       Put_RS(low);
       Put_RS('h');
     }
    
    
    void Init_Hardware()
     {
     #ifdef p18F258
       CANCON=0x00;     //   0b 000 0  0000    request disable mode
       CANSTAT =0x00;  //    0b 001 0 000 0    disable mode no interrupt
     #endif
       PORTB = 0xFF;
       TRISB = 0xFF;
       TRISBbits.TRISB0=1;   	// B0 <- IR input
       TRISBbits.TRISB1=1;   	// B1 input for debug echo reception
       TRISBbits.TRISB2=1;   	// B2 BP Start
       TRISBbits.TRISB3=1;		// B3 BP gamme
       TRISBbits.TRISB4=1;		// B4 not used
       TRISBbits.TRISB5=1;		// B5 not used
       TRISBbits.TRISB6=1;       //  B6 not used
       TRISBbits.TRISB7=1;       //  B7 not used
    
          // ATTENTION a l'ordre des canaux ANALOGIQUES !!!
      ADCON0 =0 ;
      ADCON1=0x07;           // No analog input on Port A
      TRISA = 0b0010010 ;   // PORTA ouput except RA1 et RA4 = Digital input
    
      PORTC = 0xFF;          // set PORTC to $FF
      TRISC = 0b10000110;
      TRISCbits.TRISC0 = 0;
      TRISCbits.TRISC1 = 0;
      TRISCbits.TRISC2 = 1; //RC2/CCP1 en entree
      TRISCbits.TRISC3 = 0;
      TRISCbits.TRISC4 = 0;
      TRISCbits.TRISC5 = 0;
      TRISCbits.TRISC6 = 0;  // TX - Set as Output UART RS232 and Bootloader
      TRISCbits.TRISC7 = 1;  // RX - Set Receive pin for UART RS232 and Bootloader
     }
    
    
    
    void main(void)
    {
     Init_Hardware();
    
     Init_RS();
     Put_RS(CLS);
     Tempo(150000L);
     txt=&Texte[0];
     strcpypgm2ram(txt,RS_Str[1]); k=PutStr_RS(txt);
     strcpypgm2ram(txt,RS_Str[2]); k=PutStr_RS(txt);
     strcpypgm2ram(txt,RS_Str[3]); k=PutStr_RS(txt);
     Tempo(100000L);
    
    // configure Timer0 comme compteur d'impuls
      T0CON=0x00;
      T0CONbits.TMR0ON=0;   //stops Timer0
      T0CONbits.T08BIT=0 ;  //mode 16 bits
      T0CONbits.T0CS=1;     //Transition sur RA4 (T0CKI pin)
      T0CONbits.T0SE=0;     //increment sur front montant
      T0CONbits.PSA=0;      //1= Sans Prescaler   0=avec prescaler !
      T0CONbits.T0PS2=0;    // prescaler =1:8
      T0CONbits.T0PS1=1;
      T0CONbits.T0PS0=0;
    
    
    // configure le TIMER1
      T1CON=0x00;
      T1CONbits.RD16=1;       // timer mode 16 bits
      T1CONbits.T1CKPS1=1;    // Prescaler =1:8
      T1CONbits.T1CKPS0=1;    // Prescaler
      T1CONbits.T1OSCEN=0;    // Timer1 oscillateur shutt off
      T1CONbits.T1SYNC=1;     // No Synchro
      T1CONbits.TMR1CS=0;     // internal clock = Quartz Fosc/4
      T1CONbits.TMR1ON=0;     // desactive Timer1
      IPR1bits.TMR1IP=1;      // set hihh priority for Timer1
      WriteTimer1(3035);      // 62500*8*4*1/QMhz =>  =100 msec
      PIR1bits.TMR1IF=0;      // raz flag interrupt
      INTCONbits.PEIE = 1;    // enable interupt Peripheriques
    
      PIE1bits.TMR1IE=0;      // Disable Interrupt Timer1
      INTCONbits.GIE = 0;     // active global interrupt
      INTCONbits.GIEL=0;
    
       LATAbits.LATA2=0;
       LATAbits.LATA3=0;
    j=0;
    do
    {
    LATAbits.LATA3=0;
    capture=0;
    CumulTE=0;
    tWord=0;
    tNew=0;
    tOld=0;
    count_100mS =0;
    WriteTimer0(0);
    WriteTimer1(3035);     // 62500 cycles * 8 => 100mS
    INTCONbits.TMR0IE=0;    // no interrupt sur debordement timer0
    INTCONbits.TMR0IF=0;
    RCONbits.IPEN=1;        // Interruption prioritaires activées
    PIR1bits.TMR1IF=0;
    PIE1bits.TMR1IE=0;      // Enable Interrupt Timer1
    // start mesure
    INTCONbits.GIEL=0;
    INTCONbits.GIE=1;		// Toutes les IT démasquées autorisées
    T0CONbits.TMR0ON=1;   // comptage Timer0 On
    T1CONbits.TMR1ON=1;   // arme timer1
    LATAbits.LATA3=1;
    do
    {
     // traité via interrupt !!!!!
     if ( INTCONbits.TMR0IF==1)
       {
            CumulTE++;               // cumul debordement comptage du Timer0
          INTCONbits.TMR0IF=0;
        }
      if(PIR1bits.TMR1IF==1)
       {   WriteTimer1(3035);
           count_100mS ++ ;
           PIR1bits.TMR1IF=0;
      }
    
     }while (count_100mS < 10 );    // 10 x 100mS soit 1 seconde ecoulee
    
     // stop Mesure
     T0CONbits.TMR0ON=0;
     LATAbits.LATA3=0;
     INTCONbits.GIE=0;
     LATAbits.LATA2=0;
     T1CONbits.TMR1ON=0;     // comptage Timer1 Off
    
    
     CRLF();
     Write_Word(j,0,0);
      Put_RS(9);
      Write_Word(count_100mS,0,0);
     CRLF();
     j++;
     // valeurs cumulee via compteur Timer0
     Put_RS('C');; Put_RS('u'); Put_RS('m');; Put_RS('u');  Put_RS(9);
     ultoa(CumulTE,txt);
     k=PutStr_RS(txt);
     CRLF();
    
     Put_RS('F');  Put_RS('1');Put_RS(9);
     F1=(float) CumulTE *65536.0* 8.0 ;
     fltToa (F1, txt,1);
     k=PutStr_RS(txt);
     CRLF();
    
     // Reste dans le timer0
     Put_RS('t');; Put_RS('W'); Put_RS(9);
     tWord=ReadTimer0();
     Write_Word(tWord,0,0);
     CRLF();
    
     tNew=0;
     /* reste dans le prescaler
     tOld=0;
     T0CONbits.TMR0ON=1;
     while (ReadTimer0()==tWord)
     {
        LATAbits.LATA2=1;
       Tempo(100L);
        tOld++;
       LATAbits.LATA2=0;
        Tempo(100L);
      }
    
     T0CONbits.TMR0ON=0;   // comptage Timer0 Off
     LATAbits.LATA2=0;
    
     tNew=256-tOld;   // complement du prescaler=256
    if(tNew>256) tNew=0;
     Put_RS('t'); Put_RS('N'); Put_RS('=');
     Write_Word(tNew,0,0);
     CRLF();
     */
     F3=(float)tWord * 8.00; //*256 + (long)tNew;
     Put_RS('F');; Put_RS('2'); Put_RS(9);
     F2=F3 + F1;
     fltToa (F2, txt,1);
     k=PutStr_RS(txt); Put_RS(9); Put_RS('H'); Put_RS('z');
     CRLF();
     Put_RS('F');; Put_RS('r');Put_RS('e');; Put_RS('q'); Put_RS(9);
     Freq=F2 / 4.0;
     fltToa (Freq, txt,1);
     k=PutStr_RS(txt); Put_RS(9); Put_RS('H'); Put_RS('z');
     CRLF();
    
    
     CRLF();
     Tempo(200000L);
    }while(1);
    }

Discussions similaires

  1. Mesure de fréquence pic 16f628
    Par Ticlem dans le forum Électronique
    Réponses: 18
    Dernier message: 04/03/2011, 19h43
  2. Communication USB PC <-> Pic 18F2455
    Par invitef5e98bfb dans le forum Électronique
    Réponses: 5
    Dernier message: 17/05/2010, 16h02
  3. 18f2455?
    Par invited1b9fc52 dans le forum Électronique
    Réponses: 1
    Dernier message: 04/02/2010, 22h42
  4. [PIC] Mesure d'une fréquence
    Par invite91ed4b59 dans le forum Électronique
    Réponses: 8
    Dernier message: 18/02/2007, 21h31
  5. Réponses: 11
    Dernier message: 15/03/2006, 15h17
Découvrez nos comparatifs produits sur l'informatique et les technologies.