# ATMEGA8 with 8Mhz crystal just running at 1Mhz

I have a ATMEGA8A-PU with a 8Mhz crystal oscillator (T8.000 is 8Mhz isn't it?) and the following C code:

#define F_CPU 8000000UL

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

int main(void) {
DDRC = 0b00100000;
while(1) {
PORTC ^= 1 << PORTC5;
_delay_ms(1000);
}
return 0;
}


So, just a simple code, that switches the LED on and off every second.

But when I write this program to the controller, the LED switches on/off after about 8 seconds. When I replace F_CPU to 1000000UL, it switches nearly every second.

So I thought, it's a problem with the fuse bits, but they are set to F1 (low) and D9 (high) which looks good to me.

Anyone who has an idea how I get the full 8Mhz?

• What environment are you using for building this? What do F1 and D9 mean (per datasheet CKSEL fuses is what we need to know)? – Mihailo Nov 22 '11 at 8:38
• According to the Engbedded AVR Fuse Calc, it's an Ext Clock setting, hence the confusion. The ATMEGA8 doesn't have a CKDIV8 bit like its larger siblings, so that's out. I don't know what to say except, double check everything. – mng Nov 22 '11 at 9:12
• After playing with it a bit more, it appears that plugging F1 D9 into the bottom part of the form gives erroneous results up top. Starting from the top gives C0 D9. (It sounds like this is an oscillator, not a plain crystal.) – mng Nov 22 '11 at 9:22

When I replace F_CPU to 1000000UL, it switches nearly every second.

That should give you a clue: the CPU is running at 1MHz and not 8MHz

Your lfuse settings are wrong.

lfuse => 0xF1
SUT[1:0] => 11
CKSEL[3:0] => 0001


This selects the internal RC Oscillator (see sec. 8.2 "Clock Sources" in the Datasheet), and SUT is set to a value that is not allowed for this value of CKSEL (Table 8-9)

To have it run off the 8MHz ext. crystal, you need these settings:

From Table 8-3:

CKSEL[3:1] = 111 (freq. range is [3.0, 8.0] MHz)
CKOPT = 1 (unprogramed, for low-power mode; if set to 0, you need to change hfuse as well)


From Table 8-4:

CKSEL[0] = 1
SUT[1:0] = 11 (Crystal Oscillator, Slowly rising power: change this if you want)


This gives lfuse = 0xFF

Don't forget the 22pF capacitors!

• Thanks, but I thought I have to invert the values (0, 1), because 1 means unprogrammed and 0 means programmed, and I want CKSEL[3:1] to be programmed. – Ethan Leroy Nov 22 '11 at 10:04
• @EthanLeroy, you don't invert anything, you use the values given in table 8-1 (page 25) in the datasheet. Your confusion probably stems from the fact that boolean fuses generally use the value 0 for true and 1 for false. – avakar Nov 22 '11 at 14:33
• When they say "1 is unprogrammed", that means that is the value you get after erasing, and you need to write/program a '0'. – W5VO Nov 22 '11 at 15:30
• @EthanLeroy: You're not alone, almost everyone gets confused with this. AFAIK, you need to mentally invert the values for a few GUI based tools (can't think of anything specific right now, but I know I've seen some tools that have checkboxes corresponding to each fuse bit, you have to uncheck for a '1' and check for a '0'). Atleast avrdude and uisp accept fuse values that can be directly lifted from the datasheet -- they figure out if the fuse bit needs to be programed or not, you just give them what the datasheet says. – ksk Nov 22 '11 at 18:16

You probably haven't changed any fuses and it uses internal 1MHz oscillator. You've mentioned you're using external crystal, if so, you have to program some fuses in order for it to work.

CKSEL3:0 fuses should be 1111 (all unprogrammed - 1 is unprogrammed, 0 is programmed), you also try CKOPT fuse first unprogrammed (1) and later programmed (0) if it originally does not work. That should be all you need to do to make it working. As per datasheet you'll be interested in sections 8.3 Crystal Oscillator and 24.2 Fuse Bits.