2
\$\begingroup\$

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?

\$\endgroup\$
  • 1
    \$\begingroup\$ If you enable an interrupt and don't specify an ISR, bad things are going to happen. The CPU will jump to the vector regardless of whether or not you've put any ISR code in your firmware... \$\endgroup\$ – Adam Lawrence Aug 16 '13 at 18:47
  • \$\begingroup\$ Well, I guess that explains it why it runs perfectly fine during the step-by-step execution. Thanks. \$\endgroup\$ – udushu Aug 16 '13 at 19:05
  • \$\begingroup\$ Things can be different in debug mode vs. application mode, especially with ISRs (my experience with Microchip). \$\endgroup\$ – Adam Lawrence Aug 16 '13 at 19:08
4
\$\begingroup\$

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)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.