STM32 PWM Phase Shift (Timer Synchronized) + Example Code

In this tutorial, we’ll discuss The STM32 PWM Phase Shift and how to configure and use the Synchronized Timer Slave Mode With PWM in STM32 microcontrollers to generate phase-shifted PWM output signals with programmable phase angles (45°, 90°, 120°, etc). We’ll implement the STM32 PWM Phase Shift in a code example and a full test project. Without further ado, let’s get right into it!

Table of Contents

  1. STM32 PWM Phase Shift
  2. STM32 PWM Phase Shift (Timer Synchronization)
  3. STM32 PWM Phase Shift Example
  4. Wrap Up

STM32 PWM Phase Shift

Timers in STM32 microcontrollers have a special mode called “Asymmetric PWM” Mode. Which can be used to generate phase-shifted PWM output signals with programmable phase angles between them. Moreover, the timer slave mode can also be used to trigger another timer so they run synchronously and generate phase-shifted PWM signals similar to what could be achieved using Asymmetric PWM mode but with multiple timer units.

One last method that can also be used to generate phase-shifted PWM signals with STM32 microcontrollers is to use interrupt events to synchronize the PWM manually by code inside the ISR. However, this is inefficient from a CPU utilization perspective but it can be doable if, and only if, the PWM output signal’s frequency is relatively low (under 1kHz or so).

Different Methods To Generate Phase-Shifted PWM Outputs With STM32 MCUs:

  1. Use Timer Synchronization (slave mode with trigger)
  2. Use Timer’s Asymmetric PWM Mode (if available in your target MCU)
  3. Use Timer Update Interrupt to manually manipulate the PWM outputs

In this tutorial, we’ll use method number 1 (timer-synchronized PWM Outputs) to generate 3 PWM output signals with programmable phase-shift angles. Since it’s available in all STM32 target microcontrollers and way more efficient than using interrupts.


STM32 PWM Phase Shift (Timer Synchronization)

The STM32 TIMx timers are linked together internally for timer synchronization or chaining. When one Timer is configured in Master Mode, it can reset, start, stop, or clock the counter of another Timer configured in Slave Mode. Using this feature, we can set up TIM1 as a master which triggers TIM2 (slave) that in turn triggers TIM3 (second slave) to generate 3 Phase-Shifted PWM output signals.

Each TIMx timer module can select a trigger source according to the table below.

STM32 Timer Synchronized PWM (Phase Shift)

Keep in mind that the timers (TIM1& TIM2) both need to have an extra channel other than the PWM output channel. That extra channel will be an output-compare-no-output-pin configuration to be used as a trigger output TRGOx that goes into the ITRx of the following timer.

By setting up the three timers (TIM1, TIM2, and TIM3) in this way, we could achieve 3 phase-shifted PWM outputs as shown below.

STM32 PWM Phase Shift (Timer Synchronization - Slave Mode)

❕ Note

Note that the phase shift angle between PWM1 & PWM2 is controlled by the TIM1-OC (output compare) channel. Likewise, the phase shift between PWM2 & PWM3 is controlled by the TIM2-OC channel.


STM32 PWM Phase Shift Example

In this example project, we’ll generate 3 Phase-Shifted PWM outputs with a 120° phase-shift between them, each with a duty cycle of 50% and a PWM frequency of 20kHz.

#1

Open STM32CubeMX, create a new project and select the target microcontroller. For me, it’s (STM32F103C8T6 / BluePill)

#2

Configure the 3 timers (TIM1, TIM2, and TIM3) as follows:

You can use this STM32 PWM Calculator that I’ve made to help you configure the timer PWM mode quickly. The PWM Configurations For the 3 Phase-Shifted PWM outputs will be as follows:

  • PSC = 0, ARR = 3599 (20kHz)
  • PWM1,2,3 Pulse = 1800 (50%)
  • OC1,2 (Phase-Shift) = 1199 (120°)

Here are the three timers’ configurations (side-by-side).

STM32 PWM Phase Shift Synchronized Timer Configurations Example

#3

Go to the Clock configuration page and select a clock source to give you the maximum SysClk of 72MHz (in my case).

STM32 Clock Tree Configuration CubeMX

#4

Name & Generate The Project Initialization Code For CubeIDE or The IDE You’re Using.

STM32 PWM Phase Shift Example Code

Here is The Application Code For This LAB (main.c)

❕ Note

Note that besides starting the 3 PWM output channels, I’ve also enabled and started both TIM1-OC and TIM2-OC output compare channels which are needed to achieve the phase shift between the PWM output signals as illustrated earlier in this tutorial.

STM32 PWM Phase Shift Example Testing

Here are the 3 phase-shifted PWM output signals as shown on my DSO. The 3-phase PWM signals are 20kHz, 50%, 120° apart, and perfectly synchronized.

STM32 PWM Phase Shift Synchronized Timer Example

The measured phase shift between PWM1 & PWM2 is 16.6µs. Given that the period is 50µs, then it’s a 360x(16.6/50) = 120° phase shift.

❕ Note

Each PWM output channel can have its complementary output enabled to help you drive half-bridge (gate driver) configurations if needed. According to the setup we’ve made so far, they’ll still maintain the phase shift relation between each other. The complementary PWM output is just the inverse of each PWM output waveform we already have, with optional dead-time insertion, of course.

For further information, check out this STM32 PWM Complementary Output & Dead-Time Control Tutorial.


Required Parts For STM32 Examples

All the example Code/LABs/Projects in this STM32 Series of Tutorials are done using the Dev boards & Electronic Parts Below:

QTY.Component NameAmazon.comAliExpresseBay
1STM32-F103 BluePill Board (ARM Cortex-M3 @ 72MHz)AmazonAliExpresseBay
1Nucleo-L432KC (ARM Cortex-M4 @ 80MHz)AmazonAliExpresseBay
1ST-Link V2 DebuggerAmazonAliExpresseBay
2BreadBoardAmazonAliExpresseBay
1LEDs KitAmazonAmazonAliExpresseBay
1Resistors KitAmazonAmazonAliExpresseBay
1Capacitors KitAmazonAmazonAliExpress & AliExpresseBay & eBay
1Jumper Wires PackAmazonAmazonAliExpress & AliExpresseBay & eBay
1Push ButtonsAmazonAmazonAliExpresseBay
1PotentiometersAmazonAliExpresseBay
1Micro USB CableAmazonAliExpresseBay

★ Check The Links Below For The Full Course Kit List & LAB Test Equipment Required For Debugging ★

Download Attachments

You can download all attachment files for this Article/Tutorial (project files, schematics, code, etc..) using the link below. Please consider supporting our work through the various support options listed in the link down below. Every small donation helps to keep this website up and running and ultimately supports the whole community.


Wrap Up

In conclusion, we’ve explored the STM32 PWM Phase Shift implementation using timer synchronized slave mode and how to configure the STM32 timers to generate 3-Phase PWM signals with programmable (adjustable) phase shift angles between those PWM output signals.

You can build on top of the provided example code project and integrate it into your system. You can also check the rest of the tutorials in this series to learn more about other features of the STM32 PWM.

Share This Page With Your Network!
Join Our +25,000 Newsletter Subscribers!

Stay Updated With All New Content Releases. You Also Get Occasional FREE Coupon Codes For Courses & Other Stuff!

Photo of author
Author
Khaled Magdy
Embedded systems engineer with several years of experience in embedded software and hardware design. I work as an embedded SW engineer in the Automotive & e-Mobility industry. However, I still do Hardware design and SW development for DSP, Control Systems, Robotics, AI/ML, and other fields I'm passionate about.
I love reading, writing, creating projects, and teaching. A reader by day and a writer by night, it's my lifestyle. I believe that the combination of brilliant minds, bold ideas, and a complete disregard for what is possible, can and will change the world! I will be there when it happens, will you?

3 thoughts on “STM32 PWM Phase Shift (Timer Synchronized) + Example Code”

  1. Hai Khaled Magdy,

    With the same process of STM32 PWM Phase Shift (Timer Synchronized) + Example Code, can we generate a 4phase 90 degree and a 2 phase 180 degree in one.

    Reply
  2. Thanks for your article, I am a rocky STM32 developer and I already implemented a stepper motor controller with 120 degree shift phases, with a LCD display showing the angule of rotation, but after I use HAL_TIM_PWM_Stop for each timer and start again with HAL_TIM_PWM_Start the last timer doesn’t restart, can you help me. Thanks for your time.

    Reply

Leave a Comment