CCP capture 16F877a
Répondre à la discussion
Affichage des résultats 1 à 9 sur 9

CCP capture 16F877a



  1. #1
    ilyasse192

    Angry CCP capture 16F877a


    ------

    salut, je suis entrain de réaliser un analyseur des signaux PWM. j'utilise CCP1 (16f877a) pour capter le deux fronts
    j'ai fais le programme mais quand je lance la simulation sur isis il me donne des nombres qui se répète même si je change TON et TOFF ?? ...
    voici mon code:
    Code:
    void init()     {
      TRISC=0x0F      ; 
      CCP1IE_bit=1    ;   //activer module CCP
      CCP1CON=0x04 ;  // front montant 
      TMR1IF_bit= 0   ;  
      T1CON= 0x38    ;   //Prescaler 1:8 TMR1(max)
      INTCON=0xC0    ;  // autorise lé interruptions masquée 
      TMR1IE_bit= 1  ;
     
    void interrupt(){
    
      if(CCP1IF_bit) {
        
       CCP1IF_bit=0  ;
        CCP1CON=0   ; //stop CCP1 
       
       if(CCP1M0_bit==1){                  //si front montant 
       
        valu = CCPR1L*(t1+1) | CCPR1H*(t1+1) << 8; //copié la valeurs du timer1
        tad[i]=valu;                             // enregistrer la valeur sur un tableau
        i++        ;
        CCP1M0_bit=0  ;                     // changé le front de lecture (descendant)
                    }
    
       else       {                               // si front descendant 
       vald = CCPR1L*(t1+1) | CCPR1H*(t1+1) << 8;// copié la valeurs du timer1 
        tad[j]=vald;                           // enregistrer la valeur sur un autre tableau
        j++       ;
        CCP1M0_bit=1  ;                    // changé le front de lecture (montant) 
                  }
        TMR1L=0;                             // initialiser TMR1 à chaque fin lecture 
        TMR1H=0;
         t=0        ;                              // RAZ compteur de dépassement TMR1
        CCP1CON=0x04   ;                 // autorisé mode capture
       
                  }
      
      if(TMR1IF_bit) {                    
       t++;                                      // compteur depassement++
       TMR1IF_bit=0  ;
                     }
      
      
      if(i==1&j==9){CCP1CON=0;ok=1;} // si le tableau a terminé 10 enregistrement desactiver le module CCP1 pendant l'affichage des enregistrements 
                     }

    -----
    Dernière modification par ilyasse192 ; 28/02/2014 à 02h52.

  2. #2
    ilyasse192

    Re : CCP capture 16F877a

    une petite correction du code, j'ai oublier la remise à 0 du flag CCP1IF_bit

  3. #3
    gauvin95

    Re : CCP capture 16F877a

    Je pense pas que tu auras beaucoup de réponses ici... c'est de la programmation et non de l'elec...

    Poste le plutôt ici >>> Forum Programmation <<<

  4. #4
    mgduc

    Re : CCP capture 16F877a

    Citation Envoyé par gauvin95 Voir le message
    Je pense pas que tu auras beaucoup de réponses ici... c'est de la programmation et non de l'elec...

    Poste le plutôt ici >>> Forum Programmation <<<
    C'est bien de l'électronique, bien que c'est de la programmation la question a sa place ici car c'est la programmation d'un composent électronique.

    Si jamais il y a un problème hardware, je doute que le forum programmation soit de grand aide...
    Dernière modification par mgduc ; 28/02/2014 à 03h22.

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

    Re : CCP capture 16F877a

    merci pour la suggestion

  7. #6
    JPL
    Responsable des forums

    Re : CCP capture 16F877a

    J'ai restauré cette discussion : le doublon en informatique avait été supprimé.
    Si nécessaire elle pourra être transférée dans le forum de programmation.
    Dernière modification par JPL ; 01/03/2014 à 11h24.
    Rien ne sert de penser, il faut réfléchir avant - Pierre Dac

  8. #7
    ilyasse192

    Re : CCP capture 16F877a

    puisque le programme entre dans la routine d'interruption alors le problème se trouve au niveau de récupération des Ton et Toff... je me demande si je dois utiliser des variable float(32bit) au lieu des variable int (16bit) ??

  9. #8
    paulfjujo

    Re : CCP capture 16F877a

    bonsoir,


    pour le cumul des TON TOFF il est biensur preferable d'utiliser des entier long (32 bits)
    par contre ,meme avec un bout de code incomplet j'ai souligné quelques details :

    Code:
    Ou sont les differentes inits de variables (i,j,value,t..)?
    Les variables utitlisees dans l'interrupt ET dans le main doivent etre declaré "volatile".
    
    void init()     {
      TRISC=0x0F      ; 
      CCP1IE_bit=1    ;   //activer module CCP
      CCP1CON=0x04 ;  // front montant 
      TMR1IF_bit= 0   ;  
      T1CON= 0x38    ;   //Prescaler 1:8 TMR1(max)
      INTCON=0xC0    ;  // autorise lé interruptions masquée 
      TMR1IE_bit= 1  ;
     
    l'init englobe l'interrupt ?
    ou il manque l'accolage fermante...de void init()
    
    void interrupt(){
    
      if(CCP1IF_bit) {
        
       CCP1IF_bit=0  ;
        CCP1CON=0   ; //stop CCP1 
       
       if(CCP1M0_bit==1){                  //si front montant 
       
        valu = CCPR1L*(t1+1) | CCPR1H*(t1+1) << 8; //copié la valeurs du timer1
    
    
    C'est quoi "tl+1"  ?
    Là il ya de forts risques de debordements , car  CCPR1L et CPPR1H sont sur 8 bits.
    si tu veux faire des calculs, vaudrait mieux les faire dans le main() ..
    sans voir tout ton code en entier, difficile de comprendre ...
    
    
    
        tad[i]=valu;                             // enregistrer la valeur sur un tableau
        i++        ;
        CCP1M0_bit=0  ;                     // changé le front de lecture (descendant)
                    }
    
       else       {                               // si front descendant 
       vald = CCPR1L*(t1+1) | CCPR1H*(t1+1) << 8;// copié la valeurs du timer1 
    
        tad[j]=vald;                           // enregistrer la valeur sur un autre tableau
     
      C'est le meme tableau ! qui risque d'etre ecrabouillé par les valeurs stockees par tad[i]=valu;
    
    
        j++       ;
        CCP1M0_bit=1  ;                    // changé le front de lecture (montant) 
                  }
        TMR1L=0;                             // initialiser TMR1 à chaque fin lecture 
        TMR1H=0;
         t=0        ;                              // RAZ compteur de dépassement TMR1
        CCP1CON=0x04   ;                 // autorisé mode capture
       
                  }
      
      if(TMR1IF_bit) {                    
       t++;                                      // compteur depassement++
    
    Et tu en fais quoi de ce compteur ?
    Dans chaque mesure etat haut ou etat bas il faudrait en tenir compte pour mettre  à jour
    valu= Valu + t*65536;
    et mem utiliser 2 compteurs de debordements.. different , suivant CCP1M0_bit, pour
    vald=vald+ t2*65536;
    valu et vald : entiers long 32 bits.
    
    
       TMR1IF_bit=0  ;
                     }
      
      
      if(i==1&j==9){CCP1CON=0;ok=1;} // si le tableau a terminé 10 enregistrement desactiver le module CCP1 pendant l'affichage des enregistrements
    Dernière modification par paulfjujo ; 01/03/2014 à 18h23.

  10. #9
    ilyasse192

    Re : CCP capture 16F877a

    bonjour à tous,
    grâce à toi paulfjujo j'ai réussi a adapté votre exemple (que j'ai trouvé sur ton site) de mesure de frequence via CCP1 pour enregistrer l'état des 5bit (TON et TOFF) + LCD ...
    si quelqu'un est intéressé voilà le code :


    Code:
     
     * Project name:
         analyseur PWMs
     * Test configuration:
         MCU:             PIC16F877A
         Oscillator:      HS, 12.0000 MHz
         Ext. Modules:    Character LCD 2x16
                          
         SW:              mikroC PRO for PIC
     
    
    sbit LCD_RS at RB1_bit;
    sbit LCD_EN at RB2_bit;
    sbit LCD_D4 at RB3_bit;
    sbit LCD_D5 at RB4_bit;
    sbit LCD_D6 at RB5_bit;
    sbit LCD_D7 at RB6_bit;
    sbit LCD_RS_Direction at TRISB1_bit;
    sbit LCD_EN_Direction at TRISB2_bit;
    sbit LCD_D4_Direction at TRISB3_bit;
    sbit LCD_D5_Direction at TRISB4_bit;
    sbit LCD_D6_Direction at TRISB5_bit;
    sbit LCD_D7_Direction at TRISB6_bit;
    
    
    char x,y;
    bit ok ;
    char txt1[] = "enregistreur";
    char txt2[] = "signaux PWM";
    char txt3[] = "Ton:";
    char txt4[] = "Toff:";
    char txt5[10];
    char txt6[10];
    char i=0;
    char j=0;
    char count=0;
    unsigned toff,ton,tbas, thaut;
    unsigned long tab1[7];
    unsigned long tay2[7];
    char edge = 0;
    char capture = 0;
    float temps1 = 0;
    float temps2 = 0;
    float distance = 0;
    float distance2 = 0;
    
    void interrupt() {
    
      if(PIR1.CCP1IF){                 //Si PIR1.CCP1IF égal à 1
        if(!edge){                     //Si edge égal à 0
    
          tbas = 256*CCPR1H + CCPR1L;      //garde la valeur de départ
          count=0;
          tab1[i]=tbas;i++;
          edge = 1;                        //edge prend la valeur 1 ( changé la boucle)
          CCP1CON = 0x05;
          //if (ok==1){capture=1;ok=0;}
          }
          
        else{
    
         // ok=1;
          thaut =256*CCPR1H + CCPR1L;     //garde la valeur de fin
          count=0;
          tay2[j]=thaut;j++;
          edge = 0;                      //edge prend la valeur 0
          CCP1CON = 0x04;
        }
        PIR1.CCP1IF = 0;
        if(i==5){capture=1;}
                      //remise à 0 du flag (PIR1.CCP1IF)
      }
        //if(PIR1.TMR1IF){ PIR1.TMR1IF=0;}
        
    }
    
    
    void main() {
    
      char i;
      TRISB = 0;                // PORTB en sortie
      PORTB = 0;                // Initialisation du PORTB
      TRISA = 0;                // PortA en sortie
      PORTA = 0x00;             // Initialisation du PORTA
      TRISC = 0;                // PortC en sortie
      TRISD = 0;                // PortA en sortie
      //PORTD = 0x01;
      Delay_ms(2);
      CCP1CON = 0x04;           // Mode de capture a chaque front descendant
      TRISC.F2 = 1;             // RC2 en entré
      T1CON = 0x21;             // timer1 ON, internal clock Fosc/4, prescaler 1:4
      INTCON.GIE = 1;
      INTCON.PEIE =1;
      PIE1.CCP1IE = 1;           // active la capture par interruption
      PIR1.CCP1IF = 0;           //remise à 0 du flag (PIR1.CCP1IF)
    
      Lcd_Init();                        // Initialisation du LCD
    
      Lcd_Cmd(_LCD_CLEAR);               // Effacer le LCD
      Lcd_Cmd(_LCD_CURSOR_OFF);          // Desactivation du curseur
      Lcd_Out(1,2,txt1);                
      Lcd_Out(2,4,txt2);                
      Delay_ms(2000);
      Lcd_Cmd(_LCD_CLEAR);               // Effacer le LCD
        TMR1L=0;
        TMR1H=0;
        PORTD = 0x00;                     
        Delay_us(200);
        PORTD = 0x01;
        Delay_us(500);
    
        PORTD = 0x00;                     
        Delay_ms(20);
        PORTD = 0x01;
        Delay_ms(25);
    
        PORTD = 0x00;                       
        Delay_ms(12);
        PORTD = 0x01;
        Delay_ms(30);
    
        PORTD = 0x00;                      
        Delay_ms(56);
        PORTD = 0x01;
        Delay_ms(40);
    
        PORTD = 0x00;                     
        Delay_ms(40);
        PORTD = 0x01;
    
    
    
      while(1)
    
      {
        if(capture){
        PIE1.CCP1IE = 0;                 //desactive  la capture par interruption
    
        capture = 0;                     // Capture prend la valeur 0
        CCP1CON = 0x04;                  // Mode de capture a chaque front descendant
        PORTA = 0x01;
        x=0;
        y=0;
        tbas = tab1[x];
        while(1){
    
       // edge++;
        thaut = tay2[y];
        tay2[y]=0;
        toff = ~tbas + thaut+1;
        // toff = thaut+1-tbas  ;
        tab1[x]=0;
        x++;y++;
        tbas = tab1[x];
        ton = ~thaut + tbas+1;
       // ton = tbas+1-thaut;
    
        temps1 =((float)toff*4/3);
        temps1 = (temps1/1000);
        temps2 =((float)ton*4/3);
        temps2 = (temps2/1000);
        floatToStr(temps1,txt5);
        floatToStr(temps2,txt6);
        Delay_ms(200);
        Lcd_Out(1,1,txt3);
        Lcd_Out(2,1,txt4);
        Lcd_Out(1,5,txt5);
        Lcd_Out(2,5,txt6);
        Delay_ms(2000)   ;
        Lcd_Cmd(_LCD_CLEAR);
                         }
        
        i=0;j=0;
        PIR1.CCP1IF = 0;                 //remise à 0 du flag (PIR1.CCP1IF)
        PIE1.CCP1IE = 1;                 // enable interrupt
        Delay_ms(1000);
        
        PORTD = 0x00;                     
        Delay_ms(1);
        PORTD = 0x01;
        Delay_ms(1);
        
        PORTD = 0x00;                      
        Delay_ms(2);
        PORTD = 0x01;
        Delay_ms(2);
        
        PORTD = 0x00;                       
        Delay_ms(10);
        PORTD = 0x01;
        Delay_ms(20);
        
        PORTD = 0x00;                    
        Delay_ms(20);
        PORTD = 0x01;
        Delay_ms(40);
    
        PORTD = 0x00;                    
        Delay_ms(40);
        PORTD = 0x01;
    
        }
      }
    }
    j''envois le signal PWM par la sortie RD0 avec des periode + cycle variable et ça marche supeeer.
    Dernière modification par ilyasse192 ; 06/03/2014 à 06h57.

Discussions similaires

  1. A/n pic 16f877a
    Par narakphysics dans le forum Électronique
    Réponses: 11
    Dernier message: 11/09/2012, 09h39
  2. PWM pic 16F877A
    Par invite735f61e0 dans le forum Électronique
    Réponses: 5
    Dernier message: 07/04/2009, 21h21
  3. pic 16F877A
    Par invite636b8579 dans le forum Électronique
    Réponses: 22
    Dernier message: 01/04/2009, 15h00
  4. PIC 16F877A sur 3V ?
    Par invite2dc206d9 dans le forum Électronique
    Réponses: 17
    Dernier message: 17/02/2008, 20h49
  5. pic 16f877a
    Par invited2ae1532 dans le forum Électronique
    Réponses: 3
    Dernier message: 01/02/2008, 10h49
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...