Problème d'interruptions sur PIC18F2520 et PIC12F683
Répondre à la discussion
Affichage des résultats 1 à 5 sur 5

Problème d'interruptions sur PIC18F2520 et PIC12F683



  1. #1
    jlg_47

    Problème d'interruptions sur PIC18F2520 et PIC12F683


    ------

    Bonjour,


    J'ai écrit une petite application que j'ai testée sur un PIC18F2520 parce que j'en avais un.
    Elle fonctionne parfaitement ...

    Vu les besoins, je veux l'implémenter sur un PIC12F683 qui est très largement suffisant pour ça.

    Le code est écrit en C et la partie fonctionnelle est un "copier-coller" sans aucune modification.

    Par contre j'ai dû adapter les parties de code correspondantes au processeur, aux entrées sorties et aux interruptions.

    L'application utilise des interruptions du timer2 pour mesurer des intervalles de temps et des interruptions provoquées par un signal connecté à RB0 pour le PIC18F2520 et à GP2 pour le 12F683.

    Cela fonctionne parfaitement sur le PIC18F2520 et cela ne fonctionne pas de façon satisfaisante sur le PIC12F683.

    Après de nombreuses investigations, j'en suis arrivé à la conclusion que le problème se situe au niveau des interruptions.
    Une grosse différence entre le PIC18F2520 et le PIC12F683 est que le PIC18F2520 possède 2 niveaux d'interruptions (haut et bas) et mon code original sur PIC18F2520 utilisait ces 2 niveaux. (interruption timer2 en priorité basse et interruption RB0 déclarée en priorité haute)

    Vu qu'un bit du registre d'interruption du PIC18F2520 suffit pour désactiver les niveaux de priorité, je l'ai fait et là mon application se plante exactement comme sur le PIC12F683. Il suffit de passer IPEN de 1 à 0 pour que plus rien ne marche.

    Je pense donc avoir bien cerné l'origine du problème.

    Mais je ne suis pas assez calé en "interruption" et je ne connais pas la différence entre une priorité haute et une priorité basse.
    Donc je sèche et j'appelle au secours.

    Y a t-il moyen de régler des niveaux de priorité d'interruption sans que cela soit implémenté dans le processeur?

    Voici les bouts de code relatifs aux interruptions:

    Pour le PIC18F2520 (code qui fonctionne parfaitement)

    Code:
    #pragma interruptlow low_ISR		//    traitement des interruptions 
    void low_ISR(void)
    {
    	if (PIR1bits.TMR2IF)			//  Y a t-il une une interruption du timer 2? 
    	{
    		PIR1bits.TMR2IF = 0; 		// RAZ de l'interruption
    		Timer_flag = TRUE;
    		Tick_count1++;		
    	}
    }									
    
    #pragma interrupt high_ISR
    void high_ISR(void)
    {
    		if (INTCONbits.INT0IF)			// Y a t-il une interruption sur RB0
    		{
    			INTCONbits.INT0IF = 0;
    			RB0_flag = TRUE;			
    		}	
    }                      
    
    
    ///  Validation des interruptions
    
        PIE1bits.TMR2IE = 1;    //	Timer 2
        IPR1bits.TMR2IP = 0;    // priorité basse
        PIR1bits.TMR2IF = 0;    // RAZ de l'interrupt
        
        INTCON2bits.INTEDG0 = 1;    // interrupt on up edge of INT0
        INTCONbits.INT0IF = 0;      // ensure flag is cleared
        INTCONbits.INT0IE = 1;		// enable INT0 interrupt
    
        RCONbits.IPEN = 1; 	// Enable priority levels on interrupts
    // RCONbits.IPEN = 0;     si on met ce bit à 0, plus rien ne marche !!!
        INTCONbits.GIEH = 1;	// Turn high priority interrupts on
        INTCONbits.GIEL = 1;	// Turn low priority interrupts on
    Pour le PIC12F683

    Code:
    void interrupt()
    {
         if (PIR1.TMR2IF)          // interruption timer2
         {
            PIR1.TMR2IF = 0;        // Clear interrupt flag
            Timer_flag = TRUE;
            Tick_count1++;
         }
         else if (INTCON.INTF)     // interruption externe
         {
            INTCON.INTF = 0;  // clear the interrupt
            RB0_flag = TRUE;
         }
    }
    
     Validation des interruptions
    
       PIE1.TMR2IE = 1;            // enable timer 2 interrupt
    
      PIR1.TMR2IF = 0;	           // Clear Timer2 interrupt flag
    
      INTCON.INTE = 1;            // Enable external interrupt on GP2
      OPTION_REG = 0b01000000;    // interrupt on rising edge of GP2
      IOC = 0b00000100;           // interrupt on GP2
      INTCON.INTF = 0;            // Ensure flag is cleared
      
      INTCON.GIE = 1;             // Enable general interrupts
      INTCON.PEIE = 1;	         // Enable peripheral interrupt
    Voilà, si quelqu'un aurait une petite idée du problème, ce serait sympa de m'aider.

    Bonne journée à tous.

    -----
    Dernière modification par jlg_47 ; 16/03/2012 à 16h54.

  2. #2
    RISC

    Re : Problème d'interruptions sur PIC18F2520 et PIC12F683

    Salut,

    Si tu veux migrer facilement ton code, le plus simple est de légèrement modifier ton code sur le PIC18F2520 pour qu'il utilise le mode Legacy (un seul vecteur comme sur les PIC16). Dans le mode Priority tu peux aussi écrire ton code pour qu'il n'utilise qu'un seul vecteur.

    Si tu utilises 2 vecteurs d'interruptions, il faut OBLIGATOIREMENT que IPEN soit à 1. Quand IPEN est à 0 il n'y a qu'un vecteur.

    Le mode legacy (1 vecteur d'interruption) est directement compatible avec les PIC12/PIC16 à coeur mid-range (instructions sur 14 bits).

    Si tu utilises plusieurs interruptions simultanément je te recommande d'écrire ton code de cette manière :
    Code:
    void interrupt()
    {
         if (PIE1.TMR2IE && PIR1.TMR2IF)          // interruption timer2
         {
            PIR1.TMR2IF = 0;        // Clear interrupt flag
            Timer_flag = TRUE;
            Tick_count1++;
         }
         else if (INTCON.INTE && INTCON.INTF)     // interruption externe
         {
            INTCON.INTF = 0;  // clear the interrupt
            RB0_flag = TRUE;
         }
    }
    D'autre part, il faut absolument déclarer toute les variables globales modifiées dans les interruptions en volatile.
    Je ne connais pas les types mais cela doit être de ce genre là :
    volatile unsigned char RB0_flag ;
    volatile unsigned char Timer_flag;
    volatile unsigned char Tick_count1;


    Si tu as 2 interruptions actives simultanément, l'ordre de test dans la routine d'interruption correspont donc à une priorité de moins en moins élevée.

    a+

  3. #3
    jlg_47

    Re : Problème d'interruptions sur PIC18F2520 et PIC12F683

    Bonjour Risc,

    Et merci pour tes conseils.

    La routine d'interruption que j'ai écrite pour le 12F683 ressemble fortement à celle que tu proposes.

    Code:
    void interrupt()
    {
         if (INTCON.INTF)     // interruption externe
         {
            INTCON.INTF = 0;  // clear the interrupt
            RB0_flag = TRUE;
         }
         else if (PIR1.TMR2IF)          // interruption timer2
         {
            PIR1.TMR2IF = 0;        // Clear interrupt flag
            Timer_flag = TRUE;
            Tick_count1++;
         }
    
    }
    J'ai rajouté les tests supplémentaires que tu conseilles.

    J'ai également mis les variables en volatile.


    Mais cela ne change rien.
    Alors que la version du PIC18F avec les "low level" et "high level interrupts" marche de façon excellente, la version PIC12F ou 18F sans niveau de priorité rate en gros une interruption sur cinq et donc ne fonctionne pas de façon satisfaisante.

    Théoriquement les interruptions sur RB0 et celles du Timer2 ne doivent pas se produire ensemble car le Timer2 est démarré par une interruption de RB0 et chaque interruption du Timer2 doit grosso modo se produire juste entre deux interruptions de RB0.

    Il y a peut être un problème au niveau de la programmation du Timer2, peut-être que je ne sais pas le réinitialiser correctement; mais je pense qu'alors le problème apparaitrait dans la version à 2 niveaux de priorité d'interruption.

    Voici le bout de code pour relancer le Timer2

    Code:
      void Set_timer_50()
      {
         T2CON = 0b00000000;         // Arrêt Timer2
         PR2 = 103;                  // PR2 = 103 -> période de 52 microsecondes
         // Note : prescalaire et postscalaire sont à 1
         // P = 4/8000000 * prescalaire * postscalaire * (PR2+1)
         TMR2 = 0;                   // RAZ de TMR2
         T2CON = 0b00000100;         // démarrage du Timer2
     }
    Je ne suis pas sûr qu'en passant dans ce bout de code le Timer2 redémarre bien à zéro et envoie sa première interruption 52 microsecondes après la relance.

    Un autre point: je n'inhibe pas les interruptions du Timer2 pendant qu'il est relancé, il faudrait peut-être le faire; mais je ne vois pas trop ce que cela changerait.

    C'est assez énervant de voir que cela fonctionne nickel avec 2 niveaux de priorité des interruptions et que ça plante avec un seul niveau ..

    Bonne journée

    Jean-Louis

  4. #4
    paulfjujo

    Re : Problème d'interruptions sur PIC18F2520 et PIC12F683

    bonjour,

    Citation Envoyé par jlg_47 Voir le message
    Théoriquement les interruptions sur RB0 et celles du Timer2 ne doivent pas se produire ensemble car le Timer2 est démarré par une interruption de RB0 et chaque interruption du Timer2 doit grosso modo se produire juste entre deux interruptions de RB0.
    Jean-Louis
    Tu ne peux pas en etre sur, puisqu'apparament tu armes simplement un flag qui doit , je suppose etre traité dans le main
    pour relancer le timer 2
    D'autre part, moi je supprimerai le else dans la routine d'interrupt,
    car si on traite RB0 on manque un tour de traitement de timer2, puisqu'il faudra revenir dans l'interrupt des sa sortie!
    pour mieux synchroniser, tu pourrais reactiver timer2 dans le traitement interrupt RB0

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

    Re : Problème d'interruptions sur PIC18F2520 et PIC12F683

    Bonsoir et merci à tous,

    Je suis finalement reparti d'une feuille blanche sans oublier vos conseils.

    J'ai tout refait en intégrant toutes les parties critiques directement dans les interruptions et ça marche ...

    Bonne soirée
    Dernière modification par jlg_47 ; 17/03/2012 à 20h10.

Discussions similaires

  1. [ARM] Problème dans la génération d'interruptions
    Par invite0bef94e7 dans le forum Électronique
    Réponses: 8
    Dernier message: 14/05/2010, 07h43
  2. problème d'incrémentation pic12F683
    Par invite4716c6c3 dans le forum Électronique
    Réponses: 3
    Dernier message: 22/04/2010, 16h52
  3. PIC16F84 Comptage d'interruptions impossible
    Par invited7cd4587 dans le forum Électronique
    Réponses: 3
    Dernier message: 11/04/2009, 13h39
  4. adc avec un PIC12F683
    Par invite721580c7 dans le forum Électronique
    Réponses: 2
    Dernier message: 21/01/2007, 14h38
  5. Pile sur Pic18f2520
    Par invite74b73858 dans le forum Électronique
    Réponses: 0
    Dernier message: 17/07/2006, 09h31
Découvrez nos comparatifs produits sur l'informatique et les technologies.