cancel
Showing results for 
Search instead for 
Did you mean: 

APB1 and APB2 are out of sync

SZano
Associate III

I'm using STM32F446.
I'm generating PWM signals using TIM1 and TIM8 (on APB2, which runs at 90MHz, and 180MHz for the timers).
I'm also generating PWM signals using TIM4 and TIM12 (on APB1, which runs at 45MHz, and 90MHz for the timers).

I start each PWM independently, so their starting edges are not synchronized, but this is not the point.
TIM1 and TIM8 are "in sync" in the sense that the shift between the two signals remains perfectly constant, with no drift whatsoever.
TIM4 and TIM12 are also "in sync" in this sense.
However, TIM1-8 and TIM4-12 are not in sync with each other; their relative phase shifts around in an unpredictable way, and quite quickly. I'm not sure whether it's just jitter (i.e. the drift averages to 0 over a long period of time) or the drift diverges.
Of course I'm prescaling TIM1-8 by 2, so that the counting frequency is the same as that of TIM4-12.
Even if I change the APB2 prescaler so that the two buses are at the same frequency, the out-of-sync behavior persists.

I would assume that APB1 and APB2 should never have any relative jitter in their frequency, since they are both derived from the same clock (HCLK), just scaled differently.
So, why do I observe the behavior explained above?
Is it expected? Is there any way to sync APB1 and APB2 perfectly?

Could I avoid the PWM problem by chaining the timers together, so that one single timer (possibly a basic one?) can generate the counting base, which is then consumed by all the other timers (TIM1-4-8-12), so that they are in sync?

 

Edit: there is a similar issue for STM32F746:

https://community.st.com/t5/stm32-mcus-products/timers-out-of-sync-32f746gdiscovery/m-p/403260#M114294

which never had any reply

1 ACCEPTED SOLUTION

Accepted Solutions

>> The prescaler within the TIM is NOT VISIBLE, you can set the COUNT, your can't see the COUNTER.
Now I see what you mean.
Yes, the prescaler is a counter itself, which is not accessible, and its overflow signal is what actually feeds the timer counter (which is visible, instead).
Setting the counter to 0 does not affect the prescaler counter, so the timer gets skewed by the amount of "partial prescale counting" that is still present.

Anyway, the problem was really silly: as you pointed out, the prescaler value is PSC+1 (i.e. the register is 0-based, while the actual factor is 1-based). I had programmed the timers with PSC=90 and PSC=180, in order to get 1MHz for all of them, both on APB1 @90MHz and on APB2 @180MHz. However, these values result in actual prescaling factors of 91 and 181, hence the slightly shifted PWM frequency.
I tried running both APB1 and APB2 @90MHz, but I didn't change the prescaler values (expecting an off-by-2x PWM frequency), so the problem persisted in this condition too.

Thanks a lot to you and Jan for your help and patience.

View solution in original post

8 REPLIES 8

> However, TIM1-8 and TIM4-12 are not in sync with each other; their relative phase shifts around in an unpredictable way, and quite quickly.

Do you (A) start the timers once and then leave them run freely with no changes; or (B) start/stop them or change their ARR or CCRx (Period/Pulse), while making the above observation?

Perhaps post a minimal, simple, but complete compilable example exhibiting the problem.

JW

You can run both APB1 and APB2 at the same, SLOWER speeds, and they should then be synchronous.

Even so the PSC divider count is not visible to you from the TIM

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I start them once and leave them freely running.

I don't have a minimal example now, I'll prepare one tomorrow.

Could you please elaborate?

 

I tried this:

HCLK 180MHz

APB1_timer = HCLK / 4 * 2 = 90MHz

APB2_timer = HCLK / 2 * 2 = 180MHz

 

And also this:

HCLK 180MHz

APB1_timer = HCLK / 4 * 2 = 90MHz

APB2_timer = HCLK / 4 * 2 = 90MHz

 

Both use the APB prescaler, not the prescaler inside the TIM peripheral (that one, I use to get the proper PWM frequency).

 

Both configurations produce the drifting behavior.

I'm not accessing any TIM register when the timers are running, so I'm not interfering on the bus in any way (I don't know if that might be a problem).

 

>> Even so the PSC divider count is not visible to you from the TIM

I don't understand what you mean

 

>> SLOWER speeds

Do you mean lower than 90MHz, or just lower than the maximum 90/180MHz, which prevents APB1 and APB2 to be at the same frequency?

The prescaler within the TIM is NOT VISIBLE, you can set the COUNT, your can't see the COUNTER.

Doing a reset of the counter via the APB can result in skewed / phase shifted behaviour.

You perhaps need to find a way to share a COMMON reset event for all the TIM you wish to keep synchronous.

If you're not modifying registers, I'm not sure why there would be slippage. PSC and ARR are both N-1 lengths.

The best way of keeping things in-phase is to use all the channels, but you can't do multiple frequencies because there's only a single counting element in each TIM. One could for example control 4x 50 Hz (20 ms) Servos from a single TIM

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

How exactly do you observe the timers?

Cannot the observed behaviour be explained by aliasing/sampling effects within your equipment (LA, oscilloscope)?

JW

>> The prescaler within the TIM is NOT VISIBLE, you can set the COUNT, your can't see the COUNTER.
Now I see what you mean.
Yes, the prescaler is a counter itself, which is not accessible, and its overflow signal is what actually feeds the timer counter (which is visible, instead).
Setting the counter to 0 does not affect the prescaler counter, so the timer gets skewed by the amount of "partial prescale counting" that is still present.

Anyway, the problem was really silly: as you pointed out, the prescaler value is PSC+1 (i.e. the register is 0-based, while the actual factor is 1-based). I had programmed the timers with PSC=90 and PSC=180, in order to get 1MHz for all of them, both on APB1 @90MHz and on APB2 @180MHz. However, these values result in actual prescaling factors of 91 and 181, hence the slightly shifted PWM frequency.
I tried running both APB1 and APB2 @90MHz, but I didn't change the prescaler values (expecting an off-by-2x PWM frequency), so the problem persisted in this condition too.

Thanks a lot to you and Jan for your help and patience.

We all do this sort of mistakes. This is why we discuss here, to have a second opinion.

Thanks for coming back with the solution. Please click on "Accept as solution" in your post so that the thread is marked as solved.

JW