Attiny13 with Push Button & LED - AVR-GCC toolchain (WinAVR)

In the previous Attiny13 tutorial it was shown how to make a LED blink(the hello world program). Here in this Attiny13 tutorial, we will turn on and off a LED connected to the Attiny13 using a push button to demonstrates how it works. The programming language used is AVR-GCC toolchain (WinAVR or avr‑gcc) which is more efficient than Arduino language for Attiny13 like microcontroller which has small flash memory(1KB) for program memory. 

Below is the circuit diagram.

attiny13 push button with LED circuit diagram

As you can see the push button is connected to PB4 and the LED is connected to PB1 pin of Attiny13 microcontroller. We want the LED to turn on and off according to the state of the button. If you unsure about which pin to use, which pin supports digital input/output, which pins supports ADC etc, see the Attiny13 interactive chip explorer.

attiny explorer


Programming

Below is program code to control the LED state using the push button.

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

#define BUTTON PB4   // push button input
#define LED    PB1   // LED output

int main(void) {
    // Configure PB1 as output (LED)
    DDRB |= (1<<LED);

    // Configure PB4 as input with internal pull-up
    DDRB &= ~(1<<BUTTON);
    PORTB |= (1<<BUTTON);   // enable pull-up

    while (1) {
        // Button pressed? (PB4 goes LOW)
        if (!(PINB & (1<<BUTTON))) {
            PORTB |= (1<<LED);   // LED ON
        } else {
            PORTB &= ~(1<<LED);  // LED OFF
        }
    }
}

Let’s break down the simple button + LED code line by line so you see exactly what’s happening:

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

#define BUTTON PB4   // push button input
#define LED    PB1   // LED output
  • These #definegive names to the pins.

  • PB4 is the push button input, PB1 is the LED output.

int main(void) {
    // Configure PB1 as output (LED)
    DDRB |= (1<<LED);
  • DDRB is the Data Direction Register for port B.

  • Setting bit LED (PB1) to 1 makes PB1 an output pin (so it can drive the LED).

    // Configure PB4 as input with internal pull-up
    DDRB &= ~(1<<BUTTON);
    PORTB |= (1<<BUTTON);   // enable pull-up
  • Clearing bit BUTTON(PB4) in DDRB makes PB4 an input pin.

  • Setting the same bit in PORTB enables the internal pull‑up resistor.

  • That means PB4 will read HIGH normally, and when the button is pressed (wired to GND), PB4 will read LOW.

    while (1) {
        // Button pressed? (PB4 goes LOW)
        if (!(PINB & (1<<BUTTON))) {
            PORTB |= (1<<LED);   // LED ON
        } else {
            PORTB &= ~(1<<LED);  // LED OFF
        }
    }
}
  • PINB is the input register for port B.

  • PINB & (1<<BUTTON) checks the state of PB4.

  • !(...) means “if PB4 is LOW” → button pressed.

  • If pressed, set PB1 HIGH → LED ON.

  • If not pressed, clear PB1 → LED OFF.

  • The loop runs forever, constantly checking the button.

⚙️ Behavior

  • Button released → PB4 HIGH → LED OFF.

  • Button pressed → PB4 LOW → LED ON.

Video demonstration is below.

👉 This is the simplest way to verify your wiring: press the button, LED lights up; release, LED turns off. Once you have learned this, it is very easy to extend this logic, like using a buzzer instead of LED or control anything other than just a LED or buzzer.


Post a Comment

Previous Post Next Post