difficultés à utiliser le CCP1 du 16f876 pour enregistrer trame IR
Répondre à la discussion
Affichage des résultats 1 à 8 sur 8

difficultés à utiliser le CCP1 du 16f876 pour enregistrer trame IR



  1. #1
    roland2pau

    difficultés à utiliser le CCP1 du 16f876 pour enregistrer trame IR


    ------

    Bonjour,

    Je vous écris par ce que j'ai écris un programme en C pour mon PIC16F876 que je teste sur ma platine d’essai easypic v2 (je précise cela pour dire que du côté hardware c’est fiable et que je pense que mon problème vient de mon programme).

    Le but du programme est d’enregistrer une trame Infrarouge de type RC5 (ou similaire) sur la pin RC2 du PORTC de mon PIC16f876. Le pin RC2 est utilisé via le module CCP1 en mode capture.

    Le programme détecte successivement les fronts montants et descendants sur le pin RC2 et enregistre la durée entre chaque fronts successifs dans un tableau d’entier. Puis je souhaite ensuite afficher les valeurs du tableaux sur un afficheur LCD 2*16 caractères connecté au PORTB et configuré en mode 4 bits. Pour l’affichage j’utilise la routine fournie dans un fichier exemple de mikroc (l’IDE de developpement mikroelektronika fourni avec la carte de développement).

    La séquence que j’ai développée est la suivante :

    1/ J’ai configuré le Pin RB0 du portB en entrée et en interruption. Et j’attend un événement sur cette broche pour exécuter le code de la routine d’interruption de RB0. Celle ci consiste à configurer le TIMER1 en interruption et à initialiser celui ci à 0. La pin RB0 est connecté à un bouton poussoir. Un appui sur le bouton poussoir lance la procédure d’acquisition en déclenchant le TIMER1. Comme le TIMER1 est déclenché et que le prescaler est réglé à 1, avec une horloge de 4Mhz, le compteur s’incrémente toute les 1 microsecondes, et compte de 0 à 65536, ce qui équivaut à 65,536 ms. Dans 1 seconde j’ai 1000 ms, donc une acquisition de 1 seconde correspond à 15 * 65.536 ms. Il faut donc 15 débordement du TIMER1 pour 1 seconde. Et donc 150 débordement pour 10 secondes. C’est pourquoi une fois le TIMER1 activer, je surveille ma durée d’acquisition grace à une variable ack_period que j’incrémente de 1 à chaque débordement, et que je compare à 150 dans les autres partie du programme.

    2/ Dans la routine d’IT du CCP1 , j’enregistre la valeur du TIMER1 à chaque fois qu’un front apparaît sur la pin RC2 et j’inverse à le front declencheur.

    3/ Une fois le temps d’acquisition dépassé, je désactive les interruptions et j’affiche la différence des 2 premières valeurs de mon tableau TIMER_VALUE sur l’afficheur LCD.

    Lorsque je compile j’ai aucune erreur. Par contre il n’y a rien qui se passe après qu j’ai chargé mon programme sur le PIC16f876, malgré que les signaux sont bien présent en entrée sur la pin RB0 du PIC pour lancer l’acquisiton, et la trame est bien la (vérification à l’oscilloscope) lorsque j’appuie sur une touche de ma télécommande TV qui est capté par un recepteur TSOP 38 et envoyé sur la pin RC2.

    Pouvez vous m’aider à débloquer la situation SVP ?

    Question supplémentaire : Comment s’executent les Interruptions entre elles ? Y a t il de conflits possibles entre les IT vu que sur le PIC16f876 il n’y a pas de niveau de priorité d’interruption à programmer comme sur un Motorola MC68000 par exemple ?

    Merci d’avance,
    Cordialement
    roland

    Code Source C:

    //*********DECLARATIONS********* ************************
    unsigned int read_TMR1;
    unsigned short i;
    unsigned long TIMER_VALUE[20];
    long unsigned int ack_period;
    long first_pw;
    char txt[10];
    char *text = "1ere largeur d'impulsion:";
    const RISING_EDGE = 0x05;
    const FALLING_EDGE = 0x04;

    //Routine d'interruption

    //****************************** *************************
    void interrupt() {

    //*************************Routi ne d'IT sur RB0*************************** ******
    if (INTCON.INTF) {

    if (ack_period < 150) {
    // Configuration initialisation du TIMER1

    T1CON=1 ; // Configure le TIMER1 avec comme source d'horloge interne Fosc/4

    TMR1L = 0x00; // Initialisation du Timer1 TMR1L = 0x00;
    TMR1H = 0x00 ; // Initialisation du Timer1 TMR1H = 0x00;

    PIE1.TMR1IE = 1; // Autorise les interruptions sur le TIMER1 par débordement
    PIR1.TMR1IF = 0; // RAZ du flag TMR1IF (positionné à un si il y a eu debordement du TIMER1)
    }
    else {

    PIE1.TMR1IE = 0; //
    PIE1.CCP1IE = 0; // Désactive les interruptions
    INTCON.INTE = 0; //
    INTCON.GIE = 0; //
    INTCON.PEIE = 0;

    }



    }

    //*************************Routi ne d'IT du TIMER1************************ ******

    if (PIR1.TMR1IF) {

    ack_period++; // Incrémente le compteur de durée d'acquisition
    PIE1.TMR1IE = 1; // Autorise les interruptions sur le TIMER1 par débordement
    PIR1.TMR1IF = 0; // RAZ du flag TMR1IF (positionné à un si il y a eu debordement du TIMER1)

    }


    //**************************Rout ine d'IT du CCP1************************** ******
    if (PIR1.CCP1IF) {
    //*Etape 4 du "Measuring Pulse Width" CCP Tips 'n Tricks

    read_TMR1 = CCPR1H*256; // On récupère la valeur des registre CCPR1H
    read_TMR1 = read_TMR1 + CCPR1L; // et CCPR1L dans une variable unique
    TIMER_VALUE[i] = read_TMR1;
    i++;

    //*Etape 5 du "Measuring Pulse Width" CCP Tips 'n Tricks

    if (CCP1CON = FALLING_EDGE) CCP1CON = RISING_EDGE;
    else CCP1CON = FALLING_EDGE;

    //Etape 3 du "Measuring Pulse Width" CCP Tips 'n Tricks

    PIE1.CCP1IE = 1; // autorise les interruptions sur CCP1
    PIR1.CCP1IF = 0; // RAZ du flag CCP1IF
    }

    //**********************Fin de la routine d'IT du CCP1**************************
    }

    void main(void)
    {



    //****************************** ****************************** ****************************** ********************//
    //Configuration des registres

    // On utilise CCP1/RC2 (pin13)
    // On configure le PORTC en entrée
    // Oncongigure le PORTB en entrée

    TRISC=0b00000100 ; //configure RC2 en entrée
    TRISB=0b00000001; //configure RB0 en entrée
    PORTC=0b00000000 ; // reinitialise le PORTC
    PORTB=0b00000000 ; // rénitialise le PORTB

    //Configuration du PORTB en interruption
    INTCON.INTE = 1; // Autorise les interruptions sur RB0
    INTCON.INTF = 0; // RAZ du flag d'IT sur RB0




    // Autorise les interruptions périphériques et sur CCP1

    INTCON.GIE = 1; // Positionne les bits GIE, PEIE à 1 pour autoriser les interruptions
    INTCON.PEIE = 1;
    PIE1.CCP1IE = 1; // autorise les interruptions sur CCP1
    PIR1.CCP1IF = 0; // RAZ du flag CCP1IF



    //Configuration du module CCP1

    // Choix du mode du CCP
    CCP1CON = FALLING_EDGE ; // capture sur chaque front descendant, PRESCALER=1


    //****************Initialisation des variables********************* **********
    i=0; //index du tableau de valeur pointe sur la première valeur à enregistrer
    ack_period = 0; // initialise la variable qui compte la durée de l'acquisition



    do{

    if (ack_period >= 150) {

    first_pw = TIMER_VALUE[1]-TIMER_VALUE[0]; //calcule la première largeur d'impulsion
    LongToStr(first_pw, txt ); //convertit l'entier first_pw en chaine de caractère

    Lcd_Init(&PORTB); // Affiche la différence entre les 2
    LCD_Cmd(LCD_CLEAR); // premières valeurs de TIMER_VALUE sur l'afficheur
    LCD_Cmd(LCD_CURSOR_OFF); // LCD 2*16 caractères.
    Delay_ms(1000);
    LCD_Out(1,1, text); //
    Delay_ms(1000);
    LCD_Out(2,6,txt); //

    }
    } while(1);

    }

    -----

  2. #2
    RISC

    Re : difficultés à utiliser le CCP1 du 16f876 pour enregistrer trame IR

    Salut,

    Plusieurs problèmes dans tes interruptions :

    1/ Multi-interruptions
    Dans le cas ou on a plusieurs interruptions actives et surtout si on désactive temporairement une des interruptions, il faut absolument faire ceci :

    Code:
    {
    if( PIE1bits.T1IE && PIR1bits.T1IF)
        {
         ...
        PIR1bits.T1IF = 0;
        }
    else if( INTCONbits.RBIE && INTCONbits.RBIF)
        {
         ...
        INTCONbits.RBIF=0;
        }
    else if( PIE1bits.CCP1IE && PIR1bits.CCP1IF)
        {
         ...
        PIR1bits.CCPIF = 0;
        }
    else 
        { 
         while(1) ) ;  // erreur, on ne devrait jamais venir ici...
        }
    }
    L'ordre des tests détermine l'interruption la plus prioritaire (en général celle qui a la plus haute fréquence).

    2/ On ne touche jamais (ou seulement quand on maitrise très très bien et dans des cas tout à fais rares), les flags GIE, PEIE, xxxIE) DANS les interruptions. C'est une source d'arrachage de cheveux...
    La plupart du temps quand on fait cela c'est qu'on a pas fait ce que j'ai expliqué en 1/

    Modifie ton programme comme indiqué en 1/ et reposte le. Un certain nombre de tes problèmes (voire tous) devraient être déjà résolus...

    a+
    Dernière modification par RISC ; 30/09/2012 à 15h49.

  3. #3
    roland2pau

    Re : difficultés à utiliser le CCP1 du 16f876 pour enregistrer trame IR

    Bonjour RISC,

    Je te remercie pour ta réponse! Finalement j'ai simplifié le code en supprimant les interruptions multiples afin de me concentrer dans un premier temps sur le le fnctionnement du module CCP1.

    Mon nouveau code est le suivant:

    //*********DECLARATIONS********* ************************
    unsigned int read_TMR1;
    unsigned short i;
    unsigned long unsigned TIMER_VALUE[20];
    long unsigned int ack_period;
    long first_pw;
    char txt[16];
    char *text = "1er pw:";
    const RISING_EDGE = 0x05;
    const FALLING_EDGE = 0x04;

    //Routine d'interruption

    //****************************** *************************
    void interrupt() {


    //**************************Rout ine d'IT du CCP1************************** ******
    if (PIR1.CCP1IF) {
    //*Etape 4 du "Measuring Pulse Width" CCP Tips 'n Tricks
    if ( i>3) PORTA=0b00000011; // allume RA0 et RA1 pour montrer que on est bien entré dans
    // la routine d'interruption, donc front bien détecté sur RC2
    read_TMR1 = CCPR1H*256; // On récupère la valeur des registre CCPR1H
    read_TMR1 = read_TMR1 + CCPR1L; // et CCPR1L dans une variable unique
    TIMER_VALUE[i] = read_TMR1;
    i++;

    //*Etape 5 du "Measuring Pulse Width" CCP Tips 'n Tricks

    if (CCP1CON = FALLING_EDGE) CCP1CON = RISING_EDGE;
    else CCP1CON = FALLING_EDGE;

    //Etape 3 du "Measuring Pulse Width" CCP Tips 'n Tricks

    //PIE1.CCP1IE = 1; // autorise les interruptions sur CCP1
    PIR1.CCP1IF = 0; // RAZ du flag CCP1IF
    }

    //**********************Fin de la routine d'IT du CCP1**************************
    }

    void main(void)
    {
    i=0; //index du tableau de valeur pointe sur la première valeur à enregistrer


    LongToStr(i, txt ); //convertit l'entier i en chaine de caractère
    Lcd_Init(&PORTB); // Affiche la différence entre les 2
    LCD_Cmd(LCD_CLEAR); // premières valeurs de TIMER_VALUE sur l'afficheur
    LCD_Cmd(LCD_CURSOR_OFF); // LCD 2*16 caractères.
    Delay_ms(1000);
    LCD_Out(1,1, text); //
    Delay_ms(1000);
    LCD_Out(2,6,txt);

    //****************************** ****************************** ****************************** ********************//
    //Configuration des registres

    // On utilise CCP1/RC2 (pin13)
    // On configure le PORTC en entrée
    // Oncongigure le PORTB en entrée

    TRISC=0b00000100 ; //configure RC2 en entrée
    TRISA=0b00000000; //configure PORTA en sortie
    PORTC=0b00000000 ; // reinitialise le PORTC
    PORTA=0b00000000 ; // rénitialise le PORTA



    // Configuration initialisation du TIMER1

    T1CON=0x01 ; // Configure le TIMER1 avec comme source d'horloge interne Fosc/4

    TMR1L = 0x00; // Initialisation du Timer1 TMR1L = 0x00;
    TMR1H = 0x00 ; // Initialisation du Timer1 TMR1H = 0x00;

    // PIE1.TMR1IE = 1; // Autorise les interruptions sur le TIMER1 par débordement
    // PIR1.TMR1IF = 0; // RAZ du flag TMR1IF (positionné à un si il y a eu debordement du TIMER1)


    // Autorise les interruptions périphériques et sur CCP1

    INTCON.GIE = 1; // Positionne les bits GIE, PEIE à 1 pour autoriser les interruptions
    INTCON.PEIE = 1;
    PIE1.CCP1IE = 1; // autorise les interruptions sur CCP1
    PIR1.CCP1IF = 0; // RAZ du flag CCP1IF



    //Configuration du module CCP1

    // Choix du mode du CCP
    CCP1CON = FALLING_EDGE ; // capture sur chaque front descendant, PRESCALER=1


    //****************Initialisation des variables********************* **********





    while(1) {



    if (i >= 10) {

    INTCON.GIE = 0; // Positionne les bits GIE, PEIE à 1 pour autoriser les interruptions
    INTCON.PEIE = 0;
    PIE1.CCP1IE = 0; // autorise les interruptions sur CCP1
    PIR1.CCP1IF = 0; // RAZ du flag CCP1IF

    first_pw = TIMER_VALUE[1]-TIMER_VALUE[0]; //calcule la première largeur d'impulsion
    LongToStr(first_pw, txt ); //convertit l'entier first_pw en chaine de caractère

    Lcd_Init(&PORTB); // Affiche la différence entre les 2
    LCD_Cmd(LCD_CLEAR); // premières valeurs de TIMER_VALUE sur l'afficheur
    LCD_Cmd(LCD_CURSOR_OFF); // LCD 2*16 caractères.
    Delay_ms(1000);
    LCD_Out(1,1, text); //
    Delay_ms(1000);
    LCD_Out(2,6,txt); //
    Delay_ms(10000) ;
    }
    }

    }


    Je commence par afficher la valeur de la variable i au démarrage, avant la première détection de front sur RC2.
    Puis j'ai ajouté une ligne pour allumer deux diodes reliées à RA0 et RA1 afin de me montrer si je rentre bien dans la routine d'interruption. Et apperemment je n'y rentre pas....

    J'ai donc remesuré mes niveaux de tensions, et il semble qu'en sortie de mon TSOP 38, le signal n'a plus qu'une amplitude de 2V malgré que j'alimente mon TSOP avec l'alimentation du PIC qui est de 4.7V.

    Je me demandais si ce niveau de tension est suffisant pour déclenché une détection de front sur RC2 par le module CCP1?

    Aussi en regardant dans la datasheet du 16f876, je constate figure 15-11 (p168) et table 15-5, qu'il faut un temps minimum pour la montée de l'état bas à l'état haut (et inversement) afin que le PIC puisse détecter le front. Hors quand je regarde la trame à l'oscilloscope j'ai l'impression que mon changement de niveau est instantané (cad sans la pente de 52 ns indiqué sur la datasheet).

    Vu que j'ai directement relié la sortie de mon TSOP 38 à ma pin RC2, je me demandais si il n'est pas nécessaire d'introduire une capacité afin de "ralentir" le changement d'état... et si oui comment dois je calculer la valeur de la capacité?

    Merci d'avance,
    Cordialement,

    roland
    Dernière modification par roland2pau ; 01/10/2012 à 07h53. Motif: erreur

  4. #4
    RISC

    Re : difficultés à utiliser le CCP1 du 16f876 pour enregistrer trame IR

    Salut,

    Code:
    Je te remercie pour ta réponse! Finalement j'ai simplifié le code en supprimant les interruptions multiples afin de me concentrer dans un premier temps sur le le fnctionnement du module CCP1.
    Bonne décision. Lorsque l'on développe il vaut mieux mettre en oeuvre les interruptions une par une.

    Le code de ton interruption reste encore un peu long. Pour le simplifier je te recommande de remplacer :
    read_TMR1 = CCPR1H*256;
    par : read_TMR1 = 8 << CCPR1H;
    Il est plus rapide de décaler que de multiplier ;=)

    quel outil utilises-tu pour déboguer ?
    Astu mis un point d'arrêt dans l'interruption pour vérifier si cela fonctionne ?

    Peux-tu poster ton schéma ?
    quelle fréquence à ton signal d'entrée ?
    Pourquoi n'as-tu pas mis les bits dec onfiguration au début de ton programme ?

    a+
    Dernière modification par RISC ; 01/10/2012 à 23h09.

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

    Re : difficultés à utiliser le CCP1 du 16f876 pour enregistrer trame IR

    Bonsoir,

    Je te remercie pour ton aide, c'est vraiment précieux!!!! Dieu sait que je passe énormément de temps à lire les docs datasheet, chercher des codes source sample... Mais quand on aime on compte pas!!!!

    Je vais modifier mon code source pour la routine d'IT du CCP1 avec le décalage.

    Alors pour ce qui est de ma méthode de débogage, elle est très archaique dans la mesure ou ma platine d'essai n'est pas muni d'un In Circuit Debugger, je ne peux donc pas mettre de point d'arrêt ou je n'en ai pas connaissance encore... mais la version easypic v2 est obsolète et semble intègrer juste un programmateur. Je suis en train de voir pour mettre un bootloader mais ca m'a l'air compliqué...

    A l'heure actuelle j'essaie d'introduire la routine d'afficheur LCD pour afficher des variables, et je joue sur l'endroit ou j'insère l'affichage LCD dans le programme mais ca ne marche pas très bien.

    Pour le schéma il faut que je l'édite sous eagle. Mais il s'agit concrètement de ma demoboard à laquelle j'ai connecté la sortie mon montage TSOP 3842 sur le pin RC2 du PORTC. Je sais pas si vous etes prêt à y jeter un coup d'oeil (je trouve que c'est trop osé de ma part de vous proposer cela) mais je peux vous joindre les schemas de ma demoboard?

    J'ai un peu avancé, et il semble que je rentre bien dans ma routine d'interuption maintenant que j'ai mis un jumper pour avoir mes resistances de pull-up sur le PORTC et que j'ai isolé les leds raccordées au PORTC.

    Quand tu demandes la fréquence du signal d'entrée, tu entends par la la fréquence du signal IR ? JE ne sais pas quelle est la porteuse mais je suppose qu'il s'agit de 38 kHz vu que je trouve bien ma trame IR à la sortie du TSOP 3842. La durée d'un bit est de 1,8ms (environ). Mon signal d'horloge est de 4MHz pour l'oscillateur externe du PIC.

  7. #6
    roland2pau

    Re : difficultés à utiliser le CCP1 du 16f876 pour enregistrer trame IR

    J'ai ajouté ci-joint le signal tel que j'arrive à le recevoir sur RC2.

    Voici le code tel que je l'utilise actuellement:

    //*********DECLARATIONS********* ************************
    unsigned int read_TMR1;
    unsigned short i;
    unsigned long unsigned TIMER_VALUE[20];
    long unsigned int ack_period;
    long first_pw;
    char txt[16];
    char *text = "1er pw:";
    const RISING_EDGE = 0x05;
    const FALLING_EDGE = 0x04;

    //Routine d'interruption

    //****************************** *************************
    void interrupt() {


    //**************************Rout ine d'IT du CCP1************************** ******
    if (PIR1.CCP1IF) {
    //*Etape 4 du "Measuring Pulse Width" CCP Tips 'n Tricks

    // la routine d'interruption, donc front bien détecté sur RC2
    read_TMR1 = CCPR1H*256; // On récupère la valeur des registre CCPR1H
    read_TMR1 = read_TMR1 + CCPR1L; // et CCPR1L dans une variable unique
    TIMER_VALUE[i] = read_TMR1;
    i++;

    //*Etape 5 du "Measuring Pulse Width" CCP Tips 'n Tricks

    if (CCP1CON = FALLING_EDGE) CCP1CON = RISING_EDGE;
    else CCP1CON = FALLING_EDGE;

    //Etape 3 du "Measuring Pulse Width" CCP Tips 'n Tricks

    //PIE1.CCP1IE = 1; // autorise les interruptions sur CCP1
    PIR1.CCP1IF = 0; // RAZ du flag CCP1IF
    }

    //**********************Fin de la routine d'IT du CCP1**************************
    }

    void main(void)
    {
    i=0; //index du tableau de valeur pointe sur la première valeur à enregistrer


    //****************************** ****************************** ****************************** ********************//
    //Configuration des registres

    // On utilise CCP1/RC2 (pin13)
    // On configure le PORTC en entrée
    // Oncongigure le PORTB en entrée

    TRISC=0b00000100 ; //configure RC2 en entrée
    TRISA=0b00000000; //configure PORTA en sortie
    PORTC=0b00000000 ; // reinitialise le PORTC
    PORTA=0b00000000 ; // rénitialise le PORTA



    // Configuration initialisation du TIMER1

    T1CON=0x01 ; // Configure le TIMER1 avec comme source d'horloge interne Fosc/4

    TMR1L = 0x00; // Initialisation du Timer1 TMR1L = 0x00;
    TMR1H = 0x00 ; // Initialisation du Timer1 TMR1H = 0x00;

    // PIE1.TMR1IE = 1; // Autorise les interruptions sur le TIMER1 par débordement
    // PIR1.TMR1IF = 0; // RAZ du flag TMR1IF (positionné à un si il y a eu debordement du TIMER1)


    // Autorise les interruptions périphériques et sur CCP1

    INTCON.GIE = 1; // Positionne les bits GIE, PEIE à 1 pour autoriser les interruptions
    INTCON.PEIE = 1;
    PIE1.CCP1IE = 1; // autorise les interruptions sur CCP1
    PIR1.CCP1IF = 0; // RAZ du flag CCP1IF



    //Configuration du module CCP1

    // Choix du mode du CCP
    CCP1CON = FALLING_EDGE ; // capture sur chaque front descendant, PRESCALER=1


    //****************Initialisation des variables********************* **********





    while(i<10) {}

    if (i >= 10) {
    PORTA=0b00000011; // Indique pour le debogage que je suis bien passé par
    Delay_ms(2000); // la routine d'interruption
    PORTA=0b00000000;
    INTCON.GIE = 0; // Positionne les bits GIE, PEIE à 1 pour autoriser les interruptions
    INTCON.PEIE = 0;
    PIE1.CCP1IE = 0; // autorise les interruptions sur CCP1
    PIR1.CCP1IF = 0; // RAZ du flag CCP1IF

    first_pw = TIMER_VALUE[1]-TIMER_VALUE[0]; //calcule la première largeur d'impulsion
    LongToStr(first_pw, txt ); //convertit l'entier first_pw en chaine de caractère

    Lcd_Init(&PORTB); // Affiche la différence entre les 2
    LCD_Cmd(LCD_CLEAR); // premières valeurs de TIMER_VALUE sur l'afficheur
    LCD_Cmd(LCD_CURSOR_OFF); // LCD 2*16 caractères.
    Delay_ms(1000);
    LCD_Out(1,1, text); //
    Delay_ms(1000);
    //LCD_Out(2,6,txt); //
    //Delay_ms(2000);
    }

    }


    Le programme semble bien allé jusqu'à la fin, en revanche rien ne s'affiche sur l'afficheur LCD.
    Je sais que les commandes et les données sont bien envoyées au LCD car je vois les commandes et données au rythme des leds connectés au PORTB.

    Je continue mes recherches lentemment mais surement...

    Bonne soirée
    Images attachées Images attachées  

  8. #7
    RISC

    Re : difficultés à utiliser le CCP1 du 16f876 pour enregistrer trame IR

    Salut,

    Tu vas mettre un temps infini à déboguer ton application si tu n'utilises pas un débogueur pour voir tes variables.
    Les fonctions LCD sont très lentes et risquent de perturber ton programme...
    Je te recommande d'investir dans un petit outil de programmation et debug comme le Pickit3 qui te donnera la fonction débogage si précieuse à la mise au point...

    Si tu ne peux pas mettre de points d'arrêts tu vas chercher sans fin et faire des suppositions vraies mais surtout fausses...et ne pas arriver à isoler les problèmes temps-réel.

    a+

  9. #8
    roland2pau

    Re : difficultés à utiliser le CCP1 du 16f876 pour enregistrer trame IR

    Bonsoir,

    Je pense que vous avez raison. Aujourd'hui j'ai regardé si je pouvais pas utilisé un booloader comme debuger in situ, mais ca n'a pas l'air d'etre le cas... Je sais que les versions V3, v4 V5 et plus de l'easypic integre un debuggeur... Aussi j'ai à ma disposition un clone pickit 3 mais que j'ai pas réussi à faire fonctionner.... PEut etre vais je m'y replonger et si je n'arrive pas à le faire fonctionner je rachèterai un piclit 3 avec debuggeur intégré!

    Sinon j'ai modifié mon programme et du coup pour vérifier le contenu de mon tableau TIMER_VALUE, censé contenir les valeurs du timer pour lesquels sont intervenus les changements d'etats successifs.

    Ainsi, j'ai créer deux tableaux un TIMER_VALUE_H dans lequel j'enregistre les valeurs de CCPR1H et un tableau TIMER_VALUE_L dans lequel j'enregistre les valeurs de CCPR1L. Puis une foi que j'ai quitté la routine d'interruption de CCP1, j'ai mis les lignes de codes suivantes:

    INTCON.GIE = 0; // Positionne les bits GIE, PEIE à 1 pour desactiver les interruptions
    INTCON.PEIE = 0;
    PIE1.CCP1IE = 0; //
    PIR1.CCP1IF = 0; // RAZ du flag CCP1IF

    PORTB=TIMER_VALUE_H[0]; // Affiche la valeur du registre CCPR1H (du 1er front detecté)
    Delay_ms(15000); // sur le PORTB et attends 15s pour me laisser relever les valeurs
    PORTB=TIMER_VALUE_L[0]; // Idem pour le registre CCPR1L (du 1er front détecté)
    Delay_ms(15000);
    PORTB=TIMER_VALUE_H[1]; // Idem pour le registre CCPR1H (du 2eme front détecté)
    Delay_ms(15000); // Idem pour le registre CCPR1L (du 2eme front détecté)
    PORTB=TIMER_VALUE_L[1];
    Delay_ms(15000);

    Et après je reconstitue la valeur decimale equivalente à partir de la valeur binaire sur 16 bits du registre CCPR1 pour le 1er front. Puis pour le 2 eme front.

    J'ai essayé plusieurs fois et je trouve toujours comme valeur 65 ms or, si on regarde l'oscillogramme que j'ai posté précédemment, la valeur de niveau bas entre les 2 premiers fronts est de 1,8 ms... Je ne sais pas d'ou cela peux venir...

    Donc je vais me procurer une solution de débogage et je reviendrais alors vers vous!

    Encore merci pour votre aide, c'est vraiment un gain de temps précieux.

    Cordialement,

    roland

Discussions similaires

  1. interruption basse priorité pour le module CCP1 capture
    Par invited08e1382 dans le forum Électronique
    Réponses: 3
    Dernier message: 19/05/2011, 12h17
  2. Comment programmer CAN pour pic 16F876? + peu donner aide pour typons...
    Par invite07466868 dans le forum Électronique
    Réponses: 0
    Dernier message: 26/05/2008, 21h23
  3. Comment utiliser une trame en fibre de verre pour enduire
    Par invitec8417826 dans le forum Habitat bioclimatique, isolation et chauffage
    Réponses: 7
    Dernier message: 09/07/2007, 18h11
  4. enregistrer une trame RS232
    Par invite745f9f07 dans le forum Électronique
    Réponses: 5
    Dernier message: 31/10/2006, 18h29
  5. Compilteur C pour pic 16F876
    Par invite1001d59c dans le forum Électronique
    Réponses: 2
    Dernier message: 16/05/2006, 12h54
Découvrez nos comparatifs produits sur l'informatique et les technologies.