{"id":3920,"date":"2025-11-05T13:00:36","date_gmt":"2025-11-05T13:00:36","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=3920"},"modified":"2025-11-05T13:00:38","modified_gmt":"2025-11-05T13:00:38","slug":"stm32-timers-applications-timer-synchronisation-for-3-phase-pwm","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=3920","title":{"rendered":"STM32 Timers Applications: Timer Synchronisation For 3-Phase PWM\u00a0"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/10349662-e562-46d8-a77d-10af8dc1eaff-1024x683.png\" alt=\"\" class=\"wp-image-3921\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/10349662-e562-46d8-a77d-10af8dc1eaff-1024x683.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/10349662-e562-46d8-a77d-10af8dc1eaff-300x200.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/10349662-e562-46d8-a77d-10af8dc1eaff-768x512.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/10349662-e562-46d8-a77d-10af8dc1eaff-1150x767.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/10349662-e562-46d8-a77d-10af8dc1eaff-750x500.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/10349662-e562-46d8-a77d-10af8dc1eaff-400x267.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/10349662-e562-46d8-a77d-10af8dc1eaff-250x167.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/10349662-e562-46d8-a77d-10af8dc1eaff.png 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Timer synchronization for three-phase PWM generation allows multiple timers to operate with precise&nbsp;<strong>phase shifts<\/strong>, typically 120\u00b0 apart, to produce accurately timed PWM outputs. This phase-shifted synchronization is crucial in applications like three-phase motor drives and inverters, where consistent phase relationships ensure smooth rotation and balanced power delivery.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Introduction.<\/li>\n\n\n\n<li>STM32CubeIDE Setup.<\/li>\n\n\n\n<li>Firmware Development.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Introduction:<\/h2>\n\n\n\n<p>In motor control and power electronics, generating precise and synchronized Pulse Width Modulation (PWM) signals is a fundamental requirement for driving three-phase motors such as Brushless DC (BLDC) or Permanent Magnet Synchronous Motors (PMSM). These applications demand not only accurate frequency and duty cycle control but also precise phase alignment between the three PWM signals\u2014typically spaced by 120\u00b0 electrical degrees. Achieving this synchronization ensures smooth motor rotation, minimizes torque ripple, and enhances system efficiency and performance.<\/p>\n\n\n\n<p>Timer synchronization in STM32 microcontrollers allows multiple timers to operate in a coordinated manner where one timer (the&nbsp;<strong>master<\/strong>) controls the start, update, or reset events of other timers (the&nbsp;<strong>slaves<\/strong>). This feature is critical when generating three-phase PWM signals because it guarantees that each timer starts counting at a defined offset, maintaining exact phase relationships between channels. For instance, in a three-phase inverter control system, Timer 1 can act as the master timer generating Phase A, while Timer 2 and Timer 3 are configured as slave timers producing Phases B and C, each shifted by 120\u00b0 relative to the master.<\/p>\n\n\n\n<p>By using&nbsp;<strong>trigger mode<\/strong>&nbsp;in timer synchronization, the master timer generates synchronization pulses that trigger or reset the slave timers, ensuring all timers operate on a unified time base. This eliminates timing drift caused by independent timer clock domains or interrupt latencies, which could otherwise distort phase relationships and cause imbalance in motor currents. The synchronization can be achieved through internal trigger connections (ITRx lines), allowing timers to exchange synchronization signals internally without using external pins.<\/p>\n\n\n\n<p>This method of generating phase-shifted PWM signals is not only crucial for motor control but also valuable in power converters, multilevel inverters, and interleaved DC-DC converters. It ensures consistent waveform generation, balanced load distribution, and precise control over switching events\u2014key factors in achieving high performance and reliability in embedded power systems. In short, timer synchronization with phase-shifted PWM is one of the most efficient hardware-level techniques to achieve deterministic, real-time control for advanced embedded applications.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. STM32CubeIDE Setup:<\/h2>\n\n\n\n<p>Open STM32CubeIDE after selecting the workspace and create new project as following:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"355\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-1024x355.jpg\" alt=\"\" class=\"wp-image-2940\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-1024x355.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-300x104.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-768x266.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-1536x532.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-2048x709.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-1150x398.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-750x260.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-400x139.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-250x87.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Select the MCU:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"832\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-1024x832.jpg\" alt=\"\" class=\"wp-image-2941\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-1024x832.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-300x244.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-768x624.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-1536x1248.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-2048x1664.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-1150x934.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-750x609.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-400x325.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-250x203.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Give the project a name:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"874\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_10-46-46-874x1024.jpg\" alt=\"\" class=\"wp-image-3922\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_10-46-46-874x1024.jpg 874w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_10-46-46-256x300.jpg 256w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_10-46-46-768x900.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_10-46-46-750x879.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_10-46-46-400x469.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_10-46-46-250x293.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_10-46-46.jpg 976w\" sizes=\"(max-width: 874px) 100vw, 874px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, Enable TIM1 since it will be the master as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Set the clock source to internal clock.<\/li>\n\n\n\n<li>Set Channel 1 as PWM CH1.<\/li>\n\n\n\n<li>Set Channel 2 as Output Compare No Output.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"796\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-28-37-1024x796.jpg\" alt=\"\" class=\"wp-image-3923\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-28-37-1024x796.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-28-37-300x233.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-28-37-768x597.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-28-37-1150x894.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-28-37-750x583.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-28-37-400x311.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-28-37-250x194.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-28-37.jpg 1508w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, in parameter configuration:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Set the counter period to 1600-1.<\/li>\n\n\n\n<li>Trigger Event Selection to Output Compare (OC2REF) since we set CH2 as output compare.<\/li>\n\n\n\n<li>For PWM Generation, set the pulse to 800-1, this will give us 50% duty cycle.<\/li>\n\n\n\n<li>For output Compare, set the mode to Active level on match and pulse to 532.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"742\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-31-33-742x1024.jpg\" alt=\"\" class=\"wp-image-3924\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-31-33-742x1024.jpg 742w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-31-33-218x300.jpg 218w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-31-33-768x1059.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-31-33-1114x1536.jpg 1114w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-31-33-750x1034.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-31-33-400x552.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-31-33-250x345.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-31-33.jpg 1150w\" sizes=\"(max-width: 742px) 100vw, 742px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, enable the TIM2 as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Set slave mode to trigger mode.<\/li>\n\n\n\n<li>Trigger Source to ITR0 since it will be triggered by TIM1.<\/li>\n\n\n\n<li>Set CH1 to PWM and CH2 to output compare no output.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"708\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-35-11-1024x708.jpg\" alt=\"\" class=\"wp-image-3925\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-35-11-1024x708.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-35-11-300x208.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-35-11-768x531.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-35-11-1150x796.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-35-11-750x519.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-35-11-400x277.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-35-11-250x173.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-35-11.jpg 1480w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, configure timer as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Counter Period to 1600-1.<\/li>\n\n\n\n<li>Trigger event selection to output compare (OC2REF)<\/li>\n\n\n\n<li>For PWM Channel, set the pulse to 800-1, this will give us 50% duty cycle.<\/li>\n\n\n\n<li>For output compare channel, set the mode to Active Level on Match and Pulse to 532.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-37-24-939x1024.jpg\" alt=\"\" class=\"wp-image-3926\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-37-24-939x1024.jpg 939w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-37-24-275x300.jpg 275w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-37-24-768x838.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-37-24-1150x1255.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-37-24-750x818.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-37-24-400x436.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-37-24-250x273.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-37-24.jpg 1164w\" sizes=\"(max-width: 939px) 100vw, 939px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>For TIM3, Enable it as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Slave Mode to Trigger Mode.<\/li>\n\n\n\n<li>Trigger source to ITR1 (Triggered by TIM2).<\/li>\n\n\n\n<li>Set Channel 1 to PWM Generation. <\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"643\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-45-34-1024x643.jpg\" alt=\"\" class=\"wp-image-3927\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-45-34-1024x643.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-45-34-300x188.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-45-34-768x482.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-45-34-1150x722.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-45-34-750x471.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-45-34-400x251.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-45-34-250x157.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-45-34.jpg 1484w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>For TIM3 configuration:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Set counter period to 1600-1.<\/li>\n\n\n\n<li>Set pulse of PWM to 800-1.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"934\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-48-48-934x1024.jpg\" alt=\"\" class=\"wp-image-3928\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-48-48-934x1024.jpg 934w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-48-48-274x300.jpg 274w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-48-48-768x842.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-48-48-1150x1261.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-48-48-750x823.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-48-48-400x439.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-48-48-250x274.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-48-48.jpg 1156w\" sizes=\"(max-width: 934px) 100vw, 934px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>With those configuration, the following pins will be enabled:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>PA8 for TIM1_CH1.<\/li>\n\n\n\n<li>PA0 for TIM2_CH1.<\/li>\n\n\n\n<li>PA6 for TIM3_CH1.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"948\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-52-51-1024x948.jpg\" alt=\"\" class=\"wp-image-3929\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-52-51-1024x948.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-52-51-300x278.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-52-51-768x711.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-52-51-1150x1065.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-52-51-750x695.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-52-51-400x370.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-52-51-250x232.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-05_15-52-51.jpg 1490w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>That all for the configuration. Save the project and this will generate the code.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Firmware Development: <\/h2>\n\n\n\n<p>Once the code has been generated, main.c shall be opened.<\/p>\n\n\n\n<p>In main.c in user code begin 2 in main function, start TIM3 as follows:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">HAL_TIM_PWM_Start(&amp;htim3, TIM_CHANNEL_1);<\/pre><\/div>\n\n\n\n<p>Since TIM3 has only PWM, we only need to start the PWM channel.<\/p>\n\n\n\n<p>For TIM2:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">HAL_TIM_PWM_Start(&amp;htim2, TIM_CHANNEL_1);\nHAL_TIM_OC_Start(&amp;htim2, TIM_CHANNEL_2);<\/pre><\/div>\n\n\n\n<p>For TIM2, we need to start CH1 as PWM and CH2 as Output Compare.<\/p>\n\n\n\n<p>For TIM1:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">HAL_TIM_PWM_Start(&amp;htim1, TIM_CHANNEL_1);\nHAL_TIM_OC_Start(&amp;htim1, TIM_CHANNEL_2);<\/pre><\/div>\n\n\n\n<p>Similar to TIM2.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>That all for the firmware. Save, build and run the project.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Results:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>By using either logic analyzer or oscilloscope, probe PA8, PA0 and PA6, you should get the following:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"630\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/RigolDS22.png\" alt=\"\" class=\"wp-image-3930\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/RigolDS22.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/RigolDS22-300x185.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/RigolDS22-768x473.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/RigolDS22-750x461.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/RigolDS22-400x246.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/RigolDS22-250x154.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Note that the frequency is 10KHz and we set the period (16000000\/1600)=10,000 and the phase difference is 120 degree and intended.<\/p>\n\n\n\n<p>Now, we have the basic of PWM generation for three phase.<\/p>\n\n\n\n<p>Happy coding \ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Timer synchronization for three-phase PWM generation allows multiple timers to operate with precise&nbsp;phase shifts, typically 120\u00b0 apart, to produce accurately timed PWM outputs. This phase-shifted synchronization is crucial in applications like three-phase motor drives and inverters, where consistent phase relationships ensure smooth rotation and balanced power delivery. In this guide, we shall cover the following: [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,11,12],"tags":[],"class_list":["post-3920","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3920"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3920"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3920\/revisions"}],"predecessor-version":[{"id":3931,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3920\/revisions\/3931"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3920"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3920"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3920"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}