As I'm a complete novice, I thought I'd start with something really simple: making a led blink. According to several websites, this is something everyone should be able to do... Hmmm... In my case, the LED doesn't do anything. It stays dark. Why?

This is the program I've written (on a Ubuntu 12.04 machine):

#define F_CPU 1000000UL

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

void sleep(int milliseconds)
{
while (milliseconds > 0)
{
_delay_ms(1);
milliseconds--;
}
}

int main()
{
// set lowest bit to output in DDRB register
DDRB |= 0x01;

while(1)
{
// switch led on
PORTB &= 0x01;
sleep(500);

// switch led off
PORTB &= 0x00;
sleep(500);
}

return 0;
}


Then I followed these steps:

1. Compiled my program:

2. Hex

3. Uploaded to the microcontroller (using an AVRISPmkII):

sudo avrdude -p m8 -P usb -c avrispv2 -U flash:w:test-001-blinkingled.hex -F -v

with following result:

This is a picture of my very basic circuit: (I use an old 9V adapter for power, so I used 2 resistors to regulate the voltage to 4.95V)

What am I doing wrong? If you see other strange or stupid things, please educate me!

• Never use resistors to "regulate" the voltage. They don't. Use a proper voltage regulator. This is probably part of your problem. – Gustavo Litovsky Oct 21 '13 at 21:13
• Does it have an internal clock? You need power supply decoupling caps in addition to using a proper regulator. – Andy aka Oct 21 '13 at 22:04
• You are a Magician! Where's the connection between your computer and the ATMEGA8 chip? – user232365 Mar 3 '14 at 19:57

Four problems

1. You are using a resistor voltage divider to power your MCU. Bad. Bad bad. You need a proper regulator. Or a USB (IE 5v) power supply. Heck, use 3 AA batteries instead of a 9v if you don't have a regulator. The ATMega line can take what, 2.5 to 5v normal range? You have nothing that really depends on a full 5v, no clock sensitive/dependent code.

2. You only power one side of the ATMega. There are two power and two ground pins. They are NOT redundant. One set is Digital VCC and GND, the other is Analog VCC and GND. Ideally, you should use an inductor between the DVCC and AVCC pins, for noise sensitive analog circuits, but at the minimum, DVCC and AVCC should be connected, as should DGnd and AGnd.

3. A decoupling cap for both (~0.1uf) is recommended as well, but you could just use one for DVCC/DGnd.

4. You use a Bitwise And (&). Only bits that are already set, will be set. [0 & 1 = 0] [1 & 0 = 0] [0 & 0 = 0] [1 & 1 = 1]
Your code will never toggle the led on. You need a Bitwise OR | (the vertical bar or pipe) to turn it on. A Bitwise And with an inverted bit will turn it off (PortB &= ~0x01). Alternatively, a Bitwise XOR ^ (caret symbol) can be used to toggle.

PORTB |= 0x01;
sleep(500);

PORTB &= ~0x01;
sleep(500);

PORTB ^= 0x01;
sleep(500);


AVR Freaks has a great tutorial on bitwise operations here, for general C but they also focus on AVR/Atmega/Attiny, including port/bit manipulation.

// switch led on
PORTB &= 0x01;
sleep(500);

// switch led off
PORTB &= 0x00;
sleep(500);


Not quite. Since your LED is tied low, you need to set the port bit high to turn it on.

PORTB |= _BV(PB0);


And you need to set it low to turn it off.

PORTB &= ~_BV(PB0);

#define F_CPU 1000000UL

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

void main()
{
DDRB |= 0x01;

while(1)
{
// switch led on
PORTB |= 0x01 ; ///
_delay_ms(500) ;

// led off
PORTB  &= ~0x01;
_delay_ms(500) ;
}

• Note that the question has an answer accepted three years ago. – Transistor Sep 17 '16 at 11:35
• And nobody covered not using resistors in series for ATMega8, they can drive directly ? – mckenzm Sep 10 '20 at 5:46