In this lesson, you will learn how to manipulate timer compare registers to generate edge-aligned PWM signals that precisely control the perceived brightness of an LED.
The Concept of Edge-Alignment
In edge-aligned PWM, the signal transition always occurs at a fixed reference point, typically when the timer counter resets to zero. Imagine a timer that counts from 0 up to a Period value and then restarts. By using a Compare Register, we can define a "threshold" within that counting cycle.
When the timer count is less than the compare value, we hold the GPIO pin HIGH. Once the counter exceeds that value, the hardware automatically pulls the pin LOW. Because the cycle always starts at zero, the "leading edge" of every pulse is perfectly aligned. By varying the compare register value, we change how long the pin stays high relative to the total period—this is the duty cycle.
Implementation Strategy
To control LED intensity, we treat the GPIO as a high-speed switch. Because the human eye perceives the average light intensity over time (persistence of vision), a high-frequency PWM signal makes the LED appear dimmed rather than flickering.
To implement this, you must:
- Configure the Timer: Set the timer in an "Up-counting" mode.
- Set the Period: Write to the auto-reload register to define the total frequency (the "base" of your PWM).
- Write the Compare Value: Update the compare register to set the "on-time."
// Example: Setting brightness to 50% duty cycle
// If Period is 1000, setting compare to 500 gives 50% intensity
TIM_WriteCompareRegister(500);
// To dim the LED, simply decrease the value
TIM_WriteCompareRegister(100);
By keeping the period constant and only modifying the compare register, you maintain a stable frequency while creating a linear relationship between your register value and the light output. Always ensure your timer frequency is set well above 60Hz to prevent visible flickering, which can cause eye strain or distraction.
Key Takeaway: Edge-aligned PWM achieves variable LED intensity by anchoring the start of every pulse to the timer’s reset event and using a compare register to dynamically truncate the "on" duration within each cycle.