The question is old but I was wondering the same and started digging into the topic.

In an STM32 micro, not all timers implement every function. My post is based on the STM32F030 Timer 1, which is I believe the most feature packed 4 channel implementation (or at least it was a few years ago).

The timer basically acts as a counter, with various options to where the counter clock comes from, what resets it, what the period is and the counter direction. This is the base for all extra features it implements, the HAL driver refers to it as Time Base. By itself, the counter function is not related to the timer channels.

There are 1-6 channels implemented in STM32 timers. These channels can be configured either independently, or in some case, in pairs (for functions like quadrature encoder mode). A channel can be configured as either input capture, or output compare. The input capture "listens to" some event and saves the counter of the time base in the CCRx registers. The output compare compares the counter register to a set value, given in the CCRx registers.

All the simple IC/OC modes and the extra functions, like PWM input, output, Hall effect sensor interfacing, are built on top of these two modes, their respective option bits act on the various input/output multiplexers and, regarding to OC mode basically tell the hardware what action to take based on the comparator outputs (CNT = CCRx, CNT > CCRx). In this case, PWM mode lets the output mode controller return to the CNT <= CCRx state when the counter register resets (more specifically, the update event), where as in the other OC modes the output mode controller ignores this signal and can be reset by hand, or by an external signal. The output signal is the OCxREF signal which then passes through some more hardware before it gets to the output pins. If it gets output at all, because you are allowed to not connect the timer to the output pins.

The STM32 timers are complicated. They have many logical blocks and a ton of configuration registers/bits so I may have missed something or completely misread something. Please feel free to correct me.

Answer from Buga Dániel on Stack Overflow
Top answer
1 of 5
13

The question is old but I was wondering the same and started digging into the topic.

In an STM32 micro, not all timers implement every function. My post is based on the STM32F030 Timer 1, which is I believe the most feature packed 4 channel implementation (or at least it was a few years ago).

The timer basically acts as a counter, with various options to where the counter clock comes from, what resets it, what the period is and the counter direction. This is the base for all extra features it implements, the HAL driver refers to it as Time Base. By itself, the counter function is not related to the timer channels.

There are 1-6 channels implemented in STM32 timers. These channels can be configured either independently, or in some case, in pairs (for functions like quadrature encoder mode). A channel can be configured as either input capture, or output compare. The input capture "listens to" some event and saves the counter of the time base in the CCRx registers. The output compare compares the counter register to a set value, given in the CCRx registers.

All the simple IC/OC modes and the extra functions, like PWM input, output, Hall effect sensor interfacing, are built on top of these two modes, their respective option bits act on the various input/output multiplexers and, regarding to OC mode basically tell the hardware what action to take based on the comparator outputs (CNT = CCRx, CNT > CCRx). In this case, PWM mode lets the output mode controller return to the CNT <= CCRx state when the counter register resets (more specifically, the update event), where as in the other OC modes the output mode controller ignores this signal and can be reset by hand, or by an external signal. The output signal is the OCxREF signal which then passes through some more hardware before it gets to the output pins. If it gets output at all, because you are allowed to not connect the timer to the output pins.

The STM32 timers are complicated. They have many logical blocks and a ton of configuration registers/bits so I may have missed something or completely misread something. Please feel free to correct me.

2 of 5
4

PWM modes: Output changes continually based on comparison of counter value and compare register.
-PWM mode 1: (110) if TIMx_CNT < TIMx_CCR1 output is LOW else HIGH
-PWM mode 2: (111) if TIMx_CNT < TIMx_CCR1 output is HIGH else LOW

Output pin state changes two times for one update event, first when CNT == CCR and second when ARR overflows (update event) and is set to back zero (in upcounting). Setting the ARR controls period and setting CCR controls the duty cycle.

OC modes: Output is only changed when counter is equal to compare register
-Toggle on match: (011)
-Set active (high) on match: (001)
-Set inactive (low) on match: (010)

Output pin state changes only when CNT == CCR. The overflow event does not change the pin state.


You can technically generate PWM by using OC mode, but it very impractical. OC mode is more suitable for generating various shape pulses other than PWM.
There is only one "output" block of the timer which can be configured to both modes. There is a lot of other settings (polarity, deadtime, output disconnect) you can find in Reference Manual.

Hint: Let Cube MX and HAL do the dirty work of configuring the timer clock tree and pin assignments (function like MX_TIM8_Init()). Than control the timer and do what you want by directly setting the bits in the timer control registers. It is easier and faster to understand how to work with timer by reading few reference manual pages than trying to understand multiple layers of HAL functions and Cube MX settings. Moreover, you may need to change setting of the timer during the program run, like reconfigure from PWM to OC mode, or generate only one pulse some times.

Top answer
1 of 1
1

You don't need the complexity of chained timers to achieve this on STM32. You can either use TIM_RCR for certain timers to have a Nth UEV interrupt change polarity, or you can simply implement a software counter in an UEV interrupt handler to emulate RCR.

But the most important thing is to use preloaded OC register control for correct glitch-free operation. There are two modes of preloaded control that you can use (TIM1 as an example):

  1. Output in PWM mode with preloaded OC control:
TIM1_CCMR1 = TIM_CCMR1_OC1PE | TIM_CCMR1_OC1M_PWM1;

In this mode, TIM_CCR1 is preloaded, i.e. any changes to it will be applied after UEV (update event). In other words, every write operation changes the next duty cycle, not the current.

This mode is mandatory for glitch-free PWM mode operation.

  1. Preloaded commutation control:
TIM1_CR2 = TIM_CR2_CCPC;

In this mode, changes to certain bits in the TIM1_CCMRx and TIM1_CCER registers are preloaded. The values programmed are applied upon COM (commutation event) which can arrive either as a trigger or via TIM1_EGR = TIM1_EGR_COMG.

This mode is required for glitch-free commutation control.


In your code, you change polarity via TIM2_CCER without any preloaded control enabled, hence glitches are unavoidable. It's also worth noting that your code has excessive latency due to weird statements like while(TIM2->CNT);. In correctly written code, changing polarity even without preloaded control will still give good results albeit not ideal.

The initial requirement is: The original firmware generates PWM (duty cycle 50%) and every 8 cycles inverts the signal

It's hard to come with a good solution without further details. It's unknown, for example, whether duty cycle is always fixed at 50% or should change. If it's fixed, we can come up for instance with another approach - use timer PWM mode with preloaded OC control at twice the frequency and have duty cycle alternate between 0% and 100% in a preloaded fashion. At the 8th iteration, alternation changes.

A very simplified interrupt-based example:

void tim1_up_isr(void) {
    static int n;
    if (!(++n & 7)) return; // Change polarity every 8th iteration, i.e. do not alternate
    TIM1_CCR1 ~= TIM1_CCR1; // Alternate duty cycle between 0% and 100%
}

...
TIM1_BDTR = TIM_BDTR_MOE; // Enable main output
TIM1_CCMR1 = TIM_CCMR1_OC1PE | TIM_CCMR1_OC1M_PWM1; // PWM1 mode, buffered CCR1
TIM1_CCER = TIM_CCER_CC1E; // Enable output
TIM1_DIER = TIM_DIER_UIE; // Enable UEV interrupt

The above is just an example of the preloaded PWM control concept and in no way is the most efficient code.

In the ultimate case, when duty cycle can change and on-the-fly polarity/mode change is required, the only correct way is to use both preloaded commutation control and PWM mode with preloaded OC control.

🌐
DeepBlue
deepbluembedded.com › home › blog › stm32 pwm output example code (pwm generation tutorial)
STM32 PWM Output Example Code (PWM Generation Tutorial)
February 7, 2025 - The compare flag is set when the counter counts up when it counts down or both when it counts up and down depending on the CMS bits configuration. The direction bit (DIR) in the TIMx_CR1 register is updated by hardware and must not be changed ...
🌐
Medium
medium.com › @pqshedy33 › what-is-output-compare-mode-on-stm32-timers-1b231988274b
What is output compare mode on STM32 timers? | by Ampheo | Medium
October 9, 2025 - PWM Mode is so common that it’s treated as a separate mode, but it’s fundamentally built upon the Output Compare circuitry. Here’s the conceptual flow to configure an STM32 timer channel in Output Compare Toggle mode using the HAL library.
🌐
Stack Exchange
electronics.stackexchange.com › questions › 521839 › stm32-configure-output-compare-registers-on-the-fly
pwm - STM32 - Configure Output Compare Registers on the Fly - Electrical Engineering Stack Exchange
September 16, 2020 - \$\begingroup\$ There is an update generation register that controls whether the Output Compare uses whatever value is in the compare register, or whether it shadow buffers the compare register (makes a copy of the register at the beginning of the cycle and uses the value for current cycle allowing the register to be written to in advance for the next cycle).
🌐
Eeworld
en.eeworld.com.cn › news › mcu › eic375644.html
STM32 output comparison mode and PWM mode
At the recent STM32 media communication meeting, Donald CHAN, Director of STM32 Wireless Products, Microcontroller, Digital IC and RF Products Division (MDRF) of STMicroelectronics China, gave a detailed introduction to this new product....
Find elsewhere
🌐
Compile N Run
compilenrun.com › stm32 tutorial › stm32 timers › stm32 output compare
STM32 Output Compare | Compile N Run
The output is set to active level ... the counter matches another value or resets. PWM Mode 1: Output is active when counter < compare value, inactive when counter ≥ compare value...
🌐
YouTube
youtube.com › watch
#21 PWM and output compare
Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube.
🌐
EmbeddedExpertIO
blog.embeddedexpert.io
STM32 Timers Applications: Output Compare Mode – EmbeddedExpertIO
Using Output Compare, the timer can generate a single pulse or a train of pulses with exact timing. Motor Control When combined with PWM (Pulse Width Modulation) applications, Output Compare can help to control motor speed or position by accurately generating switching signals.
🌐
YouTube
youtube.com › watch
STM32 General Purpose Timer: Understanding Output Compare (OC) Mode - YouTube
Enroll for the full course here with this link: http://fastbitlab.com/Our engineers have carefully crafted these courses from which you can learn STM32 inter...
Published   October 13, 2018
🌐
STMicroelectronics
st.com › resource › en › product_training › STM32L4_WDG_TIMERS_GPTIM.pdf pdf
Hello, and welcome to this presentation on the STM32
reload value, compare registers and PWM mode. An 8-bit programmable repetition counter allows you to · decouple the interrupt issuing rate from the counting · period, and have, for instance, one interrupt every single, 2nd, 3rd and up to 256th PWM periods. This is · particularly useful when dealing with high PWM · frequencies. 6 · Some of the STM32 timers feature up/down counting ·
🌐
Dipartimento di Matematica e Informatica
dmi.unict.it › santoro › teaching › lsm › slides › TimerCCP.pdf pdf
Additional Timer Functionalities Capture, Compare and PWM Corrado Santoro
Each STM32 timer has four slave channels · Each channel can be connected to a GPIO line and can be · programmed for: input capture · PWM input measurement · output compare · PWM output generation · Each channel as an additional register CCRy (y is the ·
🌐
STMicroelectronics Community
community.st.com › t5 › stm32-mcus-products › pwm-mode-2-question › td-p › 599083
Pwm mode 2 question - STMicroelectronics Community
October 18, 2023 - Difference occurs only in more complex usage, involving OCxRef signal, e.g. using the Fast mode (set by TIMx_CCMRx.OCxFE) and OCxRef clear (see TIMx_CCMRx.OCxCE). Output polarity also matters in states involving Break, see Advanced Timers.
🌐
STMicroelectronics Community
community.st.com › stmicroelectronics community › discussions › product forums › stm32 mcus › stm32 mcus products › alternative use of timer output compare (pwm) and input compare on the same channel
Alternative use of timer output compare (pwm) and input compare on the same channel | Community
March 27, 2019 - I use a timer channel and a DMA stream to generate a PWM signal. At Transfer Complete interruption, I swap the channel to input capture mode to get an answer from external device, using the same DMA. At transfer (reception) complete, I swap again to output compare mode.
🌐
STMicroelectronics
st.com › resource › en › application_note › an4013-introduction-to-timers-for-stm32-mcus-stmicroelectronics.pdf pdf
AN4013 Application note - Introduction to timers for STM32 ...
February 1, 2026 - The asymmetric PWM3 to PWM10 signals are available only in the STM32C5 series. ... Figure 1. Asymmetric PWM mode versus center aligned PWM mode ... Select the output mode by writing CCS bits in CCMRx register. ... Select the polarity by writing the CCxP bit in CCER register. ... Enable the capture compare.
🌐
DeepBlue
deepbluembedded.com › home › blog › stm32 timers tutorial | hardware timers explained
STM32 Timers Explained Tutorial - Timer Modes Examples Interrupts pwm
January 20, 2024 - The general-purpose timers consist of a 16-bit auto-reload counter driven by a programmable Prescaler. They may be used for a variety of purposes, including measuring the pulse lengths of input signals (input capture) or generating output waveforms (output compare and PWM).
🌐
ControllersTech®
controllerstech.com › home › stm32 tutorials › stm32 timers series › generate pwm output
STM32 PWM Tutorial: Generate PWM with DMA using HAL
I am running a Nucleo-64 with a STM32F401RE on it and the PWM frequency, as clocked by APB1, is nothing compared to what it should be. Say APB1 clock frequency is 84MHz and the pre-scale is 20 I get 19.84MHz on the PWM output?
Published   April 30, 2026