[Solved] ATMega328P-AU running at 1 MHz instead of 16 Mhz

Hi,

I have just put ATMega328P-AU (brand new - no bootloader, no program) on PCB, added 16 MHz crystal, ISP header and successfully programmed "blink" example it using AVRISP mkII (used Uno and Duemillanove 328 board profiles). To my surprise LED blink frequency was very small. Using stopwatch I came to conclusion that 328 is running at 1 MHz instead of expected 16 Mhz.

I searched this forum but could not find the answer. Found traces lead to fuse settings.

Please, does anybody know what is wrong and how to fix it - to get 16 MHz?

Thanks.

qwertysimo

You need to change the FUSE settings.

Look at 'boards.txt' and my signature.

Thanks so far. So, I created a new section in boards.txt for testing, selected it in IDE, and used fuse calculator from your link. According to 328 manual, CKSEL3..0 for external crystal should be from 1111 to 1010. I tried to set bootloader.low_fuses from F0 to FF with different SUT setting as well. After each change in boards.txt I reopened IDE and reload the Blink sketch. No change - stil working on low frequency.

Any other idea on the cause? What else to check? Thanks.

Changing the values in the boards.txt file alone doesn't doe anything. The fuse settings are also NOT changed when uploading code.

The IDE only changes these if you use it to upload a bootloader. If you don't need that, change the fuse settings by hand.

That is what I was exactly thinking on seeing property name in form of "...bootloader..." - my changes had no effect.

"...change the fuse settings by hand" - how can I do this? In AVR Studio or is there some alternative procedure?

Thanks.

Well, if you feel at home with Studio use that.

If you like avrdude, you could do it like this:

avrdude -c <programmer> -p <mcu> -B 100 -P <port> -b <baudrate> -e -U lock:w:0x3F:m -U lfuse:w:0x<lfuse>:m -U hfuse:w:0x<hfuse>:m -U efuse:w:0x<efuse>:m                                                      
avrdude -c <programmer> -p <mcu> -B 1 -P <port> -b <baudrate> -U flash:w:<hexfile>:i -U lock:w:0x0F:m

how can I do this?

Command line. avrdude. For example, this reads the EEPROM from an ATtiny13 and saves the contents into a file named dump.txt ...
avrdude -p attiny13 -c stk500v1 -P \.\COM14 -b 57600 -U eeprom:r:dump.txt:h

Changing fuses is like building fine furniture. One wrong move and the piece is ruined.

First get comfortable reading the fuses from the targetA. Then get comfortable writing to FlashA. Next determine exactly what the fuses should be. RepeatB. If you get the fuses wrong the processor can be left in a state where only a "high voltage" programmer can resurrect it. Finally, change the fusesC.

Continuing with the woodworking analogy...

A Practice using the tool.
B Measure twice.
C Cut once.

Yap. I was just reading Ladyada's "Burning fuses" tutorial - using avrdude command line as well...

To prevent my 328 from damaging, I guess it is safe to use fuse settings from boards.txt, right? Uno is the closest match:

uno.bootloader.low_fuses=0xff
uno.bootloader.high_fuses=0xde
uno.bootloader.extended_fuses=0x05
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F

Setting low fuses to 0xFF matches 16 MHz external crystal and longest start up time - my goal!

OK, lets continue tomorrow - bedtime here. Guys, thanks a lot for great info so far.

I have just put ATMega328P-AU (brand new - no bootloader, no program) on PCB, added 16 MHz crystal, ISP header and successfully programmed "blink" example it using AVRISP mkII (used Uno and Duemillanove 328 board profiles). To my surprise LED blink frequency was very small. Using stopwatch I came to conclusion that 328 is running at 1 MHz instead of expected 16 Mhz.

The solution I use is first burn the standard bootloader, then upload your program (whether or not it uses the bootloader).

Are you sure it isn't just 8 times slow? There is a divide-by-8 fuse bit.

Use avrdude to see what your current fuses are, something like this:

avrdude -c usbtiny -p m328p -v

I am sure. I changed both "delay(1000);" statements in Blink sketch to 100 ms. Turn on/off LED cycle is hence 200 ms. Ten cycles give 2 seconds. After uploading the sketch it took about 31 seconds for LED to do 10 cycles. 31 s / 2 s "=" 16

I read your last post after I did procedure below. I do not know what were default factory settings for fuses. I can check them in my next project with another blank 328.

John_S:
The solution I use is first burn the standard bootloader, then upload your program (whether or not it uses the bootloader).

Thanks John. That was my last option if everything else fails.

Gentlemen, I made it working with your great help. Solution:

avrdude -C ../etc/avrdude.conf -c avrispmkII -P usb -p atmega328p -e -U lfuse:w:0xff:m -U hfuse:w:0xde:m -U efuse:w:0x05:m

328 is finally working at 16 MHz!

Thank you very much.