Getting started with AVRs

Introduction

If you have no experience with microcontrollers, programming or basic electronics, I recommend that you check out Arduino before starting with AVRs.

Getting started with AVRs is not that expensive or time consuming as you might think, but you should have some basic electronics skills, and some programming experience will make things much easier.

In this guide, I’ll use the following hardware.

-AVR ISP MKII clone (~$20-30 from eBay)

-A simple developement board with an ATMega128 ($25 from ebay)

The ISP (In System Programming) programmer is used to program the chip via USB (or RS232 on older versions)

On the software side, I’ll use AVR Studio 4 with WinAVR under Windows XP. If you’re using linux or mac check out this guides: Mac, Linux/Unix.

The developement board I’m using

The AVR ISP MKII clone

Installing the software under Windows

First we’ll need to download and install the latest version of AVR Studio from Atmel’s website, which is the IDE we’re going to use.

When you’ve done that, download and install WinAVR from sourceforge, which contains the C/C++ compiler and other developement tools.

You might need to install USB drivers for your ISP programmer. Most ISP Programmers comes with a CD containing all the drivers you need.

That’s all software you’ll need!

The DDRx, PORTx and PINx registers

It’s important to understand what these registers is, and how you use them. So don’t skip this step!

The pins on AVRs can be used for diffrent things, some of them I2C,  other PWM and some can be used for Analog input depending on the type of AVR you’re using. But almost all the I/O pins can be used for digital inputs and outputs.

I/O pins on AVRs are grouped in something called ports. Often 8 by 8 pins for each port. Each of these ports have a DDRx, PORTx and a PINx register. The x is the letter of the port the register belongs to.

The DDRx register

DDR stands for Data Direction Register and controls which pins on the ports that should be inputs and which pins that should be outputs.

I made a illustration to make it easier to understand how DDR is used.

1 means output, and 0 means input. In other words, pin 0,4,5 and 7 is inputs and pin 1,2,3 and 6 is outputs.

The PORTx register

The PORTx register controls the output pins. So if you write 11111111 to the PORTx register, it will make all pins which is set as outputs in DDRx go high. But when writing 1 in the PORTx to a pin set as a input in DDRx, it will activate the internal pull-up resistor on that pin.

The PINx register

The PINx register is used to read the current state of inputpins.  So if all pins in the port is set as inputs, and you give give them 5Volts, the PINx register will be 11111111.

These register might be hard to understand, but when you start to code and see how it works in action you’ll get it if you haven’t already.

Most people are using hexadecimal numbers when they’re writing to the registers, but in the beginning it’s okey to use binary numbers. Just remember to use 0b11111111 when using binary numbers in C, and 0xFF when useing hexadecimal numbers.

Writing the code

Finally, the fun part!

  1. Open AVR Studio
  2. You’ll see a dialog pop up, choose “New Project”
  3. Select “AVR GCC” as “Project Type”, since we’re going to write in C, not assembly
  4. Give the project a name like “MyFirstAVRProject” or something
  5. Click “Next”
  6. Select “AVR Simulator 2” under “Debug Platform” and the chip you are using under “Device”. In my case, Atmega128
  7. Click “Finish”

Now, we can write the basic structure of the program.

#include <avr/io.h>

int main(){
    while(1){
        //Main program loop
    }
}

First we are including the io header file, which contains port definitions and more. Then we’re opening

the main function, and creates a infinitive loop where the program should be.
Now we can try to compile it and transfer it to the AVR to make sure everything is working as it should.

Go to “Build > Build” or press F7 to build the project. This will compile the code, and give us a hex-file with machine code the AVR can understand.

No errors? Good, let’s transfer it to the AVR. Go to “Tools > Program AVR > Connect”, select “STK500 or AVRISP” as Platform, “Auto” as port and press “Connect”.

Go to the “Main”-tab and select the chip you’re using and click “Read Signature”. If you got contact with the AVR you’ll se 3 hexadecimal numbers.

Now we can upload the hex-file we compiled. Go to the “Program”-tab.

Click the button marked blue on the image above and select the hex file which you can find in “<ProjectName>\default” and press open.

Note:  Remeber to choose the hex-file for the current project, this is easy to forget, and can drive you crazy.

Now, click “Program”. If everything went as it should, the text box under will show something like this:

Getting isp parameter.. SD=0x01 .. OKOK
Reading FLASH input file.. OK
Setting mode and device parameters.. OK!
Entering programming mode.. OK!
Erasing device.. OK!
Programming FLASH ..      OK!
Reading FLASH ..      OK!
FLASH contents is equal to file.. OK
Leaving programming mode.. OK!

Now we can write a program which does something.

I have 8 LEDs on port C, if you use a other port change the letter of DDRC and PORTC to the port you’re using.


#define F_CPU 16000000    //Clock frequency

#include <avr/io.h>
#include <util/delay.h>       //Header for the _delay_ms() function

int main(){
     DDRC = 0xFF;        //Set all the pins at port C as outputs (11111111 binary)
     PORTC = 0x00;     //Set all the pins at port C low (00000000 binary)
     int count = 0;         //This is the current value

      while(1){
          _delay_ms(500);     //Wait 500ms
          PORTC = count++;  //Set port C to the current value of count and increase count with 1
          if(count>=255)        //If count is greater than or equal 255 (0xFF)
         count = 0;                   //Set count to 0
     }
}

This program will count from 0 to 255 with 500ms delay and display the number binary by using the LEDs.

First we write 0x00 to PORTC which is 00000000 in binary. All LEDs off. Then we wait 500ms, increase with 1 again and again until it reach 255 which is the max value 8 LEDs can show (2^8 -1).

I’ve commented the code, so it should be hard to understand what’s going on. Build the project, and program the AVR as we did in the previous step and it should begin counting from 0 to 255 forever.

Good sites and communities:

AVRFreaks (Good forums, and lots of projects to check out)

SparkFun (Buy electronics)

Atmel Application Notes 8-Bit RISC (Application notes from Atmel)

AVR Fuse Calculator (Good fuse calculator for AVRs)

If you have questions, feel free to post a comment.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s