2
\$\begingroup\$

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:

    avr-gcc -mmcu=atmega8 test-001-blinkingled.c -o test-001-blinkingled.o -Os

  2. Hex

    avr-objcopy -j .text -j .data -O ihex test-001-blinkingled.o test-001-blinkingled.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:

avrdude output

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)

My breadboard circuit

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

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

3 Answers 3

9
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ Hi.. Can you point me to a good and easy to understand tutorial on this bitwise addressing of IO-Ports? Thank you very much \$\endgroup\$ Apr 25, 2022 at 9:28
3
\$\begingroup\$
// 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);
\$\endgroup\$
0
\$\begingroup\$
#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) ;
 }
\$\endgroup\$
2
  • 2
    \$\begingroup\$ Note that the question has an answer accepted three years ago. \$\endgroup\$
    – Transistor
    Sep 17, 2016 at 11:35
  • \$\begingroup\$ And nobody covered not using resistors in series for ATMega8, they can drive directly ? \$\endgroup\$
    – mckenzm
    Sep 10, 2020 at 5:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.