You are on page 1of 8

Setting Up An External Crystal Clock Source

(with Fuse Bits) for AVR ATMega


Microcontrollers
Posted on August 28, 2012 by 12 Comments

Hi everyone,

Recently, I came across the need to utilize an external clock source for my ATMega microcontroller. I
was initially under the impression that it would be a relatively daunting task after reading about the
mounds of bricked AVRs which had fallen into the unforgiving grip of incorrectly set fuse bytes. I
didnt find any tutorials geared specifically towards addressing this subject, suitable for beginners.
Fortunately my experience wasnt bad at all, and the main reason for that (I suspect) is that I did a lot of
research and asked even more questions to understand exactly what I was doing, and what I may be up
against. My goal for this tutorial is to teach anyone who wants to learn exactly what each and every
aspect of setting up an external clock source is, leaving no stones unturned.

In brief, I needed to set up an external clock source because of the limitations of the internal one; the
limitations being speed and accuracy. I needed more speed to support V-USB (expect a tutorial on that
in the future) which requires a faster clock than the internal one, and for those who dont know, the
USB protocol itself is infamous for its timing accuracy requirements. This tutorial will be based on the
ATMega8, but for the most part the information here will be applicable to any other ATMega you have.
If you dont have the ATMega8, then Ill teach you how to read the relevant parts of the datasheet so
you can easily figure out what you have to do on your own. If you know your stuff, feel free to skip
sections you find irrelevant in which case I also apologize for crowding this tutorial with basic
information.

Basic Ideas

Let us first take a little while to understand the basic concepts and ideas associated with setting up an
external clock source. I highly recommend opening up the datasheet for the ATMega8 (or your
microcontroller) for the duration of this tutorial, and briefly skimming the chapter on System Clock and
Clock Options (page 25). Click here for the ATMega8s datasheet.

What is a clock?
A clock is simply a device that keeps track of time, it kind of gives you a beat to move to. The clock on
your wall counts in increments of seconds, for example. A metronome for your instrument might give
you a beat every half or full second. The amount of times a clock ticks/cycles per second is called its
frequency, measured in Hertz (Hz or cycles/second). Similarly, your ATMega has a clock inside too,
and its speed directly relates to how many instructions it can carry out per second (on every tick/cycle
of the clock). The default clock speed that comes shipped with most AVRs is 1 MHz (1 million cycles
per second) because they have internal clocks which keep time. The internal ATMega8 clock can be set
up to a maximum frequency of 8 MHz, and beyond that you need an external source or else you would
be over clocking your AVR which could lead to unpredictable problems.
How can we set a clock speed?
We have two options: use the internal one, or use an external source. If you are writing code that does
basic stuff, and you dont require precision timing, the internal clock should suffice. In any other case,
particularly for communication (i.e. using the UART for example, or in my case, USB), timing is
critical. In that case, we need an alternate method, so we use things like crystals, resonators, oscillators,
and clocks. They are all suitable to produce the beat we are looking for, at the frequency we are looking
for, but the most common amongst hobbyists are crystals and resonator (youll see how they are pretty
much the same). We will be using a crystal for this tutorial, and it looks like this:

To use the crystal we will also require two ceramic 22 pF capacitors (so have those handy). A resonator,
on the other hand, has the capacitors and crystal built into one package, thus making it a little more
compact. Thats pretty much the only difference, but there may be subtle differences in setting fuse bits
if you are using a resonator just something to look out for in the datasheet. Oscillators require an
external power source to operate, and usually have four pins. External clocks, something a lot people
dont have (but wish they did), can also be used by pumping in a square wave at the desired frequency.

Start-up time
Clocks sources usually need a little bit of time to warm up and start giving us a reliable signal when the
microcontroller is turned on. This is called the start-up time. To play it safe, we will be using the
maximum start-up time to give the clock as much time as it needs to get up to speed (no pun intended).
Actually, the max start-up time is only a few milliseconds anyway!

What are fuse bytes?


This is the one concept which I noticed catches a lot of beginners off guard (myself included), and is
the source of a lot of confusion and mishaps. Typically, there are only two fuse bytes: a high one, and a
low one. As you should hopefully know, one byte contains 8 bits. So we have 16 bits to set to on or off.
Each of those bits, depending on whether they are on or off, impacts the critical operations of the
microcontroller. The mistake most people make is messing around with bits they did not intend to
change, or giving bits they intended to change the wrong value. This is particularly easy because a bit
set to 0 means it is programmed, and a bit set to 1 means it is unprogrammed kind of counter intuitive,
especially for those who wear binary wrist watches *whistles innocently*. But more on that later.

Going back to fuse bits, basically we modify a few bits in the high byte and the low byte to tell the
microcontroller that the next time you start up, expect an external crystal giving you a frequency of x
MHz, and you have to give it y amount of time to start up before you start running the code inside of
you. Thats pretty much it; look over the section called Memory Programming on page 215 just to get a
general idea of what comprises a fuse byte. As you may notice, each bit in each of the two bytes has a
specific name (i.e. RSTDISBL, CKSEL, SUT1, etc.). This makes it easier to refer to them, and harder
to make mistakes because the name of the bit alone gives you a good idea about what its purpose likely
is. For example, RSTDISBL stands for reset disable (you do not want to program this guy, unless you
pretty much never want to reprogram your precious microcontroller again), CKSEL for clock select,
SUT for start-up time, etc. Finally, its important to note that the default values for each fuse byte are
also listed in the datasheet.

Lets Do It!

So what do we know so far? Well, we now know that we have to set some bits to indicate we are using
an external crystal, one greater than a certain frequency, and requiring a certain start-up time. Lets go
through the datasheet, and bring our ideas together. Scroll over to the chapter titled System Clock and
Clock Options on page 25 (or whichever page it is for your microcontrollers datasheet). So we have 7
bits to change in order to get everything working the way we want: CKOPT, CKSEL3..0 (that means
CKSEL3, CKSEL2, CKSEL1, CKSEL0), and SUT1..0. We will address each bit below, with the
associated tables to refer to from the datasheet. For convenience I have also added the tables and
figures to the post, but they are all copied directly from the datasheet.

But first, lets take a quick peek at Figure 10:

As you can see, the clock multiplexer is given an input from one of the many clock sources. We will be
using the Crystal Oscillator. That input goes directly to all the critical parts of the microcontroller, from
the CPU and EEPROM, to RAM and your GPIO pins. The clock really is at the heart of everything,
giving the entire system a beat to operate at. Pretty cool huh?

Choosing the values for the fuse bits


Just to make sure we are on the same page, CKSEL3..0 means all the CKSEL bits from CKSEL0 to
CKSEL3. CKSEL stands for clock select, and tells our microcontroller what kind of a clock we are
using, and what its frequency is. Lets look at Table 2:

From this, we see that CKSEL3..0 has to be somewhere between 1111 and 1010. So the four bits
(CKSEL0, CKSEL1, CKSEL2, CKSEL3) are somewhere in that range. How do we know what they
are exactly? That depends on our crystals frequency, Table 2 is just telling us that if we use an external
crystal, the four bits will be somewhere in that range. Right, moving forward.

Table 4 gives us some more detail about CKSEL3..1 (note, not CKSEL0 just yet), and tells us what our
options for CKOPT are. We will program CKOPT (set it to zero) because a programmed CKOPT is
needed when we are dealing with higher frequency ranges, need a full swing signal, or we are driving a
second buffer with the same output from the clock. We meet the first criteria (16 MHz is > 1 MHz), so
we will set CKOPT to 0. As a result, CKSEL3..1 can be any of 101, 110, or 111, it doesnt matter.
Well go with setting the three CKSEL bits to 111 just for kicks.

Good, lets move on to the final three bits we have to work on: CKSEL0, SUT1, and SUT0.
As you may notice, Table 5 is the last piece of the puzzle. It tells us exactly what CKSEL0 and
SUT1..0 have to be! So lets see, we decided that we want the maximum start-up time earlier. In this
table, that would correspond to a Start-up Time of 16K CK and an Additional Delay of 65ms. Thus,
CKSEL0, SUT0, and SUT1 would all be unprogrammed (set to 1).

Were done! To summarize our bit settings, we have:

CKSEL0 = 1
CKSEL1 = 1
CKSEL2 = 1
CKSEL3 = 1
SUT1 = 1
SUT2 = 1
CKOPT = 0

Setting the fuse bytes

We know exactly which bits we need to change in the fuse bytes, so lets look at how the fuse bytes are
organized. Head over to the chapter called Memory Programming on page 215. As I said, there are two
fuse bytes, the high fuse byte, and the low. The bits we need to set are scattered inside these two bytes,
so we need to find which one is where, and change it without changing any of the other ones. Take note
of the default values in the fourth columns of the following two tables.
Table 87 shows the bits inside the high fuse byte. The only one we want to change is CKOPT (bit 4) to
0. So the high fuse byte should be 11001001 in binary, or C9 in hexadecimal.

Similarly, Table 88 is the table for the low fuse byte. We have 6 bits to change in here, and in the end,
our low fuse byte should be 11111111 in binary, or FF in hexadecimal.

Were almost at the final step!

Setting Up the Hardware

Finally, you are at the point at which you are ready to burn the fuse bits into your microcontroller. But
you want to make sure you have the crystal connected to your AVR too, so follow the schematic
below:
C1 and C2 are 22 pF ceramic capacitors. Have this setup as close together as possible, dont have wires
running around the breadboard to reach the crystal and ground. You could use the following setup to
try out the impact of the crystal along with the following code (skip this little bit if you dont want to
try out a simple example):

So if you want, give the above minimalistic setup and code a go, and you should see the LED blink
every 200 milliseconds (note that you should not connect the crystal just yet if you are going through
the example, so simply dont connect the green and orange wires for now). I ignored the pull-up on the
reset pin, decoupling capacitors, etc. just to keep it simple, but you should have that stuff (if you dont,
this setup should still work if you did everything else right). Also, make sure you have the correct pins
for your AVR model. One mistake in the diagram is the resistor value; sorry, I forgot to change it. Let
me know if you need help choosing the correct resistor, but I am sure you can handle that

Now we will run the commands in avrdude to burn the fuse bits. Of course, if you dont use avrdude,
use whatever tool you are comfortable with because the bytes will be the same.

avrdude -c usbasp -p m8 -U lfuse:w:0b11111111:m -U hfuse:w:0b11001001:m

Notice that we are using the actual binary values because the bits being changed are very clear.
However, it is recommended to use hex values, like this:

avrdude -c usbasp -p m8 -U lfuse:w:0xff:m -U hfuse:w:0xC9:m


Just to make it clear, you wouldnt be using -c usbasp and/or -p m8 if you are not using the USBasp
programmer and/or the ATMega8.

If you followed the above example, go ahead and connect the wires to the XTAL1 and XTAL2 pins on
your AVR (the green and orange ones in the diagram). If you did everything right and used the exact
code as the one pasted above, you will now notice the LED is not flashing. Well, thats because the
F_CPU value in your code is wrong. Well, it isnt wrong, but your F_CPU value of 1000000 now
means 1/16th of a real second is actually one second to the AVR. So your delay is no longer 200
milliseconds, but 1/16th of 200 milliseconds. The delay results in a frame rate of 80 flashes per
second! Thats too fast for the human eye to comfortably process.

So to fix this, we have to tell the AVR that because we changed the clock speed to 16 MHz, one second
actually is now made up 16 million cycles, not 1 million. All we have to do is change F_CPU to
16000000UL, and were done! Your LED should blink ever 200 milliseconds, just like it was before.

Conclusion

That was fun! I hope you learned something today, and I would like to sincerely apologize to anyone
who found this tutorial filled with too much basic information. One last note: if you would like to
return your fuse bit settings to the way they were from the factory, just run the same process again but
use the default bit values found in Table 87 and 88 instead of the ones we came up with.

I would love to read your comments and answer your questions as well, so drop me a line below. Keep
it cool everyone

References

I learned everything I wrote in this tutorial from the datasheet, and my friends on the Electrical
Engineering StackExchange, AVR Freaks, and Ladyada. A big thank you to everyone who helped me!

You might also like