{"id":3874,"date":"2025-10-22T09:11:08","date_gmt":"2025-10-22T09:11:08","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=3874"},"modified":"2025-10-22T09:11:10","modified_gmt":"2025-10-22T09:11:10","slug":"stm32-timers-applications-timer-synchronisation-trigger-mode","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=3874","title":{"rendered":"STM32 Timers Applications: Timer Synchronisation Trigger Mode"},"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\/10\/ChatGPT-Image-Oct-22-2025-at-11_25_17-AM-1024x683.png\" alt=\"\" class=\"wp-image-3875\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/ChatGPT-Image-Oct-22-2025-at-11_25_17-AM-1024x683.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/ChatGPT-Image-Oct-22-2025-at-11_25_17-AM-300x200.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/ChatGPT-Image-Oct-22-2025-at-11_25_17-AM-768x512.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/ChatGPT-Image-Oct-22-2025-at-11_25_17-AM-1150x767.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/ChatGPT-Image-Oct-22-2025-at-11_25_17-AM-750x500.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/ChatGPT-Image-Oct-22-2025-at-11_25_17-AM-400x267.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/ChatGPT-Image-Oct-22-2025-at-11_25_17-AM-250x167.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/ChatGPT-Image-Oct-22-2025-at-11_25_17-AM.png 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Timer synchronization on STM32 allows multiple timers to operate in a coordinated manner using\u00a0<strong>trigger modes<\/strong>, enabling one timer to act as a master and others as slaves. This mechanism supports precise phase alignment, cascaded triggering, and synchronized PWM generation, making it ideal for applications such as motor control, power converters, and multi-channel signal generation where accurate timing relationships are crucial.<\/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 and how does it work.<\/li>\n\n\n\n<li>Timer internal connection.<\/li>\n\n\n\n<li>STM32CubeIDE setup.<\/li>\n\n\n\n<li>Firmware development.<\/li>\n\n\n\n<li>Results.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1. Introduction and How Does it Work:<br><\/h2>\n\n\n\n<p>Timer synchronization in STM32 microcontrollers is one of the most powerful and underappreciated features of the advanced timer architecture. It allows multiple timers to work together seamlessly, sharing timing information and triggering events in a highly deterministic way. This is achieved through&nbsp;<strong>master-slave relationships<\/strong>&nbsp;established via internal&nbsp;<strong>trigger connections<\/strong>&nbsp;(known as TRGO and ITR lines), where one timer acts as the master \u2014 generating synchronization signals \u2014 and one or more other timers operate as slaves, responding to those signals based on configurable trigger modes.<\/p>\n\n\n\n<p>At its core, synchronization ensures that timing operations \u2014 such as counting, PWM generation, and capture\/compare events \u2014 occur in perfect coordination. This is critical in embedded control systems where even microsecond-level misalignment can cause system instability or inefficiency. For example, in&nbsp;<strong>three-phase motor control<\/strong>, each PWM signal controlling the motor windings must be precisely phase-shifted relative to the others; even minor timing drift can result in torque ripple or reduced efficiency. Similarly, in&nbsp;<strong>DC-DC converters or inverters<\/strong>, synchronized PWM outputs are necessary to control multiple power stages operating in parallel, minimizing noise, improving power balance, and achieving higher overall performance.<\/p>\n\n\n\n<p>The&nbsp;<strong>trigger mode<\/strong>&nbsp;plays a central role in synchronization. In this mode, a slave timer listens to an external or internal trigger source \u2014 such as an update event or a compare match from the master timer \u2014 and reacts by starting, stopping, resetting, or gating its counter based on how it\u2019s configured. This makes it possible to chain timers in complex configurations, such as one timer controlling another to generate time-staggered pulses, periodic ADC conversions, or cascaded event sequences. STM32 timers support multiple synchronization schemes, including&nbsp;<strong>reset mode<\/strong>,&nbsp;<strong>gated mode<\/strong>, and&nbsp;<strong>trigger mode<\/strong>, each providing a different way to control timing relationships between modules.<\/p>\n\n\n\n<p>Another important advantage is&nbsp;<strong>hardware-level precision<\/strong>. Unlike software-based synchronization \u2014 which depends on CPU timing and can suffer from latency or jitter \u2014 hardware timer synchronization operates entirely within the timer subsystem, driven directly by the clock tree and peripheral interconnects. This eliminates software-induced timing uncertainty, making it ideal for high-speed or real-time control applications.<\/p>\n\n\n\n<p>In practical systems, timer synchronization can be extended beyond PWM generation. It can synchronize&nbsp;<strong>ADC sampling<\/strong>to ensure data acquisition occurs exactly when PWM outputs reach a certain phase, or align multiple&nbsp;<strong>output compare channels<\/strong>&nbsp;for signal generation. Even external triggers (such as encoder pulses or sensor events) can participate in synchronization chains, allowing flexible hybrid designs that blend internal and external timing sources.<\/p>\n\n\n\n<p>Ultimately, timer synchronization provides engineers with a way to build complex, timing-dependent systems that behave deterministically, without relying on processor intervention. This capability allows STM32-based designs to rival or even surpass more expensive real-time hardware in precision and reliability. It\u2019s a cornerstone of any advanced embedded control design \u2014 from robotics and motor drives to precision instrumentation and power electronics \u2014 where synchronized timing defines the system\u2019s accuracy, stability, and performance.<\/p>\n\n\n\n<p>Timer synchronization in STM32 microcontrollers works by creating a&nbsp;<strong>coordinated timing network<\/strong>&nbsp;between two or more hardware timers, where one timer acts as a&nbsp;<strong>master<\/strong>&nbsp;and others function as&nbsp;<strong>slaves<\/strong>. This coordination is made possible by a series of internal connections called&nbsp;<strong>trigger signals (TRGO and ITRx)<\/strong>, which allow timers to exchange synchronization events without CPU intervention. The synchronization mechanism ensures that timing operations \u2014 such as counting, starting, stopping, or resetting \u2014 occur at precisely defined instants relative to each other, enabling highly deterministic system behavior.<\/p>\n\n\n\n<p>When configured in synchronization mode, the&nbsp;<strong>master timer<\/strong>&nbsp;generates a trigger output signal (TRGO) based on one of its internal events \u2014 typically an update event, a compare match, or an overflow. This TRGO signal is routed internally to other timers via inter-timer trigger inputs (ITR0, ITR1, etc.), which serve as&nbsp;<strong>trigger sources<\/strong>&nbsp;for the&nbsp;<strong>slave timers<\/strong>. Each slave timer has a&nbsp;<strong>trigger selection (TS)<\/strong>&nbsp;field that defines which internal trigger it listens to and a&nbsp;<strong>slave mode (SMS)<\/strong>&nbsp;field that determines how it responds when a trigger occurs.<\/p>\n\n\n\n<p>Here\u2019s how it works in practice:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Master timer event generation:<\/strong>\u00a0The master timer runs according to its own clock and prescaler settings. When it reaches a predefined condition \u2014 such as an update event (counter overflow) \u2014 it emits a trigger signal (TRGO).<\/li>\n\n\n\n<li><strong>Trigger propagation:<\/strong>\u00a0The trigger is routed internally via the STM32\u2019s timer interconnection matrix to one or more slave timers.<\/li>\n\n\n\n<li><strong>Slave timer response:<\/strong>\u00a0The slave timers are configured in one of several\u00a0<strong>slave modes<\/strong>:\n<ul class=\"wp-block-list\">\n<li><strong>Reset mode:<\/strong>\u00a0The slave counter resets whenever a trigger is received. Useful for aligning counters.<\/li>\n\n\n\n<li><strong>Gated mode:<\/strong>\u00a0The slave counts only while the trigger is active, effectively gating its operation.<\/li>\n\n\n\n<li><strong>Trigger mode:<\/strong>\u00a0The slave starts counting on a trigger edge and stops based on its own configuration.<\/li>\n\n\n\n<li><strong>External clock mode:<\/strong>\u00a0The slave uses the trigger input as its clock source.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Synchronized operation:<\/strong>\u00a0Once synchronized, the timers operate in harmony \u2014 their counting, PWM generation, or output compare events remain phase-aligned or sequentially coordinated according to the design.<\/li>\n<\/ol>\n\n\n\n<p>This synchronization happens&nbsp;<strong>entirely in hardware<\/strong>, which is the key to its precision and speed. Unlike software-based coordination, which is subject to interrupt latency and CPU jitter, hardware timer synchronization is driven by the same peripheral bus and clock system, guaranteeing nanosecond-level consistency.<\/p>\n\n\n\n<p>The result is a flexible and scalable timing architecture where multiple timers can be cascaded or aligned to achieve complex time-dependent behaviors. For example:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>PWM synchronization:<\/strong>\u00a0A master timer generates a trigger that starts multiple slave timers, ensuring all PWM channels begin simultaneously or at controlled phase offsets.<\/li>\n\n\n\n<li><strong>ADC synchronization:<\/strong>\u00a0A timer\u2019s TRGO can start ADC conversions at exact intervals synchronized to PWM switching.<\/li>\n\n\n\n<li><strong>Multi-axis motor control:<\/strong>\u00a0Three timers can be synchronized with 120\u00b0 phase shifts to drive a three-phase inverter.<\/li>\n\n\n\n<li><strong>Event sequencing:<\/strong>\u00a0One timer can trigger another to create cascaded timing events (e.g., pulse trains or stepper motor control).<\/li>\n<\/ul>\n\n\n\n<p>In summary, STM32 timer synchronization works by connecting the output of one timer (master) to the trigger input of another (slave) through internal routing lines. By configuring each timer\u2019s trigger selection and response mode, designers can build precise timing networks that operate with deterministic accuracy, low jitter, and zero CPU overhead \u2014 a vital requirement in motor control, power electronics, synchronized data acquisition, and other real-time embedded systems.<\/p>\n\n\n\n<p>Trigger mode basically controls the start of the slave counter. Here the master timer issues a trigger signal, which resumes the counter on the slave timer.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"524\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/trigger1-1024x524.webp\" alt=\"\" class=\"wp-image-3876\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/trigger1-1024x524.webp 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/trigger1-300x153.webp 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/trigger1-768x393.webp 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/trigger1-750x383.webp 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/trigger1-400x204.webp 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/trigger1-250x128.webp 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/trigger1.webp 1113w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>As shown in the picture above, the TIMER 2 (Slave) counter was paused at 45. Once the TIM1 (master) issues Update Event (UEV) signal, the TIM2 counter resumes counting.<\/p>\n\n\n\n<p>Note here that the counter does not reset to 0, rather it just resumes from wherever it was paused. Also the trigger mode only controls the start of the counter, and not the stop.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Timer Internal Connection:<\/h2>\n\n\n\n<p>As per reference manual of STM32F446RE:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"314\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-38-58-1024x314.jpg\" alt=\"\" class=\"wp-image-3877\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-38-58-1024x314.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-38-58-300x92.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-38-58-768x236.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-38-58-1536x471.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-38-58-1150x353.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-38-58-750x230.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-38-58-400x123.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-38-58-250x77.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-38-58.jpg 1884w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Here the&nbsp;<strong>RED&nbsp;<\/strong>box represents the Slave Timers, The&nbsp;<strong>BLUE&nbsp;<\/strong>box represents the master Timer, and the&nbsp;<strong>GREEN&nbsp;<\/strong>box represents the signal used by the master to control the slave.<\/p>\n\n\n\n<p>So the Timers 2, 3 and 4 can be controlled by the same master, TIM1 by using the signal ITR0.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. 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\/10\/2025-10-22_10-45-12-874x1024.jpg\" alt=\"\" class=\"wp-image-3878\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_10-45-12-874x1024.jpg 874w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_10-45-12-256x300.jpg 256w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_10-45-12-768x900.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_10-45-12-750x879.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_10-45-12-400x469.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_10-45-12-250x293.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_10-45-12.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 CH1 as Output PWM<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"663\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-47-04-1024x663.jpg\" alt=\"\" class=\"wp-image-3879\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-47-04-1024x663.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-47-04-300x194.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-47-04-768x497.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-47-04-1536x994.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-47-04-1150x744.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-47-04-750x485.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-47-04-400x259.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-47-04-250x162.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-47-04.jpg 1882w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, in Parameters Settings set the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Set the PSC to 16-1, this will reduce the timer frequency to 1MHz (default speed is 16MHz for F4).<\/li>\n\n\n\n<li>Set the Counter Period to 1000-1, this will give PMW frequency of 1KHz.<\/li>\n\n\n\n<li>Set the trigger event selection to update event.<\/li>\n\n\n\n<li>Set the pulse to 300-1, this will give 30% duty cycle.<\/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=\"867\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-49-17-867x1024.jpg\" alt=\"\" class=\"wp-image-3880\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-49-17-867x1024.jpg 867w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-49-17-254x300.jpg 254w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-49-17-768x907.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-49-17-750x886.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-49-17-400x472.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-49-17-250x295.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-49-17.jpg 1062w\" sizes=\"(max-width: 867px) 100vw, 867px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, enable TIM2 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 ITR0.<\/li>\n\n\n\n<li>Clock source to internal.<\/li>\n\n\n\n<li>Set channel 1 to PWM generation.<\/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=\"1024\" height=\"505\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-52-04-1024x505.jpg\" alt=\"\" class=\"wp-image-3881\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-52-04-1024x505.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-52-04-300x148.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-52-04-768x379.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-52-04-1536x758.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-52-04-1150x568.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-52-04-750x370.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-52-04-400x197.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-52-04-250x123.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-52-04.jpg 1860w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, in Parameters Settings:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Set the PSC and Counter Period to 16-1 and 1000-1 respectively.<\/li>\n\n\n\n<li>Set the Pulse to 6001, this will give Duty cycle <\/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=\"846\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-54-17-846x1024.jpg\" alt=\"\" class=\"wp-image-3882\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-54-17-846x1024.jpg 846w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-54-17-248x300.jpg 248w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-54-17-768x930.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-54-17-750x908.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-54-17-400x484.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-54-17-250x303.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_11-54-17.jpg 1046w\" sizes=\"(max-width: 846px) 100vw, 846px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Once the timers have been configured, you will notice that PA0 and PA8 has been enabled for TIM2_CH1 and TIM1_CH1 respectively as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"940\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_12-02-28-1024x940.jpg\" alt=\"\" class=\"wp-image-3883\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_12-02-28-1024x940.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_12-02-28-300x275.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_12-02-28-768x705.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_12-02-28-1536x1410.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_12-02-28-1150x1056.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_12-02-28-750x688.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_12-02-28-400x367.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_12-02-28-250x229.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/2025-10-22_12-02-28.jpg 1584w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>That all for the STM32CubeIDE setup. 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\">4. Firmware Development:<\/h2>\n\n\n\n<p>Once the project is generated, main.c will be opened. In main.c file in user code begin 2 in main function, start TIM2 in PWM mode followed by TIM1 in PWM 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;}\">  \tHAL_TIM_PWM_Start(&amp;htim2, TIM_CHANNEL_1);\n  \tHAL_Delay(200);\n  \tHAL_TIM_PWM_Start(&amp;htim1, TIM_CHANNEL_1);<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Results:<\/h2>\n\n\n\n<p>By using oscilloscope or logic analyzer, probe PA0 and PA8.<\/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\/10\/RigolDS15.png\" alt=\"\" class=\"wp-image-3884\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS15.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS15-300x185.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS15-768x473.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS15-750x461.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS15-400x246.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS15-250x154.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>D0 is TIM1_CH1 and D1 is TIM2_CH1.<\/p>\n\n\n\n<p>Note that bit timer started after 200ms from TIM2_CH1 goes to high. Which is expected since there is a delay of 200ms.<\/p>\n\n\n\n<p>If you zoom in, you find the following:<\/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\/10\/RigolDS16.png\" alt=\"\" class=\"wp-image-3885\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS16.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS16-300x185.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS16-768x473.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS16-750x461.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS16-400x246.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS16-250x154.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Notice that TIM2_CH1 started to generate PWM signal after 1ms from TIM1_CH1 started the PWM signal.<\/p>\n\n\n\n<p>We have successfully synchronised two timers.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Notice here with rising edge of each channel, they are aligned together.  <\/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\/10\/RigolDS17.png\" alt=\"\" class=\"wp-image-3886\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS17.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS17-300x185.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS17-768x473.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS17-750x461.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS17-400x246.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/10\/RigolDS17-250x154.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Now, you can synchronise TIM3, TIM4 and TIM5 in same manner.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, we shall cascade two timers into one timer.<\/p>\n\n\n\n<p>Stay tuned.<\/p>\n\n\n\n<p>Happy coding \ud83d\ude09<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Timer synchronization on STM32 allows multiple timers to operate in a coordinated manner using\u00a0trigger modes, enabling one timer to act as a master and others as slaves. This mechanism supports precise phase alignment, cascaded triggering, and synchronized PWM generation, making it ideal for applications such as motor control, power converters, and multi-channel signal generation where [&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-3874","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\/3874"}],"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=3874"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3874\/revisions"}],"predecessor-version":[{"id":3887,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3874\/revisions\/3887"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3874"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3874"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3874"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}