Page 1 of 2

Not An Interrupt to be Seen

PostPosted: Tue Jun 10, 2014 9:03 pm
by SLTom992
Here is the initialization procedure I've followed as shown the manual for the PIC18F45K22:

Timer3 is initialized to run wide open on the 4 MHz system clock/4 = 1 uSec per count.

TMR3H = 0; // Clear high byte
TMR3L = 0; // Clear low byte
clrbit(PIR2, TMR3IF); // Clr TMR3 int flag
setbit(PIE2, TMR3IE); // Set timer 3 interrupt enable
setbit(T3CON, TMR3ON); // Set timer 3 running
setbit(INTCON, PEIE); // Set peripheral device interrupt enable
setbit(INTCON, GIE); // Set Global Interrupt Enable
di();
TMR3H = 0xFF; // SET high timer for 125 usec
TMR3L = 0x83; // FF83 == 125 uSec to rollover
ei();

The timer is running but there is no interrupt produced on the tick over from FFFF to 0000.

Can anyone suggest what the heck I'm doing wrong?

Re: Not An Interrupt to be Seen

PostPosted: Tue Jun 10, 2014 9:25 pm
by jtemples
How are you determining there's no interrupt?

We can't know if things like "setbit" are doing what they're supposed to; better to explicitly initialize the registers.

Re: Not An Interrupt to be Seen

PostPosted: Tue Jun 10, 2014 9:44 pm
by SLTom992
I set a breakpoint in the interrupt procedures.

I was setting all of the bits in each register explicitly and when that didn't work I reverted to the set or clr bit functions as per the manual suggestions.

In case it wasn't defaulting everywhere to high priority I explicitly set RCON register with IPEN high and OPR2 with TMR3IP set high. No change.

I have stopped the program and checked the TMR3H & L and they are indeed running.

Re: Not An Interrupt to be Seen

PostPosted: Tue Jun 10, 2014 9:52 pm
by jtemples
Did you look at TMR3IF to see if it's set? If it is, are GIE, PEIE, and TMR3IE all set as well?

Re: Not An Interrupt to be Seen

PostPosted: Tue Jun 10, 2014 10:38 pm
by SLTom992
You appear to be correct - directly after I set INTCON to 0xC0 it reads out 0x06 what do you suppose would cause that?

Re: Not An Interrupt to be Seen

PostPosted: Tue Jun 10, 2014 10:54 pm
by jtemples
Post the complete test program (setting the registers directly) that shows the problem. What compiler are you using?

Re: Not An Interrupt to be Seen

PostPosted: Tue Jun 10, 2014 10:58 pm
by SLTom992
I am using XC-8 Free Version at the moment.

OK, in order to check everything out I set everything explicitly and then set breakpoints and checked the bits set and not.

Everything was OK except for INTCON

T3CON = 0;
TMR3H = 0; // Clear high byte
TMR3L = 0; // Clear low byte
PIR2 = 0b00000000; // Clear TMR2IF
IPR2 = 0b00000010; // Set TMR3IP
PIE2 = 0b00000010; // Set TMR3IE
INTCON = 0xC0; // 0b11000000 GIE and PEIE
TMR3H = 0xFF; // SET high timer for 125 usec
TMR3L = 0x83; // FF83 == 125 uSec to rollover
T3CON = 0b00000001; // TMR3ON

When I set the breakpoint on TMR3H and checked INTCON it was 0x06 instead of 0xC0.

I get the feeling that this has something to do with the CONFIG but certainly can't find anything there that appears to have anything to do with this.

Re: Not An Interrupt to be Seen

PostPosted: Tue Jun 10, 2014 11:26 pm
by jtemples
You've enabled interrupts before assigning to TMR3H, so you're probably vectoring. That's why I asked for a complete program.

Re: Not An Interrupt to be Seen

PostPosted: Tue Jun 10, 2014 11:53 pm
by SLTom992
It said in the manual that you specifically had to zero the counter registers before enabling the interrupts. But apparently the EXACT order of the sets has to be necessary.

I now moved this initialization of the timer to the area directly below the port assignments and put it in the following order:
Code: Select all
    TMR3H = 0;                      // Clear high byte
    TMR3L = 0;                      // Clear low byte
    INTCON = 0b11000000;
    timer3_countL = 8;              // 1 millisecond timeout (in ISR)
    TMR3H = 0xFF;                   // SET high timer for 125 usec
    TMR3L = 0x83;                   // FF83 == 125 uSec to rollover
    PIR2 = 0b00000000;
    RCON = 0b10000000;
    T3CON = 0;
    IPR2 = 0b00000010;
    PIE2 = 0b00000010;
    T3CON = 0b00000001;

And while it appears that I have some sort of timing calculation off somewhere it is working somewhat and the timer IS giving an interrupt.

I would like to thank you for all of your help.

Originally I set the interrupt initialization up exactly as it was written in the manual and it didn't mention that when you're initializing several interrupts you have to do it in a specific order. Interesting.

Re: Not An Interrupt to be Seen

PostPosted: Wed Jun 11, 2014 12:46 am
by ric
I would make
INTCON = 0b11000000;
the very last statement in your initialisation code. You don't want any interrupts to occur until you have finished all the initialisation.