Timer1 Interrupt Not Working? - Page 1
Forum section: electronics / general

author: ed_reardon
author_rank: Regular Contributor
timestamp: June 16, 2017, 07:32:45 am
content: Hi all,Firstly this is only sandbox code so it's a bit spaghetti like, the idea here is that when INT3 is high the timer is started which will be a long debounce (this is due to the fact this is going to be a) A very deliberate action with consequences if it 'fires in error' and B) It's going to have to be done by physically bridging INT3 high with a wire!Now Ed thought I could start Timer1, count the flags a few times then compare, however in the simulator:INT3 interrupts MAIN and starts timer.Timer1 is 'doing it's thing'The interrupt flag never changes, just remains at zero.As INT3 works correctly I am happy that the interrupt vector is working, I know the INT3 doesn't do anything at the moment but I was building in stages and that can come later once I've got this flag working. I thought it would be quite trivial but I guess I'm missing something. As far as I can see internal interrupts are set.Code:#define PULSE LATAbits.LATA0 //define pin RA0 as PULSE pin#define DIR LATAbits.LATA1 //define pin RA1 as DIRECTION pin#define SPEED PORTBbits.RB0 //Define SPEED H/L Pinint BCOUNT;void interrupt high_isr (void){ //High priority interrupt//set up TIMER1 Countif (PIR1bits.TMR1IF == 1){PIR1bits.TMR1IF = 0;BCOUNT++;}if(INTCON3bits.INT3IF == 1){INTCON3bits.INT3IF = 0;PIE1bits.TMR1IE = 1; //Enable Timer1 Interrupt//Start Timer 1 for LONG bounce delayT1CONbits.RD16 = 0; //Operate in 2x8bit modeT1CONbits.T1RUN = 0; //Do not use T1CON clockT1CONbits.T1CKPS = 11; //Prescale 1:8T1CONbits.T1OSCEN = 0; //Shut down T1 OscillatorT1CONbits.TMR1CS = 0; //Use FOSC/4T1CONbits.TMR1ON = 1; //Start timerDIR= ~DIR;}}void delayfive (int loop) // Prototype for pulse timing, wasteful routine.{int i;for (i=0; i<loop; i++){; //do nothing, this is correct, please do not adjust! - This is just a routine to waste instruction cycles.}}int main () {//Set device clock - 4MHz operation//OSCCONbits.IRCF2 = 1; //Make theOSCCONbits.IRCF1 = 1; //internal clockOSCCONbits.IRCF0 = 1; //8MHzTRISAbits.RA0 = 0; //define A0 as OUTPUTTRISAbits.RA1 = 0; //Define RA1 as OUTPUTTRISBbits.RB0 = 1; //define RB0 as INPUTCMCON = 0xFF; //switch OFF comparitorsPWMEN1 = 0xFF; //switch OFF PWM moduleADCON1 = 0xFF; //switch OFF Port-A ADC//Interrupt Settings//RCONbits.IPEN = 1; //enable interrupt priorityINTCONbits.GIE = 1; //enable all interruptsINTCONbits.PEIE =1; //enable internal interruptsINTCON3bits.INT3IE =1; //enable INT3 external interruptINTCON2bits.INTEDG3 =1; //INT3 RISING EDGE interruptDIR = 0;if (SPEED == 1) {delayfive(100);PULSE= 1;delayfive(2);PULSE= 0;}else{delayfive(10);PULSE= 1;delayfive(2);PULSE= 0;}}The timing isn't critical (and indeed isn't really set up yet) but I expected at least to be able to see BCOUNT merrily count up once INT3 is fired?What am I doing wrong here?Cheers,Ed

author: ed_reardon
author_rank: Regular Contributor
timestamp: June 16, 2017, 07:37:34 am
content: Of course I should addPIC18F1330Plain boring free XC8 compiler in MPLAB.

author: KL27x
author_rank: Super Contributor
timestamp: June 16, 2017, 09:41:31 am
content: I see you enabled interrupt priority.It has been along while since I used an 18F. As I recall, when I used high/low priority interrupts, I found I had to set some bits opposite to my interpretation of the datasheet. I can't remember the specifics, but I attribute several grey hairs to this problem. It took a lot of mucking around, and at the time I was fairly convinced the datasheet was wrong. I'll check my datasheet and see if I can find my hand written notes.* sorry no luck

author: leeatljs
author_rank: Contributor
timestamp: June 16, 2017, 09:50:53 am
content: also...declare BCOUNT as volatile like...volatile int BCOUNT;since it can change inside the interrupt without the optimizer knowing about it.

author: JPortici
author_rank: Super Contributor
timestamp: June 16, 2017, 10:09:54 am
content: Always check datasheetANDerratahttp://www.microchip.com/wwwproducts/en/PIC18F1330you find everything at the bottom of the pageyou have this document: TIMER1 Module Data Sheet Errata:http://ww1.microchip.com/downloads/en/DeviceDoc/80329B.pdfmaybe there is what you're looking for?anyway i have a couple of suggersions:- don't use interrupt priority in pic18, it's more a pain in the butt than what it's worth- since there is only one interrupt vector, it is called everytime that an xxIF and xxIE pair are both verified.If you have peripherals that don't have the interrupt enabled at all time, you could service their interrupt also when not needed.. so you should doCode:if (xxIF & xxIE) {xxIF = 0;...}

author: KL27x
author_rank: Super Contributor
timestamp: June 16, 2017, 10:37:46 am
content: QuoteYou might also try turning off INT3 interrupt, completely, rather than just clearing the flag. So you can take it out of the equation.

author: ed_reardon
author_rank: Regular Contributor
timestamp: June 18, 2017, 09:53:24 pm
content: Hey sorry it's Ed again.Right this is starting to get frustrating!Code:#define PULSE LATAbits.LATA0 //define pin RA0 as PULSE pin#define DIR LATAbits.LATA1 //define pin RA1 as DIRECTION pin#define SPEED PORTBbits.RB0 //Define SPEED H/L Pinvolatile int BCOUNT;void interrupt high_isr (void){ //High priority interrupt//set up TIMER1 Countif (PIR1bits.TMR1IF == 1){PIR1bits.TMR1IF = 0;BCOUNT++;}if(INTCON3bits.INT3IF == 1){INTCON3bits.INT3IF = 0;//Start Timer 1 for LONG bounce delayPIE1bits.TMR1IE = 1; //Enable Timer1 InterruptT1CONbits.RD16 = 1; //Operate in 2x8bit modeT1CONbits.T1RUN = 0; //Do not use T1CON clockT1CONbits.T1CKPS = 11; //Prescale 1:8T1CONbits.T1OSCEN = 0; //Shut down T1 OscillatorT1CONbits.TMR1CS = 0; //Use FOSC/4T1CONbits.TMR1ON = 1; //Start timerDIR= ~DIR;}}void delayfive (int loop) // Prototype for pulse timing, wasteful routine.{int i;for (i=0; i<loop; i++){; //do nothing, this is correct, please do not adjust! - This is just a routine to waste instruction cycles.}}int main () {//Set device clock - 4MHz operation//OSCCONbits.IRCF2 = 1; //Make theOSCCONbits.IRCF1 = 1; //internal clockOSCCONbits.IRCF0 = 1; //8MHzTRISAbits.RA0 = 0; //define A0 as OUTPUTTRISAbits.RA1 = 0; //Define RA1 as OUTPUTTRISBbits.RB0 = 1; //define RB0 as INPUTCMCON = 0xFF; //switch OFF comparitorsPWMEN1 = 0xFF; //switch OFF PWM moduleADCON1 = 0xFF; //switch OFF Port-A ADC//Interrupt Settings//INTCONbits.GIE = 1; //enable all interruptsINTCONbits.PEIE =1; //enable internal interruptsINTCON3bits.INT3IE =1; //enable INT3 external interruptINTCON2bits.INTEDG3 =1; //INT3 RISING EDGE interruptDIR = 0;if (SPEED == 1) {delayfive(100);PULSE= 1;delayfive(2);PULSE= 0;}else{delayfive(10);PULSE= 1;delayfive(2);PULSE= 0;}}Now, the plot thickens. The BCOUNT does increment during the ISR, however as soon as it returns to main it is reset to zero.I've declared it volatile (and static) and it's made no difference, if I step through with break-points the counter DOES increment but only for a handful of cycles.Any suggestions?

author: JPortici
author_rank: Super Contributor
timestamp: June 19, 2017, 07:24:23 am
content: "however as soon as it returns to main it is reset to zero"put a data breakpoint, whenever a write to a specific value (0x00) to this variable is made and let it run

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: June 19, 2017, 10:20:13 am
content: You don't have a while(1) loop in main(), so after pulsing RA0 it exits main() and 'reboots' (which reinitializes all the variables). But after being started the timer keeps running, so after a few reboots it triggers the timer interrupt and BCOUNT is incremented. Then on the next reboot BCOUNT is initialized to zero again.

author: ed_reardon
author_rank: Regular Contributor
timestamp: June 19, 2017, 03:13:31 pm
content: You've no idea how much of a numpty I feel right now!Thank you