Creating Simple AVR Program: “Running” LEDs

Home / Creating Simple AVR Program: “Running” LEDs

Creating Simple AVR Program: “Running” LEDs

December 3, 2015 | Article | No Comments

In the previous article we have discussed about AVR microcontroller programming in Linux environment and Windows environment. The term program in this case is downloading / store a binary program to your microcontroller using usb programmer and avrdude. If you haven’t read the article I recommended you to read it. It’s not a long article so it would be fine to skim it.

Now, in this article we will discussed about writing a simple program for our AVR microcontroller. What we will need:

  1. Host Operating System, (you can use GNU/Linux or Microsoft Windows Operating System)
  2. AVR microcontroller, embedded as board. In this case I use atmega32
  3. avrdude, this tool is for writing our program to microcontroller
  4. avr-gcc, this tool is for compiling the code
  5. A USB programmer

Now, let’s configure the chip. I have assembly my AVR as follows:

  1. ATMega32 chip
  2. External clock with 16MHz frequency
  3. Eight active low LEDs connected to PORT A
  4. A port for ISP programming connected to PORT B

Well, actually there are more in my board but for this article we will just need those informations.

Please note that I use PORT A for LEDs. You may use other port but you must adjust your configuration with this article. The one I used are active-low LEDs which can only emitted light if we give low voltage. Also note that I use PORT B for ISP programmer and this is the only one PORT to program AVR microcontroller.

I assume we all have prepared the tools. See article for preparing tools in Windows and Linux.

Writing the Codes

When writing the codes, you can use any text editor. For simplicity, we use notepad in Windows and Geany in Linux (remember, any text editor will do).

What I want is some turn on and off some LEDs in a pattern. For every second, I will switch the condition for every LEDs and shift the series to the left. This will give impression like the LEDs are running :3

OK, let’s get to actual code. Write this codes and save it as avr-leds.c

#define F_CPU 16000000UL

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

/* our entry point */

int main() {
   /* we used PORT A for LEDs so we will give a little setup */
   DDRA 	= 0xFF;
   PORTA	= 0b11000101;
   /* used for shifting */

   int tmp;

   /* our main loop. The execution goes here */
   while(1) {
      /* setting the running speed. It's a simple delay in 800 miliseconds */

      /* get the least significant bit, in this case is the most right position
         on binary number but it is the most left position on leds */
      tmp = PORTA & 1;

      /* shift the number to the right */
      PORTA >>= 1;

      /* grab the saved bit and shift it to the most right position */
      PORTA |= tmp << 7;
   return 0;

It’s short and simple code. We only write what we need, not completely set other parts.

In this code, we only use port A as output. To do so, we set all the 8 bits to 1 (which has value of 0xFF or 255 in decimal). Port A is then connected to 8 LEDs and I give initial pattern of 0b11000101. Remember that I use active low LEDs, so it will turn on when we give low logic.

To access individual bit of a byte, we use bitwise operation.

The statement:

tmp = PORTA & 1

will give me the least significant byte of PORTA and store it to tmp variable.

Then the statement:

PORTA |= tmp << 7;

will write the most significant bit by the value of tmp variable.

Here you see some


OK, next we will compile the code. To do so open your terminal and invoke this command:

avr-gcc -g -Os -mmcu=atmega32 -c avr-leds.c

That command tell the compiler to compile a single file avr-leds.c but do not link it yet. It’s useful if you have bigger project you can compile each source code separately.

What you need to know is -mmcu switch. It tells compiler what chip we are using now. In this case we are using ATMega32.

The previous command will compile the file into an object file with filename avr-leds.o.

Now, invoke this command:

avr-gcc -g -mmcu=atmega32 -o avr-leds.elf avr-leds.o

This will produce a binary file called avr-leds.elf, which is a GNU executable file. The file format is ELF (Executable and Linkable Format) which is similiar to linux program. However, this is not what we need. We need hex file for AVR.

Now invoke this command:

avr-objcopy -j .text -j .data -O ihex avr-leds.elf avr-leds.hex

This will produce the file we want, an intel hex file. Let me explain what switches we gives

When we write -j switch we tells the avr-objcopy to only copy from that section. In this case we only copy data from section .text and .data. If you have program in assembly before, then you might know what is section.

A -O switch tells the avr-objcopy to produce file with following format. And in our case it is intel hex format (ihex).

The next arguments are the .elf file and .hex file respectively. It means that our input would be avr-leds.elf and will be processed to avr-leds.hex.

Burn the Program to the Device

We use avrdude to do so. Make sure you have connected the device with the downloader and connect it to PC. The downloader I use is USBasp.

avrdude -c usbasp -U flash:w:avr-leds.hex -p atmega32

And we are done!

, ,

About Author

about author


A man who is obsessed to low level technology.

Leave a Reply

Your email address will not be published. Required fields are marked *

Social Share Buttons and Icons powered by Ultimatelysocial