1
\$\begingroup\$

So I have an xbee (API mode, series 2) communicating with either a naked 328p on a breadboad (8 MHz external oscilator) or an adafruit pro trinket (328p based, 12 MHz external oscilator). Though never both at the same time.

Note the xbee has a 16 MHz internal oscilator of some description - and doesn't really the "standard" baud rates.

I picked a baud rate of 200,000 as a non-standard rate that's a perfect multiple of both clock speeds. Should be able to work with either flawlessly. And yet.... it doesn't.

  • Test 1: The 8 MHz breadboard works perfectly at 200K, with 8 bits and 1 stop bit. Fine as intended.
  • Test 2: The 12 MHz trinket... just doesn't at 200K, 8N1.
  • Test 3: 12 MHz at 200K, 8N1 - no joy.
  • Test 4: 12 MHz, 100K 8N2 works.

And now I'm just confused. I appear to have missed something basic somewhere. What speed should I have used? Why?

\$\endgroup\$
1
  • \$\begingroup\$ Pro tip: capital H in Hz. Prefix mega is M. Hence MHz. \$\endgroup\$
    – winny
    Nov 12, 2021 at 8:51

1 Answer 1

3
\$\begingroup\$

Assuming the Adafruit Pro Trinket is just an ATMega328P running at 12 MHz, it cannot divide 12 MHz to an UART bit rate of 200 Kbps, while an ATMega328P running at 8 MHz can.

So some clock speeds are just not compatible with some baud rates. A classic example is that an 8 MHz AVR can't use standard baud rate of 115200, but if you change the 8 MHz crystal to somewhat slower and commonly available 7.3728 MHz crystal that is known to be UART baud rate friendly, you can achieve exactly 115200 bps with no baud rate error other than the max 0.01% of the crystal itself.

So first of all the UART does not sample the data line at the baud rate, it uses oversampling. The ATMega328 is capable of oversampling ratios of 16x which is the default mode of operation for almost all UARTs, and by using the U2X bit the oversampling ratio can be halved to 8x to achieve higher bit rates at the expense of being less tolerant to deviations in the bit rate.

Let's do the math.

8 MHz / 16 = 500 kHz. Can't divide to 200k. Can't work without U2X. 8 MHz / 8 = 1000 kHz. Can divide to 200k. Will work with U2X.

12 MHz / 16 = 750 kHz. Can't divide to 200k. Can't work without U2X. 12 MHz / 8 = 1500 kHz. Can divide to 200k. Can't work even with U2X.

12 MHz / 16 = 750 kHz. Can't divide to 100k. Can't work without U2X. 12 MHz / 8 = 1500 kHz. Can divide to 100k. Will work with U2X.

You could have checked the datasheet how the UART works and what bit rates are possible, there is a long section about that with good looking diagrams. As some MCUs can derive their clocks differently, this will only apply to the ATMega328P, however many AVRs are quite similar.

\$\endgroup\$
2
  • \$\begingroup\$ Added info to question: The adafruit trinket pro is a 328p. The internal clock rate of the xbee is 16Mhz Question: So the correct calculation is clock rate -> samples/sec, -> some byte rate (baud)? \$\endgroup\$ Nov 12, 2021 at 7:39
  • \$\begingroup\$ In general, yes. For the XBEE, I don't even know what MCU it has since it is a product, not a MCU, so I have no clue how it can divide the bit rate. It's MCU specific. Some have fractional baud rate generators, and some have variable oversampling ratios. Please refer to documentation of the MCUs and products you use for details. \$\endgroup\$
    – Justme
    Nov 12, 2021 at 8:33

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.