Intuition The big picture
A microcontroller timer is just a counter register that increments every clock tick. By itself that's boring — but the magic is in the compare and capture hardware bolted onto it:
Output Compare / PWM → the timer's counter is the cause ; it drives a pin HIGH/LOW automatically at the moment the count reaches a target. (Time → Pin )
Input Capture → an external pin event is the cause ; the hardware snapshots the counter value the instant the edge arrives. (Pin → Time )
WHY this matters: doing these in software (while loops + delay()) wastes the CPU and is jittery. The timer peripheral does it in hardware , so timing is exact and the CPU is free.
A free-running up-counter CNT driven by a clock of frequency f t i m f_{tim} f t im . It counts 0 , 1 , 2 , … 0,1,2,\dots 0 , 1 , 2 , … and wraps (overflows) back to 0 when it reaches its top value ARR (Auto-Reload Register).
WHY a prescaler? The peripheral clock (say 72 MHz) is often too fast. A prescaler divides it so each tick lasts a usable amount of time.
is
A square wave where the fraction of time spent HIGH (the duty cycle ) encodes a value. An LED at 25% duty looks dim; a motor at 25% duty turns slowly. The frequency stays fixed; only the HIGH/LOW split changes.
HOW the hardware makes it: every tick it compares CNT to the Capture/Compare Register CCR:
While CNT < CCR → pin is HIGH
When CNT ≥ CCR → pin is LOW
At wrap (CNT = ARR+1 → 0) → pin goes HIGH again.
So CCR sets how long HIGH lasts, ARR sets the whole period .
Worked example Make a 1 kHz PWM at 50% on a 72 MHz MCU
Goal: f P W M = 1000 f_{PWM}=1000 f P W M = 1000 Hz, D = 50 % D=50\% D = 50% .
Choose PSC so ticks are convenient. Let PSC=71 ⇒ f t i m = 72 MHz / 72 = 1 MHz f_{tim}=72\text{MHz}/72 = 1\text{MHz} f t im = 72 MHz /72 = 1 MHz .
Why this step? Gives 1 µs ticks — easy mental math.
Need period T = 1 T=1 T = 1 ms = 1000 =1000 = 1000 ticks ⇒ A R R + 1 = 1000 ARR+1=1000 A R R + 1 = 1000 ⇒ ARR=999.
Why? From f P W M = f t i m / ( A R R + 1 ) f_{PWM}=f_{tim}/(ARR+1) f P W M = f t im / ( A R R + 1 ) ⇒ A R R + 1 = 10 6 / 10 3 = 1000 ARR+1 = 10^6/10^3 = 1000 A R R + 1 = 1 0 6 /1 0 3 = 1000 .
D = 50 % D=50\% D = 50% ⇒ C C R = 0.5 × ( A R R + 1 ) = 500 CCR = 0.5\times(ARR+1)=500 C C R = 0.5 × ( A R R + 1 ) = 500 .
Why? From D = C C R / ( A R R + 1 ) D=CCR/(ARR+1) D = C C R / ( A R R + 1 ) .
Worked example Servo control — 50 Hz, 1.5 ms pulse (center)
PSC=71 ⇒ 1 µs ticks (reuse the trick).
T = 20 T=20 T = 20 ms = 20000 =20000 = 20000 ticks ⇒ ARR=19999.
Pulse = 1.5 ms = 1500 ticks ⇒ CCR=1500. Why? Servo reads pulse width , not duty %, so we set CCR directly to the desired µs.
Definition Output Compare
When CNT == CCR, the hardware does an action on a pin (set / clear / toggle) and/or fires an interrupt. PWM is the "PWM mode" of this; "toggle mode" gives a square wave at half the compare rate.
Worked example Generate a precise 500 kHz square wave (toggle mode)
Toggle flips the pin each match, so one full wave = two matches.
Want f o u t = 500 f_{out}=500 f o u t = 500 kHz on a 72 MHz clock, PSC=0 ⇒ f t i m = 72 f_{tim}=72 f t im = 72 MHz.
Match must occur every f t i m / ( 2 f o u t ) = 72 M / 1 M = 72 f_{tim}/(2f_{out}) = 72\text{M}/1\text{M}=72 f t im / ( 2 f o u t ) = 72 M /1 M = 72 ticks ⇒ ARR=71, toggle on overflow.
Why /2? Because two toggles make one period.
Intuition Reverse direction
Now the pin drives the timer's memory . On a chosen edge (rising/falling), hardware copies CNT into CCR instantly — no software latency. Subtract two captures to measure a pulse width or period with tick-level precision.
Worked example Measure an unknown frequency
f t i m = 1 f_{tim}=1 f t im = 1 MHz (1 µs ticks), ARR=65535. Rising edge captures: c 1 = 200 c_1=200 c 1 = 200 , c 2 = 1200 c_2=1200 c 2 = 1200 (no wrap).
Δ = 1000 \Delta = 1000 Δ = 1000 ticks = 1000 μ s = 1 = 1000\,\mu s = 1 = 1000 μ s = 1 ms ⇒ f s i g n a l = 1 / 1 ms = 1 f_{signal}=1/1\text{ms}=1 f s i g na l = 1/1 ms = 1 kHz.
Why µs? Each tick is 1 µs, so Δ \Delta Δ ticks = Δ \Delta Δ µs directly.
Worked example Capture across an overflow
c 1 = 65000 c_1=65000 c 1 = 65000 , c 2 = 500 c_2=500 c 2 = 500 , ARR=65535. Naive c 2 − c 1 = − 64500 c_2-c_1=-64500 c 2 − c 1 = − 64500 (wrong, negative!).
Correct: ( 500 − 65000 ) m o d 65536 = 65536 − 64500 = 1036 (500-65000)\bmod 65536 = 65536-64500 = 1036 ( 500 − 65000 ) mod 65536 = 65536 − 64500 = 1036 ticks. Why? The counter wrapped once; mod restores real elapsed time.
Common mistake "Period uses ARR, not ARR+1."
Why it feels right: ARR is literally called the "top value", so it seems like the count length.
Fix: counting includes 0 0 0 , so there are A R R + 1 ARR+1 A R R + 1 distinct ticks per cycle. Forgetting + 1 +1 + 1 makes your PWM frequency slightly high — visible on a scope.
Common mistake "Prescaler divides by PSC."
Why it feels right: "prescaler = 72 → divide by 72" is intuitive.
Fix: the register divides by ( P S C + 1 ) (PSC+1) ( P S C + 1 ) so that PSC=0 means divide-by-1. To divide by 72 you write PSC=71.
Common mistake "Input capture overflow can be ignored."
Why it feels right: subtraction "just works" for short pulses.
Fix: if the counter wrapped, raw subtraction goes negative. Always take ( c 2 − c 1 ) m o d ( A R R + 1 ) (c_2-c_1)\bmod(ARR+1) ( c 2 − c 1 ) mod ( A R R + 1 ) or count overflow interrupts.
Common mistake "PWM duty is CCR/ARR."
Why it feels right: ARR is the top, CCR is the threshold — looks like a ratio.
Fix: it's C C R / ( A R R + 1 ) CCR/(ARR+1) C C R / ( A R R + 1 ) . At C C R = A R R + 1 CCR=ARR+1 C C R = A R R + 1 you get true 100%.
Why is the timer period ( P S C + 1 ) ( A R R + 1 ) / f c l k (PSC+1)(ARR+1)/f_{clk} ( P S C + 1 ) ( A R R + 1 ) / f c l k and not P S C ⋅ A R R / f c l k PSC\cdot ARR/f_{clk} P S C ⋅ A R R / f c l k ?
Output compare vs input capture: which direction does data flow (pin↔timer)?
In toggle mode, why divide by 2 to get output frequency?
Recall Feynman: explain to a 12-year-old
Imagine a clock hand sweeping a circle over and over. PWM : you tell a light "stay on while the hand is in the first quarter, off the rest" — sweep fast and the light just looks half-bright; move the "off line" to dim it. Input capture : a friend taps the table, and you write down exactly where the clock hand was at that instant. Tap twice, look at the two hand positions, and you know how long the gap was — without ever staring at a stopwatch yourself. The clock (timer) does the watching; you just read the notes.
Mnemonic Remember the +1's and the direction
"PA-1, AR-1: Pat the dog, Add a Run."
P SC needs +1 , AR R needs +1 .
C ompare = C ontrol the pin (Time→Pin). C apture = C opy the time (Pin→Time). Same first letter, opposite arrow.
GPIO and Alternate Functions — PWM/compare pins need AF mode enabled.
Interrupts and NVIC — capture/compare events fire ISRs; overflow tracking.
Clock Tree and Prescalers — where f c l k f_{clk} f c l k comes from.
Motor Control and H-Bridges — PWM drives speed; dead-time inserts gaps.
Servo and ESC Control — pulse-width interpretation of PWM.
Encoder Mode — timer counting quadrature; a cousin of input capture.
Timer period formula in terms of PSC, ARR, f_clk T = ( P S C + 1 ) ( A R R + 1 ) f c l k T=\frac{(PSC+1)(ARR+1)}{f_{clk}} T = f c l k ( P S C + 1 ) ( A R R + 1 ) Why the +1 on PSC? So that PSC=0 divides the clock by 1, not 0 (divider is PSC+1).
Why the +1 on ARR? The counter includes count 0, giving ARR+1 ticks per cycle.
PWM duty cycle formula D = C C R A R R + 1 × 100 % D=\dfrac{CCR}{ARR+1}\times100\% D = A R R + 1 C C R × 100% .
What sets PWM period vs duty? ARR sets the period; CCR sets the HIGH duration (duty).
Output compare data direction Timer → Pin (CNT reaches CCR, hardware acts on pin).
Input capture data direction Pin → Timer (edge event copies CNT into CCR).
Period from two captures (with overflow) T = ( c 2 − c 1 ) m o d ( A R R + 1 ) f t i m T=\dfrac{(c_2-c_1)\bmod(ARR+1)}{f_{tim}} T = f t im ( c 2 − c 1 ) mod ( A R R + 1 ) .
Toggle-mode output frequency vs match rate Output freq = match-rate / 2 (two toggles per period).
Settings for 1 kHz 50% PWM at 72 MHz PSC=71 (1 MHz), ARR=999, CCR=500.
Servo 1.5 ms center pulse at 50 Hz, 1 µs ticks ARR=19999, CCR=1500.
Fix for negative capture difference Take (c2−c1) modulo (ARR+1) to account for counter wrap.
Intuition Hinglish mein samjho
Dekho, timer basically ek counter hai jo har clock tick pe ek-ek karke badhta rehta hai, aur top value (ARR) pe pahunch ke wapas 0 ho jaata hai. Prescaler (PSC) clock ko slow karta hai — yaad rakho divider hamesha (PSC+1) hota hai, isliye 72 se divide karna ho to PSC=71 likhte ho. Pura period nikalta hai T = ( P S C + 1 ) ( A R R + 1 ) / f c l k T=(PSC+1)(ARR+1)/f_{clk} T = ( P S C + 1 ) ( A R R + 1 ) / f c l k , aur dono jagah +1 isliye hai kyunki counting 0 se shuru hoti hai.
PWM ka funda simple hai: hardware har tick pe CNT ko CCR se compare karta hai. Jab tak CNT < CCR, pin HIGH; uske baad LOW. To CCR decide karta hai kitni der HIGH rahega (duty), aur ARR pura period. Duty = CCR/(ARR+1). LED dim karni ho ya motor speed control karni ho — sab isi se. CPU ko kuch karne ki zaroorat nahi, hardware khud handle karta hai, isliye timing ekdum exact aur jitter-free.
Output compare matlab Time se Pin — counter target tak pahuncha, pin par action ho gaya. Iska ulta hai Input capture : yahan Pin se Time — external signal ka edge aata hai aur hardware turant CNT ka value CCR me copy kar deta hai. Do captures ka difference le lo, mil gaya pulse ka width ya frequency, bina kisi software delay ke. Bas ek dhyan rakhna: agar beech me counter overflow ho gaya to seedha subtract mat karo — ( c 2 − c 1 ) m o d ( A R R + 1 ) (c_2-c_1)\bmod(ARR+1) ( c 2 − c 1 ) mod ( A R R + 1 ) use karo, warna answer negative aa jaayega.
Short me: Compare = pin control karta hai, Capture = time copy karta hai. Ye PWM, servo, motor, frequency-measurement — embedded ki har real-time cheez ka dil hai.