2
\$\begingroup\$

I'm having a little suprise with timer interrupt on update event. I thought that if timer is configured to count up, update event will occure just after the overflow, i.e. when CNT will become equal to zero. According to figures 103-105 from reference manual.

But that doesn't seem to be the case for some reason. I tested it with this simple code:

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

// tick frequency in Hz
const uint32_t tickFreq = 1000*1000; 
const uint16_t timPrescaler = SystemCoreClock / (tickFreq ) - 1;

TIM_TimeBaseInitTypeDef timBaseStruct;
timBaseStruct.TIM_Prescaler = timPrescaler;
timBaseStruct.TIM_ClockDivision = 0; 
timBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
timBaseStruct.TIM_Period = 5;

TIM_TimeBaseInit(TIM2, &timBaseStruct);

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE );
NVIC_EnableIRQ(TIM2_IRQn);

Then in the irq handler:

void TIM2_IRQHandler(void)
{

    if(TIM2->CNT != 0)
    {
         TIM2->CNT = 1;   // <----------- and I put a breakpoint on this line
    }

    TIM2->SR = ( uint16_t ) ~TIM_IT_Update;
}

I don't have anything else enabled, no critical sections, just an empty while loop.

I also have an .ini file for debugger, so when I stop the execution, all timers are also stopped.

Now the interesting bit.

When I debug in the Keil Simulator - execution doesn't stop on the breakpoint. But when I debug on the board - execution stops on the breakpoint and I can see that TIM2->CNT is equal to 1!

It does appear to be connected with tick frequency, if I make it a thousand times less, breakpoint doesn't stop the execution. But what the hell, it's just 1 MHz; CPU is clocked on 72 MHz!

Now I wonder - is it a bug in the simulator or in the hardware? Or I have simply misread something and timer is not initialized properly?

\$\endgroup\$
1
  • \$\begingroup\$ I think it's unsafe to assume that the behaviour of the simulator perfectly mimics the behaviour of the hardware. \$\endgroup\$
    – markt
    Commented Nov 7, 2014 at 11:55

2 Answers 2

2
\$\begingroup\$

Okay, that appears to be the debugger messing up the timings.

I substituted breakpoint with turning the LED on, and without debugger it stays off. If I enter debugging and won't enable breakpoint before the start - LED stays off.

Only if I enable the breakpoint and then start the execution - breakpoint does fire and the LED turns on.

\$\endgroup\$
0
\$\begingroup\$

I don't think it's a safe mode to read the timer in the interrupt routine. I think when your ISR is called, the timer is still running!! If your systick's interrupt priority is higher than TIM2's, the TIM2's interrupt function maybe delayed. So when your code is called, the timer may have changed.

I suggest you improve TIM2's interrupt priority to higher than systick, and have a try.

\$\endgroup\$
3
  • \$\begingroup\$ As I mentioned in the question, everything else is disabled, including systick. I really doubt that calling the interrupt handler and checking one register takes more than 1 microsecond. \$\endgroup\$
    – Amomum
    Commented Nov 7, 2014 at 11:49
  • \$\begingroup\$ I'm sure the debug function will slow down the running. \$\endgroup\$
    – diverger
    Commented Nov 7, 2014 at 12:07
  • \$\begingroup\$ yes, that is correct. \$\endgroup\$
    – Amomum
    Commented Nov 7, 2014 at 12:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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