The Arduino is a great platform for rapid prototyping because it’s so easy to use, well supported, and has a huge online community. However, sometimes you might want to make a smaller, cheaper, and more minimalistic circuit that can be put into permanent projects. Or, maybe you are wondering how the Arduino works. In any case, you’ll just want the brain of the Arduino: the AVR microcontroller. This chip contains the program that runs the Arduino.
Once you have just the AVR, you might be wondering how to program it. Since you no longer have a USB connection, how do you upload code? It turns out that the Arduino can program AVR chips! Let’s get started.
First, you’ll need to make sure you have a couple things:
Great, now that you have everything you need, here’s the video tutorial.
In this video tutorial, I’m going to show you how to program an AVR microcontroller with the Arduino.
This allows you to expriment with individual AVR chips, without the cost or hassle of buying an AVR programmer.
Additionally, by learning how to program an AVR chip, you can understand how an Arduino works while making your own custom embedded system as small and inexpensive as possible.
I’ll show you the process with an ATtiny2313 AVR (datasheet) and the Arduino Duemilanove (info page).
If you’re using a different AVR chip, the pin connections will be slightly different.
Since we’ll need the datasheet for reference, you’ll probably want to download it now.
First, go to atmel.com, click in the search box, and type the name of your AVR.
Then, on the search results page, click the Datasheet link.
For this tutorial, you’ll need:
An Arduino Duemilanove, Uno, or Mega;
An AVR microcontroller;
6 jumper wires and a breadboard;
A 220 ohm resistor;
A 10 microfarad capacitor;
And a LED
The first step is the upload the ArduinoISP sketch to your Arduino to make it a programmer.
It’s located under File >> Examples >> ArduinoISP.
Ensure that the Board and Serial Port configuration is correct (under Tools), and then press Upload.
In step two, we’ll physically connect the AVR to the Arduino.
Find the pinout for your AVR in the datasheet.
Orient the chip correctly by looking for the top semicircular indent.
Most chips also or instead have a small dot in the corner, indicating pin 1.
In Circuit Serial Programming requires 6 connections:
1. First, we need VCC, which is the positive supply or voltage. In this case, it’s on pin 20.
2. GND is the negative supply, or ground, on pin 10.
Then we have 4 data connections:
3. First we find the RESET connection on pin 1.
4. Then, the UCSK (Serial Clock) on pin 19
5. Then, MISO (Master In Serial Out data) on pin 18
6. And finally, MOSI (Master Out Serial In data) on pin 17
Now let’s connect the AVR to the Arduino.
Start with an Arduino, a breadboard, and an AVR chip of your choice.
First, connect VCC (the positive voltage supply) into the 5V pin on the Arduino.
Next, connect the GND pin on the AVR to the GND pin on the Arduino.
Now connect RESET to pin 10, MOSI to pin 11, MISO to pin 12, and SCK to pin 13.
The code in this tutorial will use a LED connected to pin PD6, through a resistor to GND.
One more gotcha: you need to disable the auto-reset of the Arduino by connecting a 10uF capacitor from RESET to GND.
Note that this will most likely need an electrolytic capacitor, which has polarity.
Make sure to connect the longer lead (the plus side) to RESET
and the shorter lead to GND.
Step three is to install the AVR toolchain, which makes it possible to compile and upload programs to the AVR.
On Windows, download and install WinAVR. Make sure that the “Install Files” and “Add Directories to PATH” boxes are checked.
On Mac, you’ll want to install CrossPack tools from Objective Development. Download and open the package installer and click next until the installation completes.
On Linux, follow Ladyada’s UNIX setup guide.
Step four is configuring your Makefile, which sets the settings for the compiler and programmer.
Get the template, and change the settings at the top to reflect your setup.
The DEVICE line should be set to the name of the AVR you’re programming.
CLOCK is the speed (in Hertz) that the AVR is running at. In this case I’m using the internal 8MHz clock, so I wrote 8 million.
The PROGRAMMER line specifies the settings for the programming step. The code shown here is set to auto-detect the Arduino on Mac or Linux systems. On Windows, you’ll have to set it manually to something like COM4. (You can find the COM number of your Arduino in the Arduino program.)
The OBJECTS line specifies what C files should be compiled. For now, main.o is fine.
The FUSES line sets 3 bytes of configuration memory for the AVR (things like clock source, reset and programming disable, etc.) You can easily brick your AVR with these settings, so make sure you get them right. Luckily, there’s an easy way to configure fuses.
You can find the recommended default settings for your particular AVR by using an online fuse calculator.
If your circuit looks like the one in this tutorial, you can go ahead and use the defaults.
Copy and paste the generated fuse bytes to your Makefile’s FUSES line.
In step five, we’ll write the main program for our AVR.
This program will blink the LED I connected to PD6.
You can any I/O pin you wish, but change the Port Name and Pin Number accordingly.
At the top, we’ll have to define the CPU frequency in order to properly calculate delays.
I’m using the internal 8MHz clock, but the default configuration fuses actually divide the clock by 8 internally.
On most AVRs, this is enabled by default.
So, the actual frequency is 1MHz, which I wrote here.
we include the AVR I/O header library to interface with the I/O pins.
After that we include the delay header library.
In the main function, we first make port D pin 6 an output.
This line uses the Port D Direction Register (DDRD) to set our port D inputs/outputs.
Next, we have a vertical bar and equals sign. This is an OR bitmask.
Then, we have the assignment. Here we make pin D6 HIGH, or 1, to mean output.
If you prefer, you can instead use _BV() to make this value a 1.
End the line with a semicolon.
The for(;;) line creates our program’s infinite loop. In it, we toggle the value of pin D6 using an XOR bitmask on the PORTD Data Register.
This makes pin D6 output a HIGH value of about 5 volts.
Then, we delay for a second.
Then next the loop runs, the value of pin D6 will toggle off to zero volts and delay again.
The AVR will continue toggling this pin forever.
Finally, we end the loop and return 0 to tell that the program executed successfully.
Note that all registers on the chip are on the datasheet for reference.
Finally, step six: uploading the code to your AVR.
Open terminal and use the cd command to change directories to the folder with your Makefile and main.c.
Then, simply type “make flash” to compile your main.c into a hex file and upload it with avrdude.
And before you know it, the LED is blinking!
Congratulations! Now that you can upload code to your AVR, try experimenting with different programs.
I have more resources and code on my website: http://holachek.com/avr.
Thanks for listening!
- main.c blink program using timers
Toggle PD6 every second using AVR timers, which are more efficient and don’t halt the program using delays
- Convenient pin macros
Use these Arduino-like pin macros to speed up your coding.
Fuse calculator: http://engbedded.com/fusecalc/
- Embedded C Programming Primer at AVRFreaks
- AVR Digital Output Tutorial by Micah Carrick
- More about AVR fuses by Ladyada
- AVR Timer Tutorial (PDF) by Dean Camera
- AVR and Arduino timer interrupt tutorial by EngBlaze
Video background music track Dopart by blue On blue