0
0
Power-electronicsProgramBeginner · 2 min read

Embedded C Program to Fade LED Using PWM

Use a timer to generate PWM signals and vary the duty cycle in a loop to fade the LED, for example: for (int duty=0; duty<=255; duty++) { set_pwm_duty(duty); delay(); }.
📋

Examples

InputStart fading LED from off to full brightness
OutputLED brightness smoothly increases from off to fully bright
InputFade LED brightness up and down continuously
OutputLED brightness smoothly increases then decreases repeatedly
InputSet PWM duty cycle to 0
OutputLED is completely off
🧠

How to Think About It

To fade an LED using PWM, you slowly change the amount of time the LED is on versus off in each cycle. This is done by changing the PWM duty cycle from low to high and back. The human eye sees this as the LED getting brighter or dimmer smoothly.
📐

Algorithm

1
Initialize the PWM hardware and configure the output pin connected to the LED
2
Start a loop to increase the PWM duty cycle from 0 to maximum value gradually
3
Add a small delay after each duty cycle change to make fading visible
4
Then decrease the PWM duty cycle from maximum back to 0 gradually
5
Repeat the loop to create continuous fading effect
💻

Code

embedded_c
#include <avr/io.h>
#include <util/delay.h>

void pwm_init() {
    DDRB |= (1 << PB1); // Set PB1 as output (OC1A pin)
    TCCR1A |= (1 << COM1A1) | (1 << WGM10); // PWM, Phase Correct, 8-bit
    TCCR1B |= (1 << CS11); // Prescaler 8
}

void set_pwm_duty(uint8_t duty) {
    OCR1A = duty; // Set duty cycle
}

int main(void) {
    pwm_init();
    while (1) {
        for (uint8_t duty = 0; duty <= 255; duty++) {
            set_pwm_duty(duty);
            _delay_ms(10);
        }
        for (uint8_t duty = 255; duty > 0; duty--) {
            set_pwm_duty(duty);
            _delay_ms(10);
        }
    }
    return 0;
}
Output
LED connected to PB1 pin fades smoothly from off to full brightness and back repeatedly.
🔍

Dry Run

Let's trace the fading loop increasing duty cycle from 0 to 3 for simplicity.

1

Initialize PWM

PWM hardware set, PB1 pin output enabled

2

Set duty cycle to 0

OCR1A = 0, LED off

3

Increase duty cycle to 1

OCR1A = 1, LED slightly on

4

Increase duty cycle to 2

OCR1A = 2, LED brighter

5

Increase duty cycle to 3

OCR1A = 3, LED brighter still

Duty Cycle (OCR1A)LED Brightness
0Off
1Dim
2Brighter
3Brighter
💡

Why This Works

Step 1: PWM Initialization

We set the timer to PWM mode and configure the output pin so the hardware can generate PWM signals automatically.

Step 2: Duty Cycle Control

Changing the OCR1A register changes the duty cycle, which controls how long the LED stays on in each PWM cycle.

Step 3: Fading Effect

By increasing and decreasing the duty cycle slowly with delays, the LED brightness appears to fade smoothly.

🔄

Alternative Approaches

Software PWM using delay loops
embedded_c
#include <avr/io.h>
#include <util/delay.h>

#define LED_PIN PB0

void software_pwm(uint8_t duty) {
    PORTB |= (1 << LED_PIN);
    _delay_us(duty * 10);
    PORTB &= ~(1 << LED_PIN);
    _delay_us((255 - duty) * 10);
}

int main(void) {
    DDRB |= (1 << LED_PIN);
    while(1) {
        for(uint8_t duty=0; duty<=255; duty++) {
            software_pwm(duty);
        }
        for(uint8_t duty=255; duty>0; duty--) {
            software_pwm(duty);
        }
    }
    return 0;
}
Uses CPU for PWM timing, less efficient and less precise than hardware PWM.
Using DAC with analog output
embedded_c
// Pseudocode: output analog voltage to LED via DAC
// Increase DAC output gradually to fade LED
// Decrease DAC output gradually to dim LED
Requires DAC hardware, provides smooth analog control but more complex hardware.

Complexity: O(n) time, O(1) space

Time Complexity

The program runs a loop increasing and decreasing duty cycle with fixed delay steps, so time grows linearly with the number of steps.

Space Complexity

Uses a few variables and hardware registers, so space usage is constant.

Which Approach is Fastest?

Hardware PWM is fastest and most efficient, software PWM wastes CPU cycles and is less precise.

ApproachTimeSpaceBest For
Hardware PWMO(n)O(1)Smooth, efficient fading
Software PWMO(n)O(1)Simple hardware, less efficient
DAC Analog OutputO(n)O(1)Smooth analog control, complex hardware
💡
Use hardware PWM timers for smooth and efficient LED fading instead of software delays.
⚠️
Beginners often forget to configure the PWM output pin as output, so the LED does not light up.