A UART (Universal Asynchronous Receiver/Transmitter) is a component that transmits chunks of data (typically character size, i.e. 7 or 8 bits) onto a serial communication line. Almost every microcontroller features at least one UART component, that can be configured to various transmission (baud) rates and data formats.
However, those hardware UARTs come with a limitation – their baud rate can only be set in a particular proportion to the clock source of the microcontroller:
The generic formula used to configure the baudrate of a UART is:
baudrate = f / (c1 * (UBRS + c2)
where c1 and c2 are constants depending on the microncoller type you are using. c1 corresponds to the number of samples per bitcell (e.g., c1 is 16 for Atmel microcontrollers). c2 equals 1 in most cases.
UBRS is a parameter that can be changed in order to select a particular baudrate. However, UBRS must be an integer. So if you want to achieve a baudrate of 115200 bit/s with a clockrate f=4,000 MHz, the best you can do is select UBRS to be
UBRS = f/(baudrate * c1) – c2 in our example 4000000/(115200*16) -1 = 1,17
rounded to an integer UBRS has to be chosen as 1, thus the actual baudrate is 125000 bit/s, that is too fast.
That’s why there are quartzes available with such odd frequencies as 1.8432 MHz, 3,6864 MHz, etc., which allow to set the standard baud rates such as 38400 bit/s without error. However, when you want to use a different clockfrequency for some reason you typically get significant rounding errors, especially for the fast baud rates. A last ressort to overcome this problem is to implement a software UART routine using a timer that is exactly configured to the bit length, but this comes with performance issues and less robustness unless you also implement oversampling and voting.
The interesting thing is, that it would not be so difficult to build a hardware UART more flexible. In our paper
M. Delvai, U. Eisenmann, and W. Elmenreich. Intelligent UART module for real-time applications. In Proceedings of the First Workshop on Intelligent Solutions in Embedded Systems, pages 177–185, 2003.
we propose an alternative design for a hardware UART that can be configured to any baudrate with minimal error. This is achieved by adding a fractional part (4 bits) to the baud rate setting constant. The enhanced baud rate generator uses fixed point arithmetics to calculate sufficiently excat baud rates. The enhanced UART also solves another problem common to most hardware UARTs: Typically the transmission of a character is delayed until the internal state machine reaches the state for transmitting a new character – this can only be overcome by resetting the UART if you want to transmit a new character immediately at a given instant. Our enhanced UART supports this feature instantly.
We implemented the UART in VHDL and tested it successfully in an FPGA. Despite the additional features, the proposed UART is approximately the same size in implementation as a standard UART module.
Maybe we can get rid of those odd quartz frequencies soon?