While working through my Arduino "Brain-Fart" dilemma:
I came to a conclusion...
I have never been a proponent of the n = (Fosc / (16 * BAUD)) - 1 equation. I've always gone to the data sheet and looked up the appropriate value needed to derive the desired BAUD rate for a given crystal frequency and defined what the BAUD rate is with the following:
// USART0 = 115.2K BAUD @ 18.432MHz #define BAUD_115_2K 9
I did, at one time, use the n = (Fosc / (16 * BAUD)) - 1 equation to prove to myself that this equation worked.
Well, while in the fog of my "Brain-Fart", I decided to see if I could employ the use the BAUD rate equation to verify what the BAUD should be and, here is what I discovered.
For any of the "Magic" frequencies: 14.7456MHz, 18.432MHz, etc., the BAUD rate calculation resolves to numbers that are exact whole numbers - meaning, there is no fractional part.
But... for crystal frequencies that don't resolve to whole number results, such as 1.000MHz, 4.000MHz, 8.000MHz, 12.000MHz, 16.000MHz, 20.000MHz, the formula doesn't seem to be the most appropriate approach and, here is why:
For a, say, 16.000MHz crystal, the resulting BAUD constant when calculating for a BAUD rate of 115.2K BAUD works out to:
n = (Fosc / (16 * BAUD)) - 1 = n = (16.000MHz / (16 * 115200 BAUD)) - 1 = 8.680555... - 1 = 7.680555...
I don't know how it is for GCCAVR, WinAVR or some of the other AVR C compilers but, rather than rounding 7.680555... up to 8 when moving from a float to UNSIGNED INT, ImageCraft's ICCAVR C compiler truncates the result of the equation to the value of 7. The issue is that, according to the data sheet BAUD charts, deriving a BAUD rate of 115.2K BAUD when using a crystal frequency of 16.000MHz and a BAUD constant of 8 inherently produces an error of -3.5%.
For a BAUD constant of 7 the BAUD rate is:
BAUD = Fosc / (16 * (UBRR + 1)) = 16000000 / (16 * (7 + 1)) = 125000 BAUD >>> from the datasheet <<<
% error = 100 - ((115200 / 125000) * 100) = 100 - (0.92 * 100) = 100 - 92 = +8% error.
While I have only performed the error resulting due to fractional truncation for one BAUD rate, I suspect the error will be proportionally as bad, across all of the BAUD settings, using the much touted n = (Fosc / (16 * BAUD)) - 1 to derive BAUD rates with non BAUD friendly crystal frequencies.
I think I'll keep using hand fed BAUD constants presented in the data sheet BAUD charts.