The puzzle
An LED should glow at 30 % brightness and a motor should turn at half speed, but a pin can only be fully on or fully off. Switch it fast enough, though, and the LED’s brightness, the motor’s speed or a filtered voltage follows the fraction of time it is on. How fast, how finely, and what does the signal look like?
STEP 1
Duty cycle from a compare level
A PWM channel is output compare (lesson 4) with a fixed rule: the output is high for a number of counts set by the compare level and low for the rest of the counter period (in the usual convention: the RP2040’s default and STM32 PWM mode 1 counting up; inverted modes swap the levels). With the counter running 0…TOP:
↑ This step uses the figure at the top of the page.
All channels of one counter share its frequency and can have different duties: ST’s example drives four channels of one timer at 50 %, 37.5 %, 25 % and 12.5 %. Compare levels are double-buffered like the period (always on the RP2040; on the STM32 when output-compare preload is enabled, as ST’s HAL does for PWM), so a new duty starts at the next period boundary, never mid-pulse. Check your part’s convention for the extremes: on many timers, 100 % needs a level of TOP + 1, which a 16-bit register cannot hold when TOP = 65 535.
STEP 2
Edge-aligned and centre-aligned
In the default edge-aligned mode the counter wraps from TOP to 0 and every pulse starts at the beginning of the period. In centre-aligned mode (the RP2040 calls it phase-correct) the counter counts up to TOP and back down, so every pulse is centred on the same instant of the period and the frequency halves (exactly on the RP2040; approximately on the STM32, whose centre-aligned period is 2 × ARR). At a given frequency, centre-aligned PWM has one bit less resolution. Centre-aligned PWM is preferred for motor drives: pulses on different channels stay centred on each other, and the switching events of the phases are spread in time.
STEP 3
Frequency versus resolution
With the counter running at the full clock, one period holds f_clk/f_PWM counts, and that count is the resolution:
With the counter running at the full input clock, one PWM period holds f_clk/f_pwm counts, so resolution in bits is log₂(f_clk/f_pwm): faster PWM means coarser steps. An RC low-pass filter turns PWM into a steady voltage; the figure computes the exact first-order peak-to-peak ripple, which for RC much longer than the period is about VDD·D(1 − D)/(f_pwm·RC), largest at 50 % duty.
At 125 MHz, 20 kHz gives 6250 steps (about 12.6 bits); 1 MHz gives 125 steps (7 bits). The frequency is chosen for the load, and the resolution follows:
| load | frequency | why |
|---|---|---|
| LED brightness | a few hundred Hz to tens of kHz | above flicker; higher helps with camera banding |
| DC motor via a MOSFET | about 20 kHz or more | above hearing, low enough for switching losses |
| RC-filtered DAC | as high as resolution allows | ripple falls with frequency |
STEP 4
Filtering PWM into a voltage
An RC low-pass filter averages the PWM into a steady voltage. For RC much longer than the PWM period, the remaining ripple is approximately
largest at 50 % duty, and the output settles to within 0.7 % of a new duty in about 5RC (within half a step of an N-bit PWM takes about RC·ln 2^(N+1), unit 11). A larger RC means less ripple and a slower response; a higher PWM frequency reduces ripple without slowing the response, at the cost of resolution. That is the whole design space of a PWM DAC.
STEP 5
Worked example: an LED dimmer and a PWM DAC on the same chip
LED. clk_sys = 125 MHz, DIV = 5, TOP = 999: f = 125 MHz / 5000 = 25 kHz, within the table’s range, with 1000 brightness steps. For 30 %: level = 300.
DAC. For a 3.3 V control voltage with 10-bit resolution, TOP + 1 = 1024: f = 125 MHz / 1024 ≈ 122 kHz. With RC = 1 ms, the worst-case ripple is
about two steps of 3.2 mV, and the output settles in about 5 ms. A second RC stage, or a higher frequency with fewer bits, trades these further.
MYTHS AND FACTS
Common misconceptions
Higher PWM frequency is always better
It costs resolution and, in power stages, switching losses.
The average voltage is exact
It is exact on average; the load or filter sees the ripple, and the output driver’s resistance and the supply tolerance affect the levels.
Changing the duty takes effect immediately
Compare levels are double-buffered and load at the next period boundary.
Centre-aligned PWM has the same frequency
With the same TOP it runs at (about) half the frequency.
Check yourself
Answer in your head, then open the card.
clk_sys = 125 MHz, DIV = 5, TOP = 2499. What is the PWM frequency, and which level gives 40 % duty?
125 MHz / (5 × 2500) = 10 kHz; level = 0.4 × 2500 = 1000.
How many bits of resolution does a 50 kHz PWM have on a 100 MHz counter clock?
100 MHz / 50 kHz = 2000 steps, log₂ 2000 ≈ 11 bits.
The same settings are switched to phase-correct mode. What happens to the frequency and the pulse position?
The frequency halves, to 5 kHz in the first question's example, and the pulse is centred in the period.
A PWM DAC at 20 kHz uses RC = 1 ms. Estimate the ripple at 50 % duty at 3.3 V.
3.3 × 0.25 / (20 000 × 0.001) ≈ 41 mV peak to peak.
Sources (3)
- Raspberry Pi Ltd, pico-sdk 1.5.1, hardware_pwm/pwm.h — “continuously comparing the input value to a free-running counter … the amount of time spent at the high output level is proportional to the input value”; counter runs at clk_sys / div up to the wrap value TOP; phase-correct mode counts back down and “The output frequency is halved”; compare levels and TOP are double-buffered, taking effect at the next wrap (or at 0 in phase-correct mode); 8 slices, 16 outputs, all 30 GPIOs
- STMicroelectronics, stm32f4xx-hal-driver, Inc/stm32f4xx_hal_tim.h — TIM_OCMODE_PWM1 and TIM_OCMODE_PWM2 (PWM2 is the inverted mode); TIM_COUNTERMODE_UP and TIM_COUNTERMODE_CENTERALIGNED1–3 for edge- and centre-aligned PWM
- STMicroelectronics, STM32CubeF4, Projects/STM324xG_EVAL/Examples/TIM/TIM_PWMOutput/Src/main.c — four channels of one timer at the same frequency with nominal duty cycles of 50 %, 37.5 %, 25 % and 12.5 %, set by each channel’s CCR (the example’s own period arithmetic is approximate)