LED blink tutorial for 8-bit AVR microcontrollers: Blinking an LED—also known as a blinky LED or flashing LED light—is often the first program you’ll write when learning how to use microcontrollers.
In addition it may be referred to as the ‘hello world’ program of embedded systems. It’s simple, satisfying, and demonstrates that your hardware and code are working correctly. In this tutorial, you learn how to create an LED blink using classic AVR microcontrollers like the ATtiny85, as well as newer chips like the ATtiny1616 and AVR DB-series using UPDI.
Table of Contents
Why Blink an LED?
A LED blink (or LED flashing light) is the “Hello, World!” of embedded programming. It involves toggling a microcontroller’s output pin at regular intervals to turn an LED on and off.
What You’ll Learn
- How to connect an LED to a microcontroller
- How to write C code to toggle an output pin
- How to program older and newer AVR devices
- Differences between classic and modern AVR pin handling
What You Need
- An AVR microcontroller (ATtiny85, ATtiny1616, etc.)
- A resistor (typically 220Ω to 330Ω)
- An LED
- A breadboard and jumper wires
- An AVR programmer (USBasp, UPDI programmer, or Atmel-ICE)
- Programming software (AVRDude, pymcuprog, or MPLAB X IDE)
Connecting the LED
Connect the LED in series with a current limiting resistor of value between 220 Ohms and 680 Ohms.
Connect the LED as follows:
- Anode (+) → AVR I/O Pin (e.g., PB0)
- Cathode (–) → Resistor → GND
This configuration allows the microcontroller to control the LED by setting the pin high or low.
Example: LED Blink with ATtiny85 (Classic AVR)
Here’s a basic C program to blink an LED connected to PB0 of an ATtiny85:
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void) {
DDRB |= (1 << PB0); // Set PB0 as output
while (1) {
PORTB ^= (1 << PB0); // Toggle PB0
_delay_ms(500); // Delay 500ms
}
}
Programming the ATtiny85
Use AVRDude with a USBasp or Atmel-ICE programmer.
Example AVRDude command:
avrdude -c usbasp -p t85 -U flash:w:blink.hex
Example: LED Blink with ATtiny1616 (Modern UPDI Device)
Modern AVRs use the VPORT system for GPIO.
#define F_CPU 2000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void) {
VPORTA.DIR |= PIN3_bm; // Set PA3 as output
while (1) {
VPORTA.OUTTGL = PIN3_bm; // Toggle PA3
_delay_ms(500);
}
}
Programming with UPDI
Use a USB-to-Serial UPDI programmer with pymcuprog or patched AVRDude.
Example pymcuprog command:
pymcuprog write -d attiny1616 -f blink.hex -t uart
Example: LED Blink with AVR DB-Series (AVR128DB28)
New AVRxx series microcontrollers use the same VPORT method:
#define F_CPU 24000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void) {
VPORTB.DIR |= PIN5_bm; // Set PB5 as output
while (1) {
VPORTB.OUTTGL = PIN5_bm; // Toggle PB5
_delay_ms(250);
}
}
These newer MCUs offer more speed, memory, and peripherals while maintaining simple LED blink capabilities.
Tips for Success
- Double-check the LED orientation (long leg = anode).
- Always include a resistor to limit current.
- Match the pin numbers to your specific chip.
- Use a consistent clock frequency when calculating delays.
LED Blink Conclusion
Creating a flashing LED light using AVR microcontrollers is a foundational skill for embedded developers. Whether you’re using an old ATtiny85, a compact ATtiny45, or a modern AVR128DB28, the concept is the same: control a digital output to toggle an LED. With tools like AVRDude, pymcuprog, and MPLAB X IDE, you can easily flash your first program and bring your embedded projects to life.