An alternative UART that does not need special quartz frequencies

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.

Example 7o1 UART frame with 7 data bits, 1 parity and 1 stop bit, 11 bits in total

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.

Blockchart of enhanced UART

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?

Advertisements

About Wilfried Elmenreich

Understanding the communication networks of the future.
This entry was posted in Embedded Software, Hardware, Real-Time Networks and tagged , , , , , , , . Bookmark the permalink.

One Response to An alternative UART that does not need special quartz frequencies

  1. kuchura says:

    As far as I know, the UART clock in ARM Cortex M is obtained exactly as you described.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s