Electronic – Why does DSPIC33F restarts when timer interrupt flag is addressed

interruptsmicrochipmicrocontrollerpic

I have a peculiar problem with the timer on the DSPIC33F. I need to create a delay function and I have decided to use Timer 2 to count the number of instruction cycles. The function would enable the timer and then wait in the while loop waiting for the interrupt flag to be set. See code below:

T2CONbits.TON = 0;                  // disable Timer 2  
IFS0bits.T2IF = 0;                  // reset Timer 2 interrupt flag
TMR2 = 0;                           // reset timer accumulator
T2CONbits.TON = 1;                  // enable Timer 2

while(!IFS0bits.T2IF);              // Wait until until the timer 2 timeout
IFS0bits.T2IF = 0;                  // reset Timer 2 interrupt flag

T2CONbits.TON = 0;                  // disable Timer 2

The function works perfectly fine if the TMR2 interrupts are disabled. However, if the TMR2 interrupts are enabled, the firmware restarts when the interrupt flag is set. This restart only happens when I run through the code, but not during the step-by-step execution (I am using the ICD3 with MPLab 8.something). I did not setup the ISR for TMR2. All other interrupts are disabled.

Even though I have achieved my goal of creating the delay function, I am still wondering about the possible reasons for the firmware restart. Is that because for some reason I can address the interrupt flag only inside the ISR? Or are there any other reasons?

Best Answer

Page 2 in the PIC33f Interrupts family reference illustrates how interrupt process works for the dsPIC33f:

http://ww1.microchip.com/downloads/en/DeviceDoc/70300C.pdf

When you enable an interrupt (e.g. T2IE) and the interrupt fires it goes to the address location found at the peripheral interrupt vector. if you did not define a legal address for the peripheral the peripheral interrupt vector will have an unknown address (perhaps 0) and when the interrupt will fire it will go to that address and unpredictable things can happen

in your case, assuming the ALTIVT bit (INTCON2<15>) is cleared, when the the TMR2 interrupt fires it will go to the address location found in 0x000022.

when you write:

void __attribute__((__interrupt__, auto_psv)) _T2Interrupt (void)
{

}

you actually telling your compiler that you would like to place the address of the start of this code at address 0x000022 (TMR2 IVT Address)

and when you write:

void __attribute__((__interrupt__, auto_psv)) _AltT2Interrupt (void)
{

}

you are telling your compiler to place the address of the start of this code at address 0x000122 (TMR2 AIVT Address)