Bonjour, tout d'abord merci à tous ceux qui contribuent à ce forum, pour toutes les discussion très instructives que l'on peut trouver.
Je rencontre quelques difficultés avec l'utilisation d'un deuxième timer avec un PIC (18F1320).
Le problème : avec seulement timer 0 qui fonctionne, pas de soucis, l'interruption est appelée quand je le veux (je vérifie TIMER0IF), la valeur que je charge dans TMR0H et TMR0L me donne la période que je souaite.
Dès que j'active timer 1, l'interruption timer 0 continue de fonctionner normalement, mais l'interruption timer 1 réagit bizarrement, la valeur que je recharge dans TMR1H et TMR1L ne semble pas avoir d'incidence sur la période d'appel de l'interruption associée à timer 1.
Vous l'aurez compris, j'essaie d'avoir deux interruptions timer 0 et timer 1 overflow, appelées à deux périodes différentes (ici un rapport de 2 entre les périodes, pour l'exemple).
Ma questions (pour résumer)
- pour quelles raisons la période de timer 1 ne correspond pas à la valeur que l'on charge. Quelle que soit la valeur que je mette dans TMR1H et TMR1H, l'interruption associée à timer 1 est appelée à la même période qui correspond j'ai l'impression à un tour complet de timer1 sur 16 bits (65535 cycles CPU). Pourtant en mode simulation, la valeur 0x8000=32768 se charge bien dans TMR1H et TMR1L.
Questions supplémentaire (si quelqun sait)
- pourquoi l'interruption timer 1 ne se déclenche pas tant que l'on a pas activé le timer 0? (avec INTCONbits.T0IE = 1) Sinon le programme ne va jamais dans timer_isr().
- lorsque timer0 seulement est actif, pourquoi donc la fonction d'interruption timer_isr() est-elle appelée tous les 26 cycles machine eviron, alors qu'on a demandé que l'interruption soit déclenchée seulement sur overflow (avec INTCONbits.T0IE = 1).
Désolé si ces questions sont des évidences, mais lorsque d'affreux doutes subsistent comme ici, je pense qu'il est thérapeutique de demander de l'aideMerci donc par avance pour la thérapie!
NB : au lieu d'utiliser OpenTimer0 & 1, j'ai également tenté la configuration manuelle des registres des timers, mais cela ne semble pas améliorer les choses.
Voici le code
Code:void timer_isr (void); #pragma code high_vector=0x08 void high_interrupt (void) { _asm GOTO timer_isr _endasm } #pragma code // ici, déclaration ici des variables globales et des fonctions utilisées dans les interruptions #pragma interrupt timer_isr void timer_isr() { if(INTCONbits.TMR0IF) { TMR0H=0x00; TMR0L=0x00; INTCONbits.TMR0IF = 0; LATAbits.LATA1 = ~LATAbits.LATA1; // indicateur } if(PIR1bits.TMR1IF) { TMR1H=0x80; TMR1L=0x00; PIR1bits.TMR1IF = 0; LATAbits.LATA2 = ~LATAbits.LATA2; // indicateur } } void main() { (...) OpenTimer0(TIMER_INT_ON & T0_SOURCE_INT & T0_16BIT & T0_PS_1_1); OpenTimer1(TIMER_INT_ON & T1_16BIT_RW & T1_SOURCE_INT & T1_PS_1_1 & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF); // active les interruptions INTCONbits.GIE = 1; // boucle principale while(1) { } }
-----