Peripherals
intermediate
Weight: 4/10

Timers and PWM

Master timer peripherals and PWM generation including counting modes, prescaler configuration, input capture, output compare, and dead-time insertion for embedded systems.

peripherals
timers
pwm
capture
compare

Quick Cap

Timers are hardware counters clocked from the system clock (or an external source) that count up, down, or both, providing the timing backbone for PWM generation, input signal measurement, and precise event scheduling -- all with zero CPU overhead once configured. PWM (Pulse Width Modulation) is the most common timer output mode: it produces a digital waveform whose average voltage is controlled by varying the ratio of HIGH time to total period, enabling analog-like control of motors, LEDs, and power converters using a single digital pin.

Interviewers test whether you can reason about the relationship between clock, prescaler, auto-reload, and compare registers, and whether you understand the practical trade-offs between frequency, resolution, and application requirements.

Key Facts:

  • Hardware counters: Timers count independently of the CPU -- once started, they run without software intervention
  • Prescaler + ARR determine frequency: f_PWM = f_CLK / ((PSC+1) * (ARR+1))
  • Compare register controls duty cycle: Duty cycle = CCR / (ARR+1), where CCR is the capture/compare register value
  • Input capture: Snapshots the counter value on an external edge -- used for frequency and pulse width measurement
  • Output compare: Triggers an action (interrupt, pin toggle, DMA request) when the counter matches CCR
  • Dead-time insertion: Prevents shoot-through in H-bridge and inverter circuits by ensuring both switches are never ON simultaneously

Deep Dive

At a Glance

CharacteristicDetail
Clock sourceInternal (APB bus clock) or external pin
Counter width16-bit (most timers) or 32-bit (select advanced timers)
Counting modesUp, down, center-aligned (up-down)
ChannelsTypically 4 capture/compare channels per timer
PWM outputsEdge-aligned or center-aligned, with optional complementary outputs
Key registersPSC (prescaler), ARR (auto-reload), CCRx (capture/compare)
Interrupt sourcesUpdate (overflow), capture, compare, break (fault)

How Timers Work

A hardware timer is fundamentally a counter driven by a clock. The signal path is: system clock -> prescaler -> counter -> compare/reload -> interrupt or output action. Each stage shapes the timing behavior.

The prescaler (PSC) divides the incoming clock before it reaches the counter. A prescaler value of 0 means the counter increments at the full system clock rate; a value of 71 on a 72 MHz system yields a 1 MHz counting rate (one tick per microsecond). The prescaler register is 16 bits wide, so division ratios from 1 to 65536 are possible.

The counter (CNT) increments (or decrements) on each prescaled clock tick. Its behavior depends on the counting mode:

  • Up-counting: The counter starts at 0 and counts up to the auto-reload value (ARR). When it reaches ARR, it overflows back to 0 and generates an update event. This is the most common mode and the default for PWM generation.
  • Down-counting: The counter starts at ARR and counts down to 0, then reloads ARR and generates an update event. Used in countdown/watchdog-style applications.
  • Center-aligned (up-down): The counter counts from 0 up to ARR, then back down to 0, generating update events at both the top and the bottom (or just one, depending on configuration). This mode is critical for motor control because it produces symmetric PWM waveforms with lower harmonic content.

The auto-reload register (ARR) sets the counter's ceiling (in up-counting) or starting point (in down-counting). Together with the prescaler, it determines the timer's overflow frequency -- and therefore the PWM frequency:

px-2 py-1 rounded text-sm font-mono border
f_PWM = f_CLK / ((PSC + 1) * (ARR + 1))

For example, with a 72 MHz system clock, PSC = 71, and ARR = 999: f_PWM = 72,000,000 / (72 * 1000) = 1000 Hz. The prescaler gives you a convenient 1 MHz tick rate, and the ARR gives you 1000 ticks per period -- a 1 kHz PWM with 0.1% duty cycle resolution (1000 discrete steps).

The capture/compare registers (CCR1-CCR4) are the interface between the counter and the outside world. In output compare / PWM mode, the timer compares the counter against CCR on every tick and drives the output pin accordingly. In input capture mode, the timer copies the current counter value into CCR when an external edge is detected. Each timer typically has four independent channels, each with its own CCR.

PWM Generation

PWM works by toggling an output pin based on the relationship between the running counter and the compare register value. In edge-aligned mode (up-counting), the output is set HIGH when the counter resets to 0 and cleared LOW when the counter reaches CCR. The result is a waveform where the HIGH time equals CCR ticks and the LOW time equals (ARR - CCR) ticks.

px-2 py-1 rounded text-sm font-mono border
CCR ARR
| |
VDD ───┐ │
│ HIGH (CCR ticks) │
│──────────────────┐ │
│ │ │
GND ───┘ └───┘── (overflow → reload to 0)
LOW
|← duty cycle →|← remaining →|
| (CCR) | (ARR-CCR) |
|←──── one PWM period (ARR+1) ────→|

The duty cycle is simply CCR / (ARR + 1). To get 75% duty cycle with ARR = 999, set CCR = 750. To get 0% (always LOW), set CCR = 0. To get 100% (always HIGH), set CCR greater than ARR.

In center-aligned mode, the counter counts up to ARR and then back down to 0. The output toggles twice per period -- once on the way up when the counter matches CCR, and once on the way down. This produces a symmetric pulse centered in the period, which has two important advantages: lower harmonic distortion (important for motor drives and audio) and natural alignment of switching edges across multiple channels (important for three-phase inverters).

Frequency vs. resolution trade-off: The number of discrete duty cycle steps equals ARR + 1. A higher ARR gives finer resolution but lowers the PWM frequency (since f_PWM = f_CLK / ((PSC+1) * (ARR+1))). For motor control at 20 kHz with a 72 MHz clock and PSC = 0, ARR = 3599, giving 3600 steps of resolution (~0.03%). For a servo at 50 Hz, ARR can be very large, offering extremely fine resolution. The art is choosing PSC and ARR to hit the target frequency while maximizing resolution.

💡Quick Mental Math

Set PSC so that the prescaled clock is a round number (e.g., 1 MHz). Then ARR directly equals the number of microseconds per period. For a 1 kHz PWM: PSC gives 1 MHz tick rate, ARR = 999, period = 1000 us = 1 ms.

Input Capture

Input capture is the reverse of PWM generation: instead of the timer driving an output, an external signal captures the timer's current count. When a configured edge (rising, falling, or both) arrives on the input pin, the hardware instantly copies the counter value into the channel's CCR register and optionally triggers an interrupt or DMA request.

Frequency measurement is the most common input capture application. You configure the channel for rising-edge capture. On the first rising edge, you record CCR as t1. On the next rising edge, you record CCR as t2. The input signal's period is t2 - t1 timer ticks, and the frequency is f_timer / (t2 - t1). For signals slower than the timer's overflow period, you must also count update (overflow) events between captures and add overflow_count * (ARR + 1) to the difference.

Pulse width measurement uses both edges. Capture the counter value on the rising edge (start of pulse) and again on the falling edge (end of pulse). The difference gives the HIGH time in timer ticks.

Practical considerations: Input capture is purely hardware -- it has no software latency, achieving sub-microsecond timestamping accuracy regardless of interrupt response time. The interrupt only needs to read the already-captured CCR value and store it. This makes input capture vastly superior to using external interrupts with software timestamps, where interrupt latency introduces jitter.

⚠️Common Trap: Ignoring Timer Overflow in Capture

If the input signal period exceeds the timer's overflow period, the raw CCR difference wraps around and gives a wrong result. You must track overflow events (via the update interrupt) and account for them when computing the elapsed time between captures.

Output Compare

Output compare is the counterpart to input capture. Instead of reacting to an external signal, the timer watches for the counter to match a programmed CCR value and then triggers a predetermined action: toggling an output pin, generating an interrupt, firing a DMA request, or triggering an ADC conversion.

Common use cases include:

  • Precise delays: Set CCR to the current counter value plus a desired delay in ticks. When the match occurs, the interrupt fires at exactly the right moment -- no software polling, no jitter from instruction timing.
  • Waveform generation: Configure output compare to toggle a pin each time the counter matches CCR, then update CCR in the interrupt to produce arbitrary waveforms with precise timing.
  • ADC triggering: Many MCUs allow a timer output compare event to directly trigger an ADC conversion without CPU involvement, enabling perfectly periodic sampling at exact intervals -- critical for digital signal processing and control loops.
  • Multi-channel scheduling: With four independent compare channels per timer, you can schedule four independent events within a single timer period, each with its own CCR value and action.

Dead-Time Insertion and Complementary PWM

In motor control and power conversion, transistors are arranged in half-bridge or H-bridge configurations where a high-side and low-side switch control current through a load. If both switches in a half-bridge are ever ON simultaneously -- even for nanoseconds -- a direct short-circuit path forms from the power rail to ground. This is called shoot-through, and it can destroy the transistors instantly.

Dead-time insertion prevents shoot-through by enforcing a brief period where both switches are OFF during every transition. The timer hardware automatically delays the turn-on of each complementary output by a configurable number of clock ticks (the dead-time value), ensuring the outgoing switch has fully turned off before the incoming switch begins to conduct.

px-2 py-1 rounded text-sm font-mono border
CH1 ────┐ ┌────────────────────┐ ┌───
│ │ │ │
└──────────────┘ └──────────────┘
CH1N ┌──────────────────┐ ┌──────────────
│ │ │
──────────────┘ └──────────────┘
|dead| CH1N ON |dead| CH1 ON |dead|
| DT | | DT | | DT |

Advanced timers (e.g., TIM1 and TIM8 on STM32) provide complementary output pairs (CH1/CH1N, CH2/CH2N, CH3/CH3N) with hardware dead-time generation through the break and dead-time register (BDTR). The dead-time value is typically set based on the switching characteristics of the power transistors -- too short risks shoot-through, too long reduces effective duty cycle range and increases switching losses.

Center-aligned PWM is strongly preferred for motor control because it naturally reduces harmonic content. In a three-phase inverter, center-aligned mode causes all three phase switching events to be symmetric around the center of the period, which reduces peak current ripple, lowers acoustic noise, and simplifies current sampling (you can sample at the center of the period when all switches are in a known state).

The break input is another critical feature of advanced timers. It is a hardware fault input that immediately forces all PWM outputs to a safe state (typically all LOW or high-impedance) when an overcurrent or fault condition is detected. This happens in hardware with no software latency -- essential for safety-critical motor drives.

Timer Modes Comparison

ModeCounter BehaviorPrimary Use Case
Normal up0 -> ARR -> 0 -> ARR -> ...Basic timing, edge-aligned PWM, general-purpose
DownARR -> 0 -> ARR -> 0 -> ...Countdown timers, watchdog-style timeouts
Center-aligned0 -> ARR -> 0 (up-down)Motor control, reduced harmonic distortion
One-pulseSingle count cycle, then stopsMonostable delays, single-shot events
EncoderUp/down driven by external quadrature signalsRotary encoder position tracking

PWM Applications

ApplicationTypical FrequencyWhy That Frequency
Motor control (DC/BLDC)10-20 kHzAbove the audible range (~20 kHz) to eliminate motor whine
LED dimming1-10 kHzFast enough to appear flicker-free to the human eye
Servo control (RC)50 HzStandard hobby servo specification (1-2 ms pulse within 20 ms period)
Audio generation44.1+ kHzMust exceed Nyquist frequency for the audible band
SMPS (switch-mode power supply)100 kHz - 1 MHzHigher frequency allows smaller inductors and capacitors in the output filter

Debugging Story

A team was developing a BLDC motor controller and noticed an annoying high-pitched whine from the motor during low-speed operation. The motor ran smoothly at higher speeds. Investigation revealed the PWM frequency was set to 8 kHz -- well within the audible range. At higher duty cycles (higher speed), the motor's mechanical inertia filtered out the ripple, but at low duty cycles the acoustic energy was clearly perceptible. The fix was straightforward: increase the PWM frequency to 20 kHz by reducing the ARR value (accepting slightly coarser duty cycle resolution, from 9000 steps down to 3600 steps -- still more than adequate for speed control). The whine disappeared immediately. The lesson: always verify that your PWM frequency is above 20 kHz for motor applications, and understand that changing frequency affects resolution -- you may need to adjust the prescaler to maintain acceptable resolution at the new frequency.

Timing Methods Comparison

MethodResolutionCPU OverheadAccuracyBest For
Software delay loopPoor (varies with optimization, interrupts)100% (blocks CPU)Low (affected by interrupts, cache)Quick prototyping only
Hardware timerSub-microsecond (clock-dependent)Near zero (hardware runs independently)Very high (crystal-referenced)PWM, capture, compare, scheduling
SysTickTypically 1 ms (configurable)Minimal (single interrupt)HighRTOS tick, coarse timeouts, delays
RTOS software timerLimited by tick rate (1-10 ms typical)Low (callback in timer task)Moderate (jitter from scheduling)Application-level timeouts, periodic tasks
⚠️Common Trap: Software Delays for Timing-Critical Tasks

Never use for-loop delays or volatile spin-waits for anything timing-critical in production. They block the CPU, their duration changes with compiler optimization level, and interrupts introduce unpredictable jitter. Use hardware timers instead.

What interviewers want to hear: You understand that timers are autonomous hardware counters clocked from the system clock through a prescaler, and that the prescaler (PSC), auto-reload (ARR), and capture/compare (CCR) registers together determine the PWM frequency, duty cycle, and resolution. You can derive the frequency formula and explain the frequency-vs-resolution trade-off. You know the difference between input capture (timestamping external events) and output compare (scheduling internal actions). You can explain why dead-time insertion is non-negotiable for half-bridge drivers, why center-aligned PWM reduces harmonics in motor control, and how to handle timer overflow when measuring long durations. You default to hardware timers over software delays and understand the role of SysTick and RTOS timers for coarser timing needs.

Interview Focus

Classic Timer/PWM Interview Questions

Q1: "How do you calculate PWM frequency from timer settings?"

Model Answer Starter: "The PWM frequency is determined by the formula f_PWM = f_CLK / ((PSC + 1) * (ARR + 1)), where f_CLK is the timer's input clock, PSC is the prescaler register, and ARR is the auto-reload register. For example, with a 72 MHz clock, PSC = 71 gives a 1 MHz tick rate, and ARR = 999 gives a 1 kHz PWM frequency with 1000 steps of duty cycle resolution. The key trade-off is that a higher ARR gives finer resolution but lowers the frequency, so you choose PSC and ARR together to hit your target frequency while maximizing the number of discrete duty cycle levels. The duty cycle itself is set by the CCR register: duty = CCR / (ARR + 1)."

Q2: "What is the difference between input capture and output compare?"

Model Answer Starter: "Input capture and output compare are opposite operations on the same capture/compare register. Input capture reacts to an external signal: when a configured edge arrives on the input pin, the hardware instantly snapshots the counter value into CCR -- I use this for frequency measurement, pulse width measurement, and encoder interfaces. Output compare reacts to an internal event: when the counter matches CCR, the hardware triggers an action like toggling a pin, firing an interrupt, or starting an ADC conversion -- I use this for precise delays, waveform generation, and periodic ADC sampling. The critical advantage of both is that they're purely hardware operations with no software latency."

Q3: "What is dead-time insertion and why is it critical for motor control?"

Model Answer Starter: "Dead-time insertion adds a brief period where both the high-side and low-side transistors in a half-bridge are OFF during switching transitions. Without it, there's a moment during every transition where both transistors could conduct simultaneously, creating a shoot-through short circuit from the power rail to ground -- this can destroy the transistors in nanoseconds. The dead-time value is set in hardware through the break and dead-time register, and it's typically chosen based on the turn-off time of the power transistors plus a safety margin. Advanced timers provide complementary output pairs with automatic dead-time insertion, plus a break input that can force all outputs to a safe state on a hardware fault."

Q4: "What's the difference between edge-aligned and center-aligned PWM?"

Model Answer Starter: "In edge-aligned PWM, the counter counts up from 0 to ARR and resets -- the output goes HIGH at the start of the period and LOW when the counter hits CCR, producing an asymmetric waveform. In center-aligned PWM, the counter counts up to ARR and then back down to 0, toggling the output on both the up-count and down-count match with CCR, producing a symmetric pulse centered in the period. Center-aligned mode is preferred for motor control for three reasons: it reduces harmonic distortion because the switching edges are symmetric, it naturally aligns switching events across multiple phases in a three-phase inverter, and it provides a clean sampling point at the center of the period for current measurement."

Q5: "How do you handle timer overflow in long-duration measurements?"

Model Answer Starter: "When the signal period exceeds the timer's overflow period, a single CCR capture won't give the correct elapsed time because the counter wraps around. I handle this by enabling the timer's update interrupt to increment a software overflow counter each time the timer rolls over. When I get a capture event, I compute the total elapsed time as (overflow_count * (ARR + 1)) + current_CCR - previous_CCR. The critical subtlety is a race condition: a capture and an overflow can happen nearly simultaneously, so I check whether the overflow flag was set at the time of capture and whether the captured value is near zero or near ARR to determine if the overflow occurred before or after the capture edge. Alternatively, I can use a 32-bit timer to extend the measurement range without software overflow tracking."

Trap Alerts

  • Don't say: "PWM is just toggling a pin in a loop" -- hardware PWM runs independently of the CPU with zero jitter; software toggling is fundamentally different in accuracy and CPU cost
  • Don't forget: The "+1" in the frequency formula -- PSC and ARR are zero-indexed, so the actual divisor is (PSC+1) * (ARR+1), not PSC * ARR
  • Don't ignore: Timer overflow handling in input capture -- if you only subtract two CCR values without tracking overflows, any measurement longer than one timer period will be wrong

Follow-up Questions

  • "How would you generate three-phase PWM for a BLDC motor using a single advanced timer?"
  • "What happens if you change CCR while the timer is running -- does it take effect immediately or at the next update event?"
  • "How would you measure both frequency and duty cycle of an unknown signal using input capture?"
  • "What's the difference between preloaded and non-preloaded CCR/ARR updates, and when does each matter?"

Practice

A timer is clocked at 48 MHz with PSC = 47 and ARR = 999. What is the PWM frequency?

What is the primary advantage of center-aligned PWM over edge-aligned PWM in motor control?

In input capture mode, what does the hardware do when a configured edge arrives?

Why is dead-time insertion critical in H-bridge motor drivers?

What problem occurs if you measure a low-frequency signal with input capture but don't track timer overflows?

Real-World Tie-In

BLDC Motor Controller -- Configured an advanced timer with three complementary PWM channel pairs (CH1/CH1N, CH2/CH2N, CH3/CH3N) for six-step commutation of a brushless DC motor. Used center-aligned PWM at 20 kHz to stay above the audible range, with 200 ns dead-time calculated from the MOSFET gate driver specifications. The break input was wired to an overcurrent comparator for hardware-level fault protection with sub-microsecond response time.

Ultrasonic Range Finder -- Used input capture on two channels to measure the echo pulse from an ultrasonic transducer. Channel 1 captured the rising edge (echo start) and channel 2 captured the falling edge (echo return). The time difference, converted at the speed of sound (343 m/s), gave distance with sub-millimeter repeatability. Timer overflow handling was critical since echo times exceeded 30 ms for objects beyond 5 meters.

Switched-Mode Power Supply -- Generated a 500 kHz PWM signal to drive a buck converter's gate driver. The tight frequency tolerance required careful prescaler selection to minimize rounding error. Duty cycle was updated in a control-loop ISR triggered by the timer's update event, implementing a digital PID controller that adjusted CCR every switching cycle to regulate output voltage within 1% under varying load conditions.