Problème d'interruption sur 16f876
Répondre à la discussion
Affichage des résultats 1 à 6 sur 6

Problème d'interruption sur 16f876



  1. #1
    jc_renaud

    Problème d'interruption sur 16f876


    ------

    Salut à tous,

    J'ai un pb avec un programme utilisé pour la gestion d'un servomoteur.
    En fait, suivant le simulateur de MPLab, le programme rentre bien une première fois dans l'interruption mais ni rentre plus jamais après alors que le flag du timer0 est activé et que les interruptions sont bien autorisées.

    Quelqu'un pour m'aider ???

    je colle le code ci-dessous:

    Code:
    /**************************/
    //Programme Test_MOTEUR_1.c
    //Calibration circuit de commande Moteur 1
    //Horloge externe: 4MHz
    /*************************/
    
    //registre de configuration
    #define CP_off		|=0b11000000110000
    #define LVP_off		&=0b11111101111111
    #define CPD_off		|=0b00000100000000
    #define WRT_off		|=0b00011000000000
    #define DEBUG_off	|=0b00100000000000
    
    #pragma config FOSC=XT, WDTE=off, PWRTE=on, CP_off, BODEN=off
    #pragma config LVP_off, CPD_off, WRT_off, DEBUG_off
    
    #pragma interruptSaveCheck n
    
    void it_Timer0 (void); //prototype fonction pause
    
    #define TMR0_1 150	//délai de 1,7ms avec prédiv 16
    #define TMR0_2 113	//délai de 18.3ms avec prédiv 128
    
    #pragma bit MOT_1 @ PORTC.2
    
    /**************************/
    //fonction interruption
    /**************************/
    #pragma origin 4
    void itMain (void)
    {
    	if(T0IF)it_Timer0();
    }
    
    /**************************/
    //fonction principale
    /**************************/
    void main (void)
    {
    	//Désactivation des interruptions
    	INTCON = 0x00;
    	PIE1 = 0x00;
    	PIE2 = 0x00;
    
    	//Configuration des ports
    	TRISA = 0xFF;
    	TRISB = 0xFF;
    	TRISC = 0b11111011;
    
    	//configuration du timer0
    	T0CS=0;
    	T0SE=0;
    	PSA=0;
    
    	PS0=1;
    	PS1=1;
    	PS2=0;
    
    	MOT_1=0;
    	
    	T0IF=0;
    	T0IE=1;
    
    	TMR0=0xFF;
    
    	PEIE=1;
    	GIE=1;
    	
    	while (1)
    	{
    		T0IE=1;
    	}
    }
    
    /**************************/
    //gestion du débordement
    /**************************/
    void it_Timer0 (void)
    {
    	T0IE=0;
    	T0IF=0;
    	
    	if (MOT_1==0)
    	{
    		PS0=1;
    		PS1=1;
    		PS2=0;
    		TMR0=TMR0_1;
    		MOT_1=1;
    	}
    	else
    	{
    		PS0=0;
    		PS1=1;
    		PS2=1;
    		TMR0=TMR0_2;
    		MOT_1=0;
    	}
    
    	T0IE = 1;
    }
    Par avance, merci,

    Jc !

    -----

  2. #2
    freepicbasic

    Re : Problème d'interruption sur 16f876

    pourquoi mettre PEIE à 1 ?
    PIE1 et PIE2 sont déjà à 0 au reset !
    TMR0=0xFF; ça ne lui laisse pas beaucoup de temps ! int immediate (peut être la cause)
    pourquoi mettre T0IE à 0 puis à 1 dans l int?
    Manque la partie des 19ms signal bas du PPM ... TMR0 ne peut pas faire !

    Quant à la precision ... ça va être dur !
    1ms / 256 ~ 4µs impossible par int il faudra des nop
    et même
    1ms/64 ~16µs ... impossible par int !
    A+, pat

  3. #3
    jc_renaud

    Re : Problème d'interruption sur 16f876

    Salut Freepicbasic et merci pour ta réponse.
    Je n ai pas compris ce que tu voulais dire par PPM, mais si tu parles du temps où MOT_1 doit être à 0, c'est effectivement la partie de programme qui ne s exécute pas...

  4. #4
    jc_renaud

    Re : Problème d'interruption sur 16f876

    le fait de mettre TMR0 à 255 à l'initialisation permet de provoquer le premier passage dans l'intérruption. Celui-ci fonctionne très bien, c'est ensuite que ca ne marche pas, quand TMR0 est positionné à 150 après le traitement de la première interruption.

    Ce que je comprends pas, c'est qu'au moment du débordement du timer0, le flat est bien activé et TOIE aussi mais que le programme ne rentre pas dans l'interruption

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

    Re : Problème d'interruption sur 16f876

    Bonsoir,

    ta gestion dans l'interruption n'est pas convenable.
    On ne met pas une fonction dedans.
    On détecte la source d'interruption puis on gicle au plus vite telle est la règle.
    La pratique est de positionner une variable et de la traiter à l'extérieur, de remettre le flag à 0 et de gérer ce qu'il y a à faire dans la boucle principale.

    Donc on charge le timer avec une valeur d'offset A, le timer comptera de A à 255 puis déclenchera le flag de débordement le tick suivant.
    Idem avec un offset B.

    Ne doit subsister dans ton interruption que la détection du flag de débordement du timer0 qui déclenchera mot1 ou mot2 par une variable select_mot gérée dans la boucle principale.

    Ce qui donne pour le premier temps de 1,7ms la config timer0 suivante à charger:
    Prescaler = 8
    TMR0 offset = 42

    T0CS = 0;
    T0SE = 0;
    PSA = 0;
    PS2 = 0;
    PS1 = 1;
    PS0 = 0;
    TMR0 = 42;

    Et pour 18,3ms la config suivante:

    prescaler 128

    T0CS = 0;
    T0SE = 0;
    PSA = 0;
    PS2 = 1;
    PS1 = 1;
    PS0 = 0;

    TMR0 = 113; // offset-> le timer démarre à 113

    Code:
    /**************************/
    //Programme Test_MOTEUR_1.c
    //Calibration circuit de commande Moteur 1
    //Horloge externe: 4MHz
    /*************************/
    
    //registre de configuration
    #define CP_off		|=0b11000000110000
    #define LVP_off		&=0b11111101111111
    #define CPD_off		|=0b00000100000000
    #define WRT_off		|=0b00011000000000
    #define DEBUG_off	|=0b00100000000000
    
    #pragma config FOSC=XT, WDTE=off, PWRTE=on, CP_off, BODEN=off
    #pragma config LVP_off, CPD_off, WRT_off, DEBUG_off
    
    #pragma interruptSaveCheck n
    #pragma bit MOT_1 @ PORTC.2
    
    void timer_mot1(void);
    void timer_mot2(void);
    
    /**************************/
    //fonction interruption
    /**************************/
    #pragma origin 4
    void itMain (void)
    {
    if(T0IF) select_mot=!select_mot;
    T0IF = 0;
    }
    
    main()
    {
    volatile char select_mot = 1;
    //Configuration des ports
    TRISA = 0xFF;
    TRISB = 0xFF;
    TRISC = 0b11111011;
    
    timer_mot1(); //on charge par défaut le timing pour mot1
    INTCON = 0b11100000; // config du registre de controle des interruptions
    
    while(1)
           {
            if(select_mot) timer_mot1();
            if(!select_mot) timer_mot2();
           }
    }
    
    void timer_mot1()
    {
    OPTION = 0b10000010;
    TMR0 = 42;
    }
    
    void timer_mot2()
    {
    OPTION = 0b10000110;
    TMR0 = 113;
    }
    Essaye, j'ai pas essayé mais ça devrait tourner.
    @+
    Dernière modification par HULK28 ; 10/09/2012 à 02h10.

  7. #6
    freepicbasic

    Re : Problème d'interruption sur 16f876

    PPM c est le codage des premiers servo moteur
    Voir le site de Thobois
    http://home.nordnet.fr/fthobois/MRA-1.htm

    Au fait, pour utiliser le PORTA en digitale
    mettre ADCON1 à 7
    Et bien suivre les conseils de l'excellent Hulk28 ... LOL
    A+, pat

Discussions similaires

  1. Probléme d'interruption PIC12F683 CCS
    Par HAYAC dans le forum Électronique
    Réponses: 22
    Dernier message: 03/08/2012, 13h17
  2. Réponses: 11
    Dernier message: 19/09/2011, 09h19
  3. Probleme d'interruption sur PIC 18F4420
    Par invite919cb150 dans le forum Électronique
    Réponses: 2
    Dernier message: 09/06/2008, 08h45
  4. Réponses: 2
    Dernier message: 23/04/2007, 12h32
  5. Probleme avec Timer1 sur 16F876
    Par Peter dans le forum Électronique
    Réponses: 4
    Dernier message: 27/12/2006, 15h02
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...