LED Blink: Flash LEDs on Old and New AVRs

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

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.


Here’s a basic C program to blink an LED connected to PB0 of an ATtiny85:

C
#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

Modern AVRs use the VPORT system for GPIO.

C
#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

New AVRxx series microcontrollers use the same VPORT method:

C
#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.

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.