I'm assuming you've got your 5V supply tested and working. Next, we
need to insert the ATmega168 into the breadboard and connect up power
ATmega8 (works the same with ATmega168) straddling the middle row of the breadboard
You will need to slightly bend in the legs of the DIP
(dual inline package) to get the ATmega168 to straddle the breadboard
center. Be careful! Do not bend the pins too far inward. The pins of
the ATmega168 should insert into the inner two most rows on the
breadboard. I find it best to to insert one side and then slightly push
the IC sideways until the other side of pins can insert into the
opposite row on the breadboard. Confusing, I know.
Note: The 5V 'rail' is the horizontal row of holes next to
the red line. You should have a wire connecting your 5V power regulator
circuit to one hole on the 5V rail. This will energize all the holes
next to the red line with 5V. This is true about the blue line as well.
All the horizontal holes next to the blue line are connected together.
One of these holes should be connected to the ground pin on your
voltage regulator, and to the ground connection of your wall wart. You
can connect the VCC pins on the ATmega168 to any holes along the 5V
rail, and you connect the GND pins on the ATmega168 to any hole along
the blue GND rail.
Oh, hey! If no one ever told you, there is a really simple way to
figure out where pin 1 is on an IC. The manufacturer of anything
polarized (tantalum caps, electrolytic caps, LEDs, ICs, etc) will
always put some sort of marking on the device to indicate the how the
device is supposed to be oriented. For ICs, there is a small dimple on
one end of the IC. The blue arrow in the picture is pointing to this
dimple. The orange arrow points at pin 1, and the blue labels show how
the pin numbers increase.
Counting from the dimple, pin 1 is on the left and
increases down the left side of the IC. The pin numbers jump to the
right side row of pins and count up. See image from the ATmega168
The ATmega168 should be in the breadboard, pin 7 (VCC) and pin 20
(AVCC) should be connected to your 5V rail and pins 8 and 22 (GND)
should be connected to GND on your bread board. If you turn your power
circuit on, the ATmega168 is now running, but it has nothing to run!
Actually this is not wholly true - there is one more connection that
needs to be made before the ATmega168 starts running code. The RESET
pin on the ATmega168 needs to be connected to VCC. You can either wire
the RESET pin directly to 5V or you can 'tie it high' by connecting the
RESET pin to VCC through a resistor. This will allow you to add a
momentary reset button. What's this? The reset line on the ATmega168 is
exactly what it sounds like - it resets the micro just like the reset
works on your computer. If you look at the ATmega168 datasheet you'll
see the RESET label is written with a line above it. This is
nomenclature that indicates the reset pin is active low. What is
'active low'? The RESET pin is an input. A low level on this pin will
put the micro into reset - i.e. the pin is activated with a low input,
aka 'active low'. So unless you want your ATmega168 to stay in reset,
you'll need to pull this pin high.
Now you need a reset button. A momentary switch is a switch that is
activated (or closed) while you're touching it and open when you
release the button. These are often called 'tactile switches' because
they 'click' when you depress them giving the person pressing the
button some 'tactile' feedback.
This is what the schematic part looks like. Notice pins
1 and 2 are connected together. 3 and 4 are connected together. And
when you press 'de button, it temporarily connects 1/2+3/4 together.
Notice this button has five legs. If your button has
five legs, just ignore the middle leg - it's not connected to anything
and can be clipped off.
To test this button, whip out the trusty multimeter and
set it to the continuity setting. This is the setting on nicer,
mid-grade multimeters that is crucial to troubleshooting and
experimenting. Touch the probes together - you should hear a tone
indicating that there is continuity or a (nearly) zero resistance path
between the probes. Insert the button into the breadboard and probe the
two pins on one side of the button. If you picked pins 1/2 or 3/4 you
should hear a tone. These pins are permanently connected inside switch.
If you picked pins 1/3 or 2/4, you won't hear a noise - but hit the
button. By hitting the button you will make an electrical connection
between all four pins - and you should hear the tone! This means you
have electrical continuity.
The schematic shows pins 1 and 2 of the reset switch
connected together (connected to ground) and pins 3/4 connected
together (connected to !RESET) . In practice, you just need the switch
to work. Play with your multimeter and find two pins that don't make
noise when the button is not touched, and do make noise when the button
is depressed. Use these two pins.
The schematic shown above is what we're going for. The
10K resistor 'pulls' the reset pin high during normal activity. By
pulling the reset pin high, the ATmega168 runs normally. When you push
the reset switch (S2), the reset pin sees a continuous connection to
ground. Since the resistance through the depressed switch is nearly
zero, it wins (compared to the resistance of the 10K resistor!) and the
reset pin is pulled low, RESET is activated and the ATmega168 goes into
reset. Release the button and the reset pin is pulled high again and
the ATmega168 comes out of reset. Nifty!
See the dimple from the ATmega168 datasheet? Looking at
the top of the IC (legs down), with the dimple to the top, pin numbers
increase starting from 1 in the top left corner. This is how every IC
pin is number. However, the orientation marking varies a bit between
manufacturers and between packaging types. Look for a non-congruent
marking like a dimple, small dot, white arrow, a notched corner -
anything that makes that area of the chip different from the other
parts of the chip probably indicates pin 1. When in doubt, check the
Reset wired next to a ATmega8 (same applies for the ATmega168)
Learn how to use the the continuity setting on your multimeter. It will be vital to troubleshooting down the road!
Each microcontroller manufacturer has a different
method to get code in the flash memory of the micro. In the past few
years there has been emphasis placed on ISP or "in system programming".
ISP allows you to program the IC without having to disconnect the
microcontroller from the application. This is not trivial! History was
much more painful. Atmel has designed a relatively straight forward
method that requires the control of a few pins (6 total). Because of
this simple interface, the hardware programmer that is required to
connect your computer to this SPI interface is very straight forward
(cheap!) as well
The red stripe indicates the location of Pin 1
Remember how we identified pin1 on the IC from the
dimple? Well connectors also need polarization so that we don't reverse
the orientation of the connector and fry things. Unfortunately the way
connectors are numbered is opposite that of ICs. In the picture of the
ISP connector, you see the red stripe indicating pin 1. An IC counts
sequentially down one side. Connectors on the other hand, increase pin
numbers, back and forth, as you work your way down the connector.
The programming chain looks something like this:
There is a free C compiler called AVR-GCC. User writes code in C and then compiles that code into HEX files
AVR-GCC can be installed on the Windows platform with an easy WinAVR install program
The user gets this HEX code onto an AVR via the ISP pins
a serial port programmer and a parallel port programmere have been
designed to connect the computer port to the AVR ISP pins
computer runs a command line program to transfer the HEX file from the
computer, to the serial or parallel port, and out to the AVR ISP pins
The micro runs the machine code (*.HEX files) once powered or reset
What's a C compiler?
This is a program that inputs a program written in the C language and
outputs a HEX file. We prefer to program in C because it is easier for
us than assembly and more flexible than BASIC.
What's a HEX file?
This is a file that contains various hexidecimal characters. These hex
'codes' represent machine instructions that the ATmega168 understand.
This file is what gets sent down to the programmer, and the programmer
loads these machine instructions onto the ATmega168.
Before we can get too crazy, download and install WinAVR
on the computer that you will be doing your code development on. If
this link goes out of date, a google search should take you straight to
it. The windows install should be fairly straight forward - follow all
the defaults. WinAVR contains a version of the GCC compiler and various
other tools including avrdude and Programmer's Notepad. avrdude is a
simple command line program that takes a HEX file and sends it to the
serial or parallel port for programming onto an Atmel microcontroller.
Working backwards up this list, I'll provide you with
an example 'Hello World' HEX file that will prove that everything is
working correctly on your micro. With any micro controller board, the
first trick is always to get an LED to blink. This is the 'Hello World'
of embedded systems. Guess what blink_1MHz.hex does?
With the blink hex file in hand, you now need to get it
onto the micro. You will need to connect the AVR-PG1 (or the AVR-PG2)
to the ATmega168. The easiest way to do this is with 9 wires running
from your breadboard to the 10-pin connector on the ISP connector on
Jamming wires into the ISP connector is not a good
long-term solution but for the sake of getting the LED to blink, it'll
do. I've cut short wires and stripped both ends. One stripped end is
inserted into the end of the black programming connector, the other end
is inserted into the breadboard.
The AVR-PG2 parallel programmer wired into the
ATmega168. I've also wired up two 0.1uF caps. These decoupling caps are
placed near the VCC and GND pins on the ATmega168 to help reduce noise
into the IC. You may think you have a straight DC 5V but not really -
these 0.1uF caps help reduce ripple on the 5V line. Yes, the ATmega168
will probably run without them but they're good to have installed.
AVR ISP Note: You really do have to wire all 4 GND pins. You cannot wire just one of the GND pins on the ISP connector.
Additionally we need an LED to control. This can be tied to any GPIO pin. PC0 looks like a good spot.
The resistor/LED order does not matter - just remember
(from Tutorial 1) that you must have the resistor! The GPIO pin doesn't
actually matter. blink_1MHz.hex will toggle all the pins on all ports
so you can hook the resistor to any pin. As you add more peripheral
hardware you will want to dedicate some pins for alternate use (such as
TX and RX pins for serial communication).
You're getting closer! Time to program the chip!
Once WinAVR is installed, you should have a few new
icons on your desktop. Programmers Notepad is a nice code editor and
What's a code editor/highlighter? When programming, you
will need a text editor on your computer so that you can create (type)
code. Once you've created this 'code' on your computer (inside the code
editor) you will pass this code to the compiler (you will click a
button that runs the compiler with the C file you've typed) and the
compiler will create a HEX file (assuming there are no problems or
typos in your code). The highlighter? When creating code, it's often
nice to have various parts of your program color coded so that you can
tell a common things like for( ) and #define. This highlighting helps a lot when programming.
Use whichever text tool you like. Notepad will work, but is pretty rudimentary. I also like JFE
from my PIC days. Both have a 'tools' option which is great but JFE is
better in my opinion because it lists the C functions that you can
double click on and navigate to. If there is a way to do a similar
trick in Programmer's Notepad 2, please let me know! Because
Programmers Notepad v2 (aka PN2) comes with the WinAVR installation,
we'll use it!
AVR-GCC is extremely powerful, very complex, and
difficult to use initially. I am used to passing a *.c file to a PIC
and getting a HEX file back out. No fuss, no mess. Believe you me, the
pain of getting AVR-GCC up and running is worth it. AVR-GCC is a truly
nice compiler, and it's free. I've included a stock Makefile and blink_1MHz.c file in blink_1MHz.zip
to get you started. I am by no means a Linux or make type of person.
All you need to know is that when you type 'make' at the command
prompt, the compiler is going to look for a file called 'Makefile' (no
file extension!) and use that file to direct how to compile your C
These are the only two files you should need to get
blink to compile. Open up blink_1MHz.c in programmer's notepad and
click on Tools->Make All. This is the same as typing 'make all' from
the command prompt from what ever directory you saved these two files.
should compile your code as well. It's just a bit
easier to do this through the Programmer's Notepad interface rather
than toggling back and forth to the Command Prompt window. Once you
have successfully compiled the C file into a HEX file, you now need to
get that hex file onto the AVR. It's finally time to power up your
system! The cheap AVR programmers require the target (that's your
breadboard) to provide power to the programmer (that's the AVR-PG1 or
PG2). Power up your bread board - you should see the power LED come on.
From here on out, I will assume you're using the AVR-PG2 parallel port
There is only two spots in the makefile that you should
be concerned about at this time. These two spots are located under the
programming options section. This makefile is huge, but scroll down to
the Programming Options (avrdude) section. Now put a '#' in front of
lines you want to comment out.
If you're using the AVR-PG1 (serial port programmer) you edit like this:
#AVRDUDE_PROGRAMMER = stk200
AVRDUDE_PROGRAMMER = ponyser
# com1 = serial port. Use lpt1 to connect to parallel port.
#AVRDUDE_PORT = lpt1
AVRDUDE_PORT = COM1
If you're using the AVR-PG2 (parallel port programmer) you edit like this:
AVRDUDE_PROGRAMMER = stk200
#AVRDUDE_PROGRAMMER = ponyser
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = lpt1
#AVRDUDE_PORT = COM1
Of course the port numbers depend on your specific
computer but once you get things working, you'll be set for life.
Assuming you've edited and saved your makefile, go back to PN2. With
your breadboard powered, click Tools->Program. This will send the
command 'make program' to the command prompt. If everything is setup
correctly, you should have successfully loaded blink_1MHz.hex onto your
target ATmega168 and your LED should be blinking.
If you get an error :
can't open device "giveio"
Then read this page. Basically you need to copy the giveio.sys file from C:\WinAVR/bin to the C:\Windows directory, then type install_giveio.bat at the command prompt.
If you still are not able to program the AVR - this is where 99% of first time users end up. Dig in and troubleshoot.
Are the ISP connections correct? It's easy to get the ISP connector backwards. Take a look at the photos above.
Is there a loose wire? Pull out the multimeter and
check that you've got 5V being delivered to the VCC and GND pins on the
ATmega168. Do the wires going into the ISP connector have a good solid
Do you have your ATmega168 connected to both power and ground?
Is your 5V supply outputting 5V?
Do you have the right COM port or LPT port selected in your makefile?
There is a multitude of things to check. It's hard! I
know. But once you get things correctly set up, and that LED blinks -
it will feel fantastic!
Ok - I'm going to assume that you got the code
correctly loaded onto the AVR and that the LED is blinking.
Congratulations! You are now well on your way to a whole world of pain!
Once you get one thing working, it's hard to stop! GPS, datalogging,
RF, PCB layout - it's all just a couple hops away.
Here are some additional resources for AVR programming: