cancel
Showing results for 
Search instead for 
Did you mean: 

Reset timer prescaler counter

manx
Associate III

In my STM32H7 application I start a timer, stop it in an update interrupt handler (by setting ARR to 0), then when appropriate I set a new ARR value thus restarting the timer. This happens very frequently. During each such period I execute a number of compare interrupts. They happen say every 10 us. The timer prescaler is set so one timer count is one microsecond.

I observe some jitter between the timer start and the first compare event time. I suspect a reason for this is that the timer doesn't really start from 0 (even if I write 0 to CNT after restarting the timer, just in case). My guess is then, that the prescaler counter, that counts the actual 240 cycles before incrementing CNT, doesn't get cleared when I stop or restart the timer, or when I clear CNT.

Am I correct? And if so, is there a way to clear the prescaler counter so I'd be able to restart the timer from a REAL zero?

1 ACCEPTED SOLUTION

Accepted Solutions

So I made an experiment on an 'F407 - enabled TIM2 and TIM4 clock in RCC; set TIM2 SMCR to SMS=0b111 exetrnal clock, TS=0b11 i.e. TRGI from TIM4; set ARR=3, PSC=3, set EGR.UG to force PSC to be active; set CR1.CEN=1; then in TIM4 in reset configuration, setting EGR.UG outputs one clock to TRGO, so I can then observe how after 4 clocks TIM2->CNT increments. This all in debugger, not a single line of code.

Using this setup, I observed, that

  • TIM2->CR1.CEN = 0 stops counting for *both* the internal prescaler and CNT
  • TIM2->ARR=0 stops counting ONLY for CNT, the internal prescaler keeps counting and reloading
  • setting TIM2->UG resets both CNT and the internal prescaler, as expected and documented.

'twas fun 🙂

JW

View solution in original post

5 REPLIES 5
TDK
Guru

Raise an update event by setting the EGR->UG bit. This will reset your timer and the prescaler.

Setting ARR to zero is an odd way to stop the timer. Consider clearing the CR1->CEN bit instead and setting to re-enable.

You're only going to get as good as the timer resolution, so 1-2 clock cycles at best. And if you're relying on the timing of an interrupt, that will add a few clocks jitter as well. But you should be able to do way better than 240 clock cycles.

If you feel a post has answered your question, please click "Accept as Solution".
manx
Associate III

Thanks, I'll probably do that.

Since I stop the timer inside an update event, then it's already been reset actually. So then it shouldn't introduce jitter when I stop it immediately at the handler beginning. Also, I played with CR1 |= TIM_CR1_OPM to enable one pulse mode, so the timer is automatically stopped at the update event. This turned out to be exactly what I was looking for, but then I realized I may need something else: to be able to chose if I want to stop the timer in the update event, or let it run. So I'll probably go with the CEN option. Originally I used zeroing ARR since I have to change it's value anyway, and the RM says it stops the timer, so why use two different commands when I could use one 😉

So I made an experiment on an 'F407 - enabled TIM2 and TIM4 clock in RCC; set TIM2 SMCR to SMS=0b111 exetrnal clock, TS=0b11 i.e. TRGI from TIM4; set ARR=3, PSC=3, set EGR.UG to force PSC to be active; set CR1.CEN=1; then in TIM4 in reset configuration, setting EGR.UG outputs one clock to TRGO, so I can then observe how after 4 clocks TIM2->CNT increments. This all in debugger, not a single line of code.

Using this setup, I observed, that

  • TIM2->CR1.CEN = 0 stops counting for *both* the internal prescaler and CNT
  • TIM2->ARR=0 stops counting ONLY for CNT, the internal prescaler keeps counting and reloading
  • setting TIM2->UG resets both CNT and the internal prescaler, as expected and documented.

'twas fun 🙂

JW

manx
Associate III

That was a really great experiment! Thanks for sharing! It's great to know how this behaves under the hood.

dbgarasiya
Senior II

TIMx->CNT = 0 wiil reset counter