How do you control the duty cycle of a PWM signal?
The duty cycle is set by the Capture/Compare Register (CCR) relative to the ARR value. In edge-aligned PWM mode 1 (the most common configuration), the output is active (high) while the counter value is less than CCR, and inactive (low) from CCR to ARR. The formula is:
Duty cycle = CCR / (ARR + 1) * 100%
For example, with ARR = 999 and CCR = 250, the duty cycle is 250/1000 = 25%. Setting CCR = 0 gives 0% duty (always low), and setting CCR to a value equal to or greater than ARR + 1 gives 100% duty (always high). The critical insight is that ARR controls the frequency and CCR controls the duty cycle independently — you can change duty cycle on the fly by writing to CCR without affecting frequency. In PWM mode 2, the polarity is inverted: the output is inactive while the counter is less than CCR and active above it.
To prevent glitches when updating CCR mid-cycle, enable the preload feature (OCxPE bit in the CCMRx register). With preload enabled, writes to CCR go into a shadow register, and the actual CCR is updated atomically at the next counter overflow (update event). Without preload, writing a new CCR value while the counter is between the old and new CCR values can produce a partial-width or extra-width pulse for that one period. The ARPE bit provides the same protection for the ARR register. Always enable both preloads in any application where glitch-free updates matter (motor control, LED dimming, power converters).
Source: Timers & PWM Q&A
