CK8DIV Fuse

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello to everybody, how are you? This is not a post asking help, it's a post that explains what happens to me, and may be it will help somebody else.

I'm working with a ATmega644 at 20MHz, and using WinAVR. I have the frecuency clock defined so everything should work ok.

Firt I noticed that the delay rutines where not so accurate, like _delay_ms(500) should produce nearly 1 second, and in my case I was getting 4 seconds.

But, when trying to use the USART at 9600bps, I found that in Hyperterm I only see the correct message at 1200bps! 8 times slower!

This is the configuration of the USART (taken from Atmel AVR306 App Note)

void uart0_init(unsigned int baud) {
	/* Set baud rate */
	UBRR0H = (unsigned char)(baud>>8);
	UBRR0L = (unsigned char)baud;
	/* Enable receiver and transmitter */
	UCSR0B = (1<<RXEN0)|(1<<TXEN0);
	/* Set frame format: 8data, 2stop bit */
	UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}

and it's being called from main like this:

uart0_init(129);

So everything was right, where the problem was? In the fuses configuration of the microcontroller, CKDIV8 has activated! I think it's activated by default, as my two chips where new.

Bye!
Ezequiel

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

By default all AVR's come from the factory operating at 1MHz from the internal oscillator. (or 1.2MHz in a couple of cases) For many of these AVR's there is no 1MHz oscillator, but rather a single 8MHz one. On these models, the CLKDIV8 fuse is set, to configure teh clock prescaler to a divide by 8 mode. As a result, that the AVR runs at the default 1MHz.

Whenever you change clock sources, you will want to make sure you set this fuse appropriately as well.

Note that you can also clear the effect of this fuse in software, by altering the contents of the Clock Prescaler register.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I think it's activated by default, as my two chips where new.

That's certainly what the datasheet says but in the chips that have CKDIV8 there is also a CLKPR register (in fact all CKDIV8 does is set CLKPR to /8 by default). So if you always start code with:

#ifdef CLKPR
	CLKPR = (1 << CLKPCE); // enable a change to CLKPR
	CLKPR = 0; // set the CLKDIV to 0 - was 0011b = div by 8 taking 8MHz to 1MHz
#endif

this will guarantee that the divisor is set to a known state whether CLKDIV8 fuse is active or not.

Cliff