What is the correct way to set the BAUD when programming an ATMEGA168A?

The code below works fine, however I don't know exactly what to do in case I decide to work with a higher BAUD such as 9600:

//CPU clock
#define F_CPU 1000000UL
#define BAUD 1200
//Baud rate
#define BAUDRATE ((F_CPU)/(BAUD*16UL)-1)
  • \$\begingroup\$ atmel.com/images/doc2545.pdf look around page 178ish \$\endgroup\$ – Axis Dec 21 '15 at 3:52
  • 1
    \$\begingroup\$ You change the BAUD define of course. Though using a slow CPU clock and the 16x baud sampling as you are will limit your options as rates get higher. \$\endgroup\$ – Chris Stratton Dec 21 '15 at 5:59

There are some great formulas on page 178 of the datasheet that describe the baud generator and how to calculate the divisors to get the USART clock rate that you want.

Baud Calculations

There are also some nice examples of baud rate settings on page ~200. The examples for the 1MHz case are here:

Baud Examples

Be careful to conduct your error calculations too, as some baud divisors aren't close enough to the desired frequency and may not work for you when you are trying to use the UART. Generally, I try to get within +/-2.5% or so when setting up the baud generator on these parts.

At 1MHz you might be trying to use the internal RC clock source with the CLKDIV8 fuse programmed. That's not a good idea when trying to set up USART communications on these parts. The RC oscillator performance is not good across voltage and temperature. The internal RC oscillator tolerance on these parts is pretty bad and is not good enough to hold UART communications without errors.

Here's the data in the datasheet about the internal RC oscillator performance across voltage and temperature. You'll notice that stacking the errors up can yield some pretty bad tolerances on the final RC oscillator values:

Internal RC Performance

To get it working, you will need to use an external clock source or go through some calibration procedures as described in these app notes. If you know your voltage and temperature won't move around much, you can gradually move the value in the OSCCAL to a value that does work, but that will be different from part-to-part and isn't a great production solution if you are making lots of devices. If you are going to try that, be sure to follow the guidelines in the datasheets and app notes. Changing the value in OSCCAL too much at once can disturb the oscillator and cause problems.

http://www.atmel.com/Images/doc2563.pdf http://www.atmel.com/Images/doc8002.pdf

Good luck - have fun setting it up and getting it working.

  • \$\begingroup\$ You're an order of magnitude off on the speed. It's the internal oscillator with the CKDIV8 fuse set. Which is terrible for UART communications, if anybody asks. \$\endgroup\$ – Ignacio Vazquez-Abrams Dec 23 '15 at 6:24
  • \$\begingroup\$ @IgnacioVazquez-Abrams - You're right! Missed a zero when I was counting last night. I'll update the answer. Thank you! \$\endgroup\$ – mhilden Dec 23 '15 at 14:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.