2021-04-04 10:29 AM
Hey folks!
Got some questions around synced timers on STM32F401, where the aim is to have two timers start together, where one timer has a period an integer multiple of the other. I've got what I need working but how it works, doesn't add up.
Here's the "short" summary:
I've got two timers with PWM output. TIM1 is the master and enables TIM2. The PWM OC for both is set to fire at the same value. Both are UP counters and everything else.
I want the period of TIM2 to be a multiple of TIM1, i.e., so for every N pulses out of TIM1 I get a single pulse out of TIM2. My intuition tells me this should mean:
TIM2.Period = TIM1.Period * N
However, what I'm finding is that I actually need to do:
TIM2.Period = (TIM1.Period * N) + (N - 1)
Looking at it on a scope, without this extra addition the pulses don't sync --- i.e., TIM1 bounces around relative to TIM2.
If I set prescalar to any value and keep the periods the same, I don't get this issue --- but I need the "resolution" so that doesn't work for particular application (but just makes things more confusing).
So my question is here --- what's the deal with these extra needed cycles? Is there an extra clock tick before the update event or something? I've scanned the datasheet several times looking at the timing diagrams and I just can't work it out. I'm 99% sure everything else is configured correctly.
Extra Stuff And Other Thoughts
I'm using https://www.st.com/en/evaluation-tools/nucleo-f401re.html this Nucleo board.
Code is attached which is Cube based --- so everything in the setup bar some extras is coming right out of there. It's not exactly in the state above as described but it's a similar example. I can work up a minimum test case if not good.
TIM1 has DMA attached to drive GPIO pins but toggling all that seemed to have no effect.
I tried fiddling with clock settings (HSI vs HSE) to no effect.
Solved! Go to Solution.
2021-04-04 11:59 AM
What you and Cube call Timerx.Period is a value loaded into TIMx_ARR.
The timer's period, let's denote it Tx, is given as TIMx_ARR + 1, see TIM chapter in RM.
Thus, if you want :
T2 = N * T1
(TIM2_ARR + 1) = N * (TIM1_ARR + 1)
TIM2_ARR = N * TIM1_ARR + N - 1
Q.E.D.
JW
2021-04-04 11:59 AM
What you and Cube call Timerx.Period is a value loaded into TIMx_ARR.
The timer's period, let's denote it Tx, is given as TIMx_ARR + 1, see TIM chapter in RM.
Thus, if you want :
T2 = N * T1
(TIM2_ARR + 1) = N * (TIM1_ARR + 1)
TIM2_ARR = N * TIM1_ARR + N - 1
Q.E.D.
JW
2021-04-04 12:14 PM
Perfect answer. Thanks! I lay it out in text and it's immediately obvious --- doh! Because it's ARR inclusive, right?
2 --> 0 1 2 0 1 2 0 1 2 0 1 2
4 --> 0 1 2 3 4 0 1 2 3 4
8 --> 0 1 2 3 4 5 6 7 8
2021-04-04 02:55 PM
> Because it's ARR inclusive, right?
Yes.
JW