Electronics Design AU
DigitalEmbedded Systems

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:

ApplicationTypical frequency rangeReasoning
Servo control50 HzStandard RC servo protocol: 1–2 ms pulse width at 50 Hz
LED dimming1–10 kHzAbove persistence of vision; reduces visible flicker in camera captures
DC motor speed control1–20 kHzAbove audio range; manageable switching losses
Buck/boost converters50 kHz–5 MHzHigh frequency reduces inductor and capacitor size (see how a buck converter works)
Class-D audio (DAC-less)200 kHz–1 MHzCarrier 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

Related Forum Discussions