atmega linux tutorial

First of all you need to install (via apt-get, yum or source):
geany (simple IDE, of course you can use nano, vim…)

Write this simple C code and name it a.c (turning on all led on PORTD)

#include <avr/io.h>

int main(void)
  // Set Port D pins as all outputs
  DDRD = 0xff;

  // Set all Port D pins as HIGH
  PORTD = 0xff;

  return 1;
} can be useful if you know nothing about hex

Compile it for your atmega (mine is ATMEGA32-16PU)

avr-gcc -mmcu=atmega32 -Os a.c

Next you need to convert this program to HEX

avr-objcopy -j .text -j .data -O ihex a.out a.hex

Now it's time to burn it to your microcontroller. I am using AVR ISP mkII (USB).

Show a list of supported microcontroller (for the -p argument)

avrdude -p list -P usb -c avrispmkII

First you need to set the SCK The default clock of an atmega is usually shipped with internal RC oscillator at 8.0MHz and with the fuse CKDIV8 programmed, resulting in 1.0MHz system clock.

avrdude -p m32 -P usb -c avrispmkII -tuF

avrdude: Expected signature for ATMEGA32 is 1E 95 02
avrdude> sck 10
avrdude> quit

Programming the hex file into an ATMEGA32:

avrdude -p m32 -P usb -c avrispmkII -Uflash:w:a.hex

Setting the fuse for the ATMEGA32:
find what you need here:

avrdude -p m32 -P usb -c avrispmkII -U hfuse:w:0xE4:m -U lfuse:w:0x99:m

Having problems? Want to restart from scratch:

avrdude -p m32 -P usb -c avrispmkII -tuF
avrdude> sck 1000
avrdude> e
avrdude> sck 10

avrdude: erasing chip

Check the state of the chip and other informations

avrdude -p m32 -c avrispmkII -P usb -v

Understanding the fuses is important. For example, if you programmed to use the Ext. Clock, then you will need an external clock… Basically, 3 clocks : internal, ext. clock, crystal / rc clock. If you want an Ext. Clock simply use another AVR lie attiny13 with this code :

#include <avr/io.h>

int main(void)
  DDRB = 0xff;
    while (1) {
        PORTB = ~PINB;
  return 1;

Use the internal clock around 4 Mhz. then plug a pin from portb (attiny13) to xtal1 (atmage8 for example).

Easier life

#define bit_get(p,m) ((p) & (m))
#define bit_set(p,m) ((p) |= (m))
#define bit_clear(p,m) ((p) &= ~(m))
#define bit_flip(p,m) ((p) ^= (m))
#define bit_write(c,p,m) (c ? bit_set(p,m) : bit_clear(p,m))
#define BIT(x) (0x01 << (x))
#define LONGBIT(x) ((unsigned long)0x00000001 << (x))

//To set a bit://
bit_set(foo, 0x01);

//To set bit number 5://
bit_set(foo, BIT(5));

//To clear bit number 6 with a bit mask://
bit_clear(foo, 0x40);

//To flip bit number 0://
bit_flip(foo, BIT(0));

//To check bit number 3://
if(bit_get(foo, BIT(3))) { }

//To set or clear a bit based on bit number 4://
if(bit_get(foo, BIT(4))) {
    bit_set(bar, BIT(0));
} else {
    bit_clear(bar, BIT(0));

//To do it with a macro://
bit_write(bit_get(foo, BIT(4)), bar, BIT(0));

DDRD&=~_BV(0); //set PORTD pin0 to zero as input
PORTD|=_BV(0); //Enable pull up
PORTD|=_BV(1); //led OFF
DDRD|=_BV(1); //set PORTD pin1 to one as output

while(1) {
   if (bit_is_clear(PIND, 0))//if button is pressed {

            PORTD&=~_BV(1);//led ON
            loop_until_bit_is_set(PIND, 0);//LED ON while Button is pressed
            PORTD|=_BV(1);//led OFF

Useful links and tools

Convert from binary to hex with google:

Various documentation
Understanding ADC:

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License