Cubicle Hero

Just another pollutant in the Internet wasteland

Blinky on the ATtiny861

Blinky is the most basic program in the embedded world: blink an LED. This article will focus on using either Eclipse IDE or Atmel Studio to program the chip, as well as a few programming concepts specific to microcontrollers (or at least uncommon elsewhere that may be unfamiliar even to programming veterans).

Eclipse IDE vs. Atmel Studio

As with most <this vs. <that>, the answer is "it depends" and it comes down to personal preference. Try them both and decide for yourself. I prefer Eclipse, in general, but it's difficult to setup for this and strictly for programming chips while Atmel Studio contains simulators, debuggers, and more. Depending on your programmer, it may not be possible to use both interchangably, or even at all. Atmel Studio does not support USBtiny programmers and AVR ISP mkII programmers will only work with one IDE at a time due to driver issues (you can use Zadig to switch, libusb for Eclipse and WinUSB for Atmel Studio). Before continuing, get one or both IDEs up and running using the following articles.

C, C++, or Assembly

This, actually, has a definitive answer, at least for now. Assembly is just impractical (though, breaking into small blocks of ASM inside of the other languages may be necessary). C++ can be used but is often scoffed at and is a religious war as heated as they come in this industry. At the moment, it seems that Eclipse's AVR plugin doesn't support C++ out of the box anyway. C is our champion by default due to acceptability, more available examples, community support, and ease of development.

Everything from here on out assumes you have a working knowledge of C, including pointers, macros, structs, and enums. Bitwise math is in abundance.

Embedded Basics

Here are a few aspects of the code specific to embedded programming. They'll make more sense after reading the code.

The Wiring

Connect port A, pin 7, or PA7 on the pinout, to ground using an LED and resistor, in series. The resistor value depends on the LED, but a 1kΩ resistor is probably a reasonable guess and there's a very wide margin for error (a resistor isn't even required, but is highly advised). A resistor too high will decrease the LED brigthness considerably but it should still be visible; a resistor too small (or no resistor) may cause the LED to shine too brightly, heating up and burning out eventually.

Pin => LED => Resistor => Ground rail.

If your chosen pin is different, change the registers accordingly.

The Code

Version 1

#include <avr/io.h>

int main(void) {
    // set PA7 to output
    DDRA |= (1<<7);

    for (;;) {
        // invert PA7
        PORTA ^= (1<<7);

        // wait for some time
        volatile long wait_for = 10000;
        while (--wait_for);
    }

    return 0;
}

Notes

Version 2

#include <avr/io.h>

int main(void) {
    // set PA7 to output
    DDRA |= _BV(7);

    for (;;) {
        // invert PA7
        PORTA ^= _BV(7);

        // wait for some time
        volatile long wait_for = 10000;
        while (--wait_for);
    }

    return 0;
}

Notes

Final Version

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

int main(void) {
    // set PA7 to output
    DDRA |= _BV(7);

    for (;;) {
        // invert PA7
        PORTA ^= _BV(7);

        // sleep for 0.125 seconds
        _delay_ms(125);
    }

    return 0;
}

Notes

In Review

By now, we should have our first AVR chip all wired up and a very basic program written to it, even if pointless or flawed. Next, we'll learn how to configure the chip itself at write-time, modifying how the chip works instead of just pins and peripherals.