Pulse Width Modulation (PWM) lets you control analog devices using digital signals. By varying the duty cycle of a square wave, PWM simulates analog voltages, giving you precise control over things like LED brightness and motor speed.
Microcontrollers generate PWM using their built-in timer modules. Configuring timer parameters like frequency, resolution, and compare values lets you tailor PWM signals to specific applications.
PWM Fundamentals
Basic Principles and Parameters
PWM works by rapidly switching a digital output between high and low. The trick is that by controlling how long the signal stays high versus low in each cycle, you effectively control the average voltage delivered to a load.
Three parameters define a PWM signal:
- Duty cycle is the proportion of time the signal is high compared to the total period. It's expressed as a percentage: 0% means always off, 100% means always on. A 50% duty cycle delivers half the maximum voltage to the load.
- Frequency is the number of complete PWM cycles per second, measured in Hertz (Hz). Higher frequencies produce smoother output with less ripple, but the switching speed of your hardware sets an upper limit.
- Resolution is the number of discrete duty cycle steps available within one PWM period. This is determined by the bit depth of the PWM timer. An 8-bit timer gives you distinct duty cycle values, while a 16-bit timer gives . Higher resolution means finer control over the output.
Generating PWM Signals
PWM signals are generated using a microcontroller's timer/counter module set to PWM mode. Here's how the process works:
- The timer counts upward from zero at a rate set by the timer clock.
- You define a maximum count value (the period), which determines the PWM frequency and resolution.
- You set a compare value that controls the duty cycle. While the timer count is below the compare value, the output pin is driven high. Once the count exceeds the compare value, the output goes low.
- When the timer reaches the period value, it resets to zero and the cycle repeats.
The resulting signal is output through a dedicated PWM pin or a general-purpose I/O pin configured as an output.

PWM Configuration
Timer Configuration for PWM
Setting up PWM requires configuring several timer parameters in sequence:
- Select the clock source. This is usually the system clock, though an external clock input can also be used.
- Set the prescaler. The prescaler divides the clock source frequency down to the timer clock frequency: For example, a 16 MHz system clock with a prescaler of 64 gives .
- Set the timer period. This determines both resolution and PWM frequency. For an -bit timer, the period is typically set to (255 for 8-bit, 65535 for 16-bit). The PWM frequency is then: Continuing the example above with an 8-bit timer: .
- Set the compare value. This controls the duty cycle and ranges from 0 to the period value. The duty cycle is: A compare value of 128 on an 8-bit timer gives a duty cycle of .

Dead Time Insertion
In applications like motor control, complementary PWM signals drive a high-side and a low-side switch. If both switches turn on at the same time, even briefly, you get a shoot-through current that can damage the hardware.
Dead time is a short delay inserted between turning one switch off and the other on, ensuring they're never conducting simultaneously. Most microcontrollers with advanced PWM peripherals include dedicated hardware for dead time insertion, configured as part of the timer settings. The dead time duration is typically specified in timer clock cycles.
If hardware support isn't available, dead time can be implemented in software by adding a deliberate delay between switching the complementary outputs. Hardware dead time is preferred because it's more reliable and doesn't depend on software timing.
PWM Applications
LED Dimming
PWM is the standard way to control LED brightness in embedded systems. The human eye perceives average light intensity, so rapidly switching an LED on and off at varying duty cycles creates the appearance of different brightness levels:
- A 25% duty cycle produces a dim LED
- A 75% duty cycle produces a noticeably brighter LED
- 100% is full brightness
This approach gives you smooth, precise brightness control without analog circuitry or variable resistors. The one thing to watch is the PWM frequency: it should be above the flicker fusion threshold (typically above 100 Hz, though 200+ Hz is safer) so the human eye doesn't perceive any flickering.
Motor Control
PWM is widely used to control DC motors and brushless DC (BLDC) motors. Varying the duty cycle changes the average voltage supplied to the motor, which directly controls its speed. A higher duty cycle means higher average voltage and faster rotation; a lower duty cycle slows the motor down.
This is far more efficient than using a variable resistor to limit current, since the switching transistor is either fully on or fully off, minimizing power wasted as heat.
For BLDC motors, PWM works together with electronic commutation to control current through the motor windings. The PWM signals drive the high-side and low-side switches of a three-phase inverter bridge. Dead time insertion is critical here to prevent shoot-through currents across the bridge legs and ensure safe, efficient operation.