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)
Pour le PIC12F683Code:#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
Voilà, si quelqu'un aurait une petite idée du problème, ce serait sympa de m'aider.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
Bonne journée à tous.
-----