I was recently working on a project based on the ubiquitous ATmega328P microcontroller from Atmel. I decided that to make it easy for other people to work with, I would write the software for the microcontroller in the Arduino IDE.
Once I had a basic image prepared and loaded onto the microcontroller using a device programmer, I found that it seemed to run very slowly, and output from the serial ports was mangled. Here’s the basic circuit implementation I used:
After some Googling, I found that, by default, the ATmega328 uses some internal circuitry and will run at a clockspeed of 1MHz rather than using the external crystal clocked at 16MHz. I verified this by reading from the serial port at 600 baud (1/16th of the 9600 baud rate I specified) and sure enough, I got valid output. The Arduino IDE, configured for an Arduino Uno (ATmega328P) board, assumes that the device will be running at 16MHz, and if that clock rate is deviated from, all of the calculated bus speeds and time delays will be thrown off.
With the basic circuit above, there are some internal fuses on the ATmega328 that must be set appropriately to use the external crystal oscillator. Additionally, when running at clock speeds above 8MHz, there’s an additional bit that must be unset to ensure device stability.
The fuse low byte of the device must be 0xF7, the high byte must be 0xDE, and the extended fuse byte must be 0xFF. In the settings for my device programmer, this is controlled by setting certain bits to 0, as they all default to 1.
If you’ve purchased a default ATmega328 microcontroller and are experiencing strange behavior when trying to run binaries built in the Arduino environment, make sure your fuse settings match the image below.