Embedded C Program to Blink LED with Delay
PORTB |= (1 << PB0); delay(); PORTB &= ~(1 << PB0); delay(); to blink an LED.Examples
How to Think About It
Algorithm
Code
#include <avr/io.h> #include <util/delay.h> int main(void) { DDRB |= (1 << PB0); // Set PORTB0 as output while(1) { PORTB |= (1 << PB0); // LED ON _delay_ms(500); // Delay 500 ms PORTB &= ~(1 << PB0); // LED OFF _delay_ms(500); // Delay 500 ms } return 0; }
Dry Run
Let's trace blinking LED connected to PORTB0 with 500ms delay through the code
Set PORTB0 as output
DDRB = 0x01 (binary 00000001), so pin PB0 is output
Turn LED ON
PORTB |= 0x01 sets PB0 high, LED lights up
Delay 500ms
Program waits for 500 milliseconds
Turn LED OFF
PORTB &= ~0x01 clears PB0, LED turns off
Delay 500ms
Program waits for 500 milliseconds
Repeat
Loop back to step 2 to continue blinking
| Step | PORTB | LED State |
|---|---|---|
| 1 | 00000001 | Configured as output |
| 2 | 00000001 | ON |
| 3 | 00000001 | ON (delay) |
| 4 | 00000000 | OFF |
| 5 | 00000000 | OFF (delay) |
Why This Works
Step 1: Configure pin as output
Setting the data direction register bit for the LED pin to 1 makes it an output so we can control voltage.
Step 2: Turn LED ON and OFF
Setting the pin high with PORTB |= (1 << PB0) supplies voltage to LED, turning it ON; clearing it turns LED OFF.
Step 3: Use delay for visible blinking
The _delay_ms() function pauses the program so the LED stays ON or OFF long enough to see the blink.
Alternative Approaches
#include <avr/io.h> #include <avr/interrupt.h> volatile int led_state = 0; ISR(TIMER0_COMPA_vect) { if (led_state) { PORTB &= ~(1 << PB0); led_state = 0; } else { PORTB |= (1 << PB0); led_state = 1; } } int main(void) { DDRB |= (1 << PB0); TCCR0A = (1 << WGM01); OCR0A = 195; TIMSK0 = (1 << OCIE0A); TCCR0B = (1 << CS02) | (1 << CS00); sei(); while(1) {} }
#include <avr/io.h> void delay(void) { volatile unsigned int i; for(i=0; i<30000; i++) {} } int main(void) { DDRB |= (1 << PB0); while(1) { PORTB |= (1 << PB0); delay(); PORTB &= ~(1 << PB0); delay(); } }
Complexity: O(1) time, O(1) space
Time Complexity
The blinking loop runs indefinitely with fixed delay; no loops depend on input size, so time complexity is constant O(1).
Space Complexity
Uses fixed registers and variables; no extra memory allocation, so space complexity is O(1).
Which Approach is Fastest?
Using hardware timer interrupts is more efficient as it frees CPU during delay, while software loops block CPU.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Simple delay loop | O(1) | O(1) | Easy to implement, less accurate |
| _delay_ms() function | O(1) | O(1) | Accurate delay, simple code |
| Timer interrupts | O(1) | O(1) | Efficient multitasking, precise timing |