PWM Explained: Frequency, Duty Cycle, Dead-Time, and Hardware Timers
Last updated 29 June 2026 · 11 min read
Direct Answer
PWM (Pulse Width Modulation) generates an average voltage by rapidly switching a digital output between high and low at a fixed frequency, varying the proportion of time the output is high (the duty cycle). A 50% duty cycle produces half the supply voltage as an average, 100% produces full voltage. The key parameters are frequency (how fast the output switches), duty cycle (the on-time fraction), and resolution (the number of distinct duty cycle steps). Always use a hardware timer peripheral for PWM — software PWM from a timer interrupt lacks the timing accuracy needed for motor control, SMPS, or audio, and consumes CPU cycles that the application needs for other work.
Detailed Explanation
PWM is one of the most fundamental techniques in embedded systems. It appears everywhere: motor speed control, LED brightness, servo positioning, switch-mode power supply control, Class-D audio amplifiers, and heater power regulation. Understanding the core parameters and the hardware that implements them is essential for using PWM correctly.
The Core Concept: Averaging by Switching
A PWM output is a digital signal that alternates between high (supply voltage) and low (ground) at a fixed frequency. The average output voltage is proportional to the fraction of the period that the signal is high:
V_average = V_supply × (Duty Cycle / 100%)
Where duty cycle is the proportion of the period the output is high, expressed as a percentage:
Duty Cycle = (T_on / T_period) × 100%
For a 3.3 V MCU output:
- 0% duty cycle → 0 V average
- 25% duty cycle → 0.825 V average
- 50% duty cycle → 1.65 V average
- 75% duty cycle → 2.475 V average
- 100% duty cycle → 3.3 V average
The load sees this as an effective voltage only if it has a time constant significantly longer than the PWM period. An inductor in a motor winding naturally averages the switching current. An LED appears at a stable brightness if the switching rate is faster than the eye's flicker fusion threshold (typically 50–100 Hz, though camera systems require higher frequencies to avoid beat patterns). A low-pass filter explicitly averages the PWM output into a DC voltage — this is how microcontrollers can produce analog outputs without a DAC.
Key Parameters
Frequency
PWM frequency determines how fast the output switches. The appropriate frequency depends on the application:
| Application | Typical frequency range | Reasoning |
|---|---|---|
| Servo control | 50 Hz | Standard RC servo protocol: 1–2 ms pulse width at 50 Hz |
| LED dimming | 1–10 kHz | Above persistence of vision; reduces visible flicker in camera captures |
| DC motor speed control | 1–20 kHz | Above audio range; manageable switching losses |
| Buck/boost converters | 50 kHz–5 MHz | High frequency reduces inductor and capacitor size (see how a buck converter works) |
| Class-D audio (DAC-less) | 200 kHz–1 MHz | Carrier must be well above audio bandwidth (20 kHz) |
Frequency choice involves trade-offs: higher frequency reduces ripple and filtering requirements but increases switching losses in power transistors and reduces resolution at a given timer clock rate.
Duty Cycle
Duty cycle maps directly to the controlled quantity — motor speed, LED brightness, output voltage. Most hardware timer implementations express duty cycle as a count value (the compare register) relative to the period count (the auto-reload register):
Duty Cycle = CCR / (ARR + 1) (STM32 notation)
Where CCR is the capture/compare register value and ARR is the auto-reload register (period count minus 1).
Setting CCR = 0 produces 0% duty cycle; setting CCR = ARR produces approximately 100% duty cycle (depending on the PWM mode configuration).
Resolution
Resolution is the number of distinct duty cycle steps the hardware can produce. It is set by the timer counter's period:
- A period of 256 counts gives 8-bit resolution (256 steps)
- A period of 1,024 counts gives 10-bit resolution
- A period of 4,000 counts gives approximately 12-bit resolution
For a given timer clock frequency f_clock:
Count_period = f_clock / f_PWM
This count period is the available resolution. For an 80 MHz timer clock at 20 kHz PWM:
- Count_period = 80,000,000 / 20,000 = 4,000 steps ≈ 11.9 bits
At 100 kHz:
- Count_period = 80,000,000 / 100,000 = 800 steps ≈ 9.6 bits
Higher PWM frequency sacrifices resolution. Choose the lowest frequency that meets the application's ripple and response requirements to preserve resolution.
Hardware Timer PWM vs Software PWM
Hardware Timer PWM
The MCU's hardware timer peripheral generates the PWM waveform autonomously. Firmware sets the period (ARR), initial duty cycle (CCR), and polarity, then enables the timer output. From that point, the timer hardware handles all GPIO toggling without any CPU involvement.
Benefits:
- CPU-independent: the timer runs even when the CPU is in a critical section, handling other interrupts, or in a sleep state.
- Accurate timing: transitions occur at exact timer counts, not subject to interrupt latency.
- Multi-channel: a single timer peripheral often drives 3–4 independent PWM channels simultaneously — useful for 3-phase motor drives.
- Dead-time hardware insertion (on advanced timers): complementary outputs with programmable dead-time, managed by the timer hardware.
Software PWM
Software PWM toggles a GPIO in a timer interrupt or DMA event. Any GPIO can be used, but timing accuracy degrades under interrupt load:
- At 50 Hz (servo control), a few microseconds of interrupt latency is typically acceptable — servo motors are not sensitive to microsecond timing errors.
- At 20 kHz (motor control), the period is 50 µs. A 5 µs interrupt latency jitter is 10% of the period — unacceptable for smooth motor control.
- At frequencies above 10 kHz, software PWM becomes impractical for most embedded systems.
Rule: Use hardware timer PWM for any application requiring accurate timing (motor control, SMPS, audio). Use software PWM only for low-frequency, coarse-resolution applications (LED dimming at a few hundred Hz, servo at 50 Hz) where hardware timer channels are not available.
Dead-Time for Complementary Outputs
Motor H-bridges and synchronous rectifiers in SMPS designs use complementary PWM: two outputs — high-side (HS) and low-side (LS) switches — that are nominally opposite in phase. If both switches turn on simultaneously, even briefly, they create a direct short-circuit between supply and ground through the switching transistors. This is shoot-through current, which is destructive.
Dead-time is a brief interval at each transition when both HS and LS are off simultaneously, preventing shoot-through. During dead-time, the load current circulates through the body diode of whichever transistor is turning on.
Dead-time requirements depend on the switching device:
- Silicon MOSFETs: typically 100 ns–1 µs, depending on gate charge and driver characteristics
- GaN FETs: typically 20–100 ns (faster switching)
- IGBTs: typically 500 ns–5 µs
Shorter dead-time reduces dead-time voltage distortion; longer dead-time ensures reliable shoot-through prevention across manufacturing variation and temperature. Most motor control designs use a conservatively chosen fixed dead-time rather than adaptive dead-time.
Advanced timer peripherals on many MCUs (STM32 TIM1 and TIM8 on STM32F4/G4/H7; the complementary output module on some STM32G0 parts) provide hardware dead-time insertion via the BDTR (Break and Dead-Time Register). The hardware automatically inserts the programmed dead-time gap at every HS/LS transition without requiring firmware to manage the timing — the only reliable approach for motor control at switching frequencies above approximately 1 kHz.
MCU Timer Peripheral Overview
Different MCU families implement PWM differently, but the underlying concepts are consistent:
STM32 (TIMx peripheral): Standard timers (TIM2–TIM5 on many series) have up to 4 capture-compare channels (CH1–CH4), each mappable to specific GPIO pins per the datasheet alternate function table. Advanced control timers (TIM1, TIM8) add complementary outputs (CH1N–CH3N) and hardware dead-time. Configure with HAL_TIM_PWM_Start() after setting ARR and CCRx.
ESP32 (LEDC peripheral): A dedicated LED Controller peripheral offering up to 8 high-speed and 8 low-speed PWM channels, each configurable for 1–20 bit resolution. Unlike many MCU timers, LEDC can route its output to any GPIO through the IO_MUX/GPIO matrix. Configure with ledc_timer_config() and ledc_channel_config().
nRF52 (PWM peripheral): Up to 4 independent PWM modules, each with 4 channels and a 15-bit counter, configurable for 125 kHz–8 MHz PWM frequency. The nRF52840 PWM peripheral supports sequence playback mode, which can automatically step through an array of duty cycle values in DMA — useful for audio and complex waveforms.
RP2040 (PWM slices): 16 independent PWM slices, each with A and B channels and a 16-bit counter. Flexible counter wrap register sets the period. Duty cycle is set by the CC (Channel Level) register. RP2040's PIO (Programmable I/O) state machines can also generate PWM on any pin at higher precision if needed.
Design Considerations
- Output filter for DAC use: when using PWM as a simple DAC, a first-order RC low-pass filter (R in series, C to GND) at the GPIO output converts the PWM to a DC voltage. Set the filter's cutoff frequency (f_c = 1 / (2πRC)) at least 10× below the PWM frequency and well above the highest frequency in the control signal to avoid attenuating the useful bandwidth.
- Timer clock source affects frequency accuracy: the timer clock is derived from the MCU's peripheral bus clock (APB clock on STM32; LEDC clock source on ESP32). Ensure the base clock is stable before configuring the timer — a poorly configured PLL or HSE failure will produce drifting PWM frequency. See STM32 clock tree explained for clock configuration and common setup errors.
- GPIO drive strength matters for fast PWM: at high frequencies (above 100 kHz), the GPIO's output drive strength affects the rise and fall times of the PWM signal. Slow rise times at the gate of a power FET increase switching losses. Configure the GPIO output speed for the appropriate slew rate — higher drive strength for high-speed PWM into a gate driver, lower drive for LED dimming to reduce EMI.
- DMA-linked PWM for waveform generation: some MCU timer peripherals support DMA burst transfers to the compare register, allowing the firmware to pre-load an array of duty cycle values that the timer steps through automatically at each PWM period. This enables waveform synthesis (audio, haptic), motor ramp profiles, and multi-axis servo sequences without interrupt-driven firmware.
- Deadband compensation for motor voltage accuracy: dead-time distorts the effective duty cycle — during dead-time, the output voltage is determined by the load current direction (forward or reverse through the body diode), not the commanded duty cycle. For precision DC motor control (servo or position applications), dead-band compensation in firmware corrects for this distortion, particularly at low duty cycles near zero. At low speeds, dead-time represents a larger fraction of the active period and the effect is most pronounced.
For embedded products requiring motor control firmware, multi-channel PWM generation, or power converter drive signals, Zeus Design's firmware team develops production-grade PWM and motor control firmware for STM32, ESP32, and nRF platforms.
Common Mistakes
- Using software PWM for motor control or SMPS — interrupt latency produces timing jitter that causes audible noise, torque ripple, and efficiency loss. Hardware timer PWM is mandatory for any application above a few hundred Hz or requiring accurate dead-time control.
- Not accounting for dead-time loss in duty cycle — the effective output voltage is slightly lower than commanded because of dead-time. At low duty cycles, dead-time can consume a significant fraction of the active window, causing a minimum effective speed or voltage below which the output is unpredictable. Design duty cycle limits into the control loop to avoid this non-linear region.
- Setting PWM frequency too high for the timer resolution — at high PWM frequencies, the count period drops to tens or hundreds of counts, drastically reducing resolution. A 1 MHz PWM at 80 MHz timer clock gives only 80 steps (~6.3 bits) — insufficient for smooth speed control. Match the frequency to the application and verify the resulting resolution is adequate.
- Forgetting to configure the GPIO as alternate function output — configuring the timer for PWM but leaving the GPIO in its default input or general output mode produces no PWM at the pin. The GPIO must be configured for the appropriate alternate function (AF) number to connect the timer output to the pin. CubeMX handles this automatically; manually written code must explicitly set the AF register.
- Using the wrong servo PWM frequency — standard RC servos expect a 50 Hz PWM signal with pulse widths between 1 ms (0°) and 2 ms (180°), though many servos tolerate up to 333 Hz. Digital servos often accept higher update rates, but standard analog servos driven at higher frequencies may jitter or lock up. Always verify the servo's specification before changing the PWM frequency.
Frequently Asked Questions
- What PWM frequency should I use for motor control?
- DC motors and H-bridge drives typically use PWM frequencies in the range of 1–20 kHz. Below 1 kHz, audible switching noise from the motor windings is common. Above 20 kHz the switching losses in the FETs increase and the dead-time becomes a significant fraction of the period, reducing effective duty cycle range. 8–15 kHz is a common working range for brushed DC motor control using MOSFETs. For brushless DC (BLDC) and stepper motors, 10–25 kHz is typical. Always keep the PWM frequency well above the motor winding's L/R time constant to ensure current ripple stays within acceptable limits.
- What is the difference between PWM resolution and PWM frequency?
- PWM resolution is the number of distinct duty cycle steps available — typically expressed in bits (8-bit = 256 steps, 10-bit = 1024 steps). It is determined by the timer's counter period: a 1,000-count period gives 1,000 steps. PWM frequency is how often the waveform period completes per second. For a given timer clock, frequency and resolution trade against each other: halving the frequency doubles the count period and adds one bit of resolution. At 80 MHz with a 20 kHz PWM, the counter runs to 4,000, giving approximately 12 bits of resolution. At 80 kHz PWM, the same timer yields 1,000 counts — just under 10 bits.
- Can I generate PWM on any GPIO pin?
- For software PWM, any digital output-capable GPIO can be used. For hardware PWM, only GPIO pins connected to a timer's capture-compare channel in the MCU's signal routing matrix are available. On STM32, each timer output (TIMx_CHy) is connected to specific GPIO pins defined in the datasheet's alternate function table — you must route the timer output to a compatible pin. On ESP32, the LEDC peripheral can route to any GPIO through the IO_MUX/GPIO matrix, giving more flexibility. Always check the MCU datasheet rather than assuming a specific pin can carry hardware PWM.
References
Related Questions
What Are Logic Gates and How Do They Work?
Logic gates are the building blocks of digital circuits. AND, OR, NOT, NAND, NOR, XOR: truth tables, Boolean algebra, CMOS implementation, and universal gates.
How Do GPIO Pins Work on a Microcontroller?
GPIO (General Purpose Input/Output) pins let a microcontroller read digital signals and drive outputs. Learn how push-pull, open-drain, and pull resistors work.
What Are Interrupts in Embedded Systems and How Do They Work?
Interrupts let a microcontroller respond to hardware events instantly without polling. Learn how ISRs, NVIC priority, and interrupt latency work.
Bare-Metal vs RTOS: Which Should You Use for Your Firmware?
Bare-metal firmware and RTOS suit different embedded projects. Learn the trade-offs — timing, RAM overhead, complexity — and how to choose.
How Does a Buck Converter Work?
A buck converter steps down voltage using a switching MOSFET and LC filter. Learn how duty cycle sets Vout, CCM vs DCM, and key component selection pitfalls.
Signal Integrity in PCB Design: Reflections, Crosstalk, and Termination
Transmission line effects, reflections, crosstalk, and termination strategies for PCB designers. Learn when signal integrity matters and how to address it.
Related Forum Discussions
FPGA design passes timing analysis and simulation but fails intermittently in hardware — is this a clock domain crossing issue?
I'm on my first real FPGA project at work and I'm getting intermittent data corruption that I can't explain. The design has two clock domain
STM32 GPIO interrupt configured but ISR never fires — what am I missing?
Trying to use a button on PA0 to trigger an interrupt on an STM32F411 Nucleo board. Using HAL, generated the init code with CubeMX. The GPIO
Can't decide between FreeRTOS and bare-metal for a simple sensor node — what's the tipping point?
Working on a temperature and humidity monitoring node — STM32F103 target, BME280 over I2C, reports data every 60 seconds over UART to a Rasp