Embedded systems often require communication between integrated circuits. An example would be a digital temperature sensor reporting the ambient temperature of the room to the the main microprocessor. This data is often transmitted over a serial interface.
So what is a serial interface? At a very basic level, a serial interface is a shift register that shifts data in/out one bit at a time. The illustration below shows how the data is loaded using a parallel load into a shift register. After the parallel load, data is shifted out one bit at a time, starting with the least significant bit.
So why would we use a serial interface as compared to a parallel interface? If we want to transfer a 32-bit value using a parallel interface, we need a minimum of 32 pins on the microprocessor. Parallel buses are very fast, but they require a large number of external pins for a single interface. Adding additional pins to a devices increases the material costs and physical size of a microprocessor.
The motivation behind using serial interfaces is that a serial interface consists of only a few pins. Using a small number of pins, we can transmit data of any size. If we need our data to be 32 bits instead of 8 bits, we simply need additional clock cycles. Reducing the number of pins also makes printed circuit board (PCB) development much easier since there are far fewer pins to route between devices.
The serial interface we will examine here is called a UART. The term UART stands for Universal Asynchronous Receiver/Transmitter. UARTs are commonly used to interface with devices that have no graphical display capabilities. The UART can provide input/output to a terminal program that allows the user to monitor status and provide input.
The UART interface consists of two pins: the Rx and Tx pin. The Rx pin is used to receive data. The Tx pin is used to transmit data. When two devices are connected using a UART, the Rx pin of one device is connected to the Tx pin of the second device.
The Rx and Tx pins are normally connected to separate shift registers (one for shifting data out and one for shifting data in). Two separate shift registers allows a UART to transmit and receive data at the same time.
In addition to the shift registers, there will be one or more status registers. Software examines the status registers to determine when the transmit shift register is empty. When the transmit register is empty, the next byte of data can be loaded into the transmit shift register. The status register also will have a status bit that indicates when a new byte of data has been received. Software can then read the receive register which removes the data and allows the next byte of data to be shifted in.
A UART can have additional registers that allow software to configure the behavior of the UART. Software will set the speed at which the interface transmits data and the format in which the data is sent.
One of the key features of a UART is the ‘A’ in the name. The ‘A’ stands for Asynchronous. A UART is asynchronous in nature because there is no common clock shared between the devices. Instead, both devices must agree on what the structure of the data being sent is and at what speed the data is being sent. This agreement allows a UART interface to over sample the data lines and re-construct the raw data into a data packet. We will examine the three characteristics that make up a UART data packet.
In order to correctly send the data between two UARTs, both UARTs must be configured to receive and transmit data at the same data rate. This is commonly referred to as the baud rate of the UART. By setting the same baud rate, the internal state machines of the UART can set an appropriate rate at which the shift registers operate. Common data rates include 9600 and 115200 baud but some UARTs support higher data rates of several megabits per seconds.
In some situations a data packet may contain a parity bit. The parity bit is used by the receiving device to determine if any data corruption has occurred in the transmission process. If a data packet is configured for even parity, the total number of ones, including the parity bit, should be an even. If a data packet is configured for odd parity, the total number of ones, including the parity bit, should be an odd number.
In order for a microprocessor to detect when data arrives, we need to define how the Rx/Tx lines behave when data is not being sent. In most situations, both the Rx/Tx lines will be driven high when no data is being sent. When a device transmits data, it starts a data transmission with a start bit. The UART will bring the Tx line low for one time period of the data rate, indicating that a transmission of data is about to begin.
After the start bit, the data is shifted out at the defined data rate until all of the data has been transmitted. UARTs transmit data least significant bit first. Once all the data has finished being transmitted, the optional parity bit is sent, followed by a stop bit. The UART generates a stop bit by bringing the Tx line high for 1 period of the data rate. Many UARTs can be configured to generate 1 or 2 stop bits. The figure below demonstrates how the value 0x71 would be transmitted using both even and odd parity.
Data that is sent without a start bit or a stop bit results in a framing error. A UART may simply discard this data or more likely it will indicate an error condition by setting a status bit in a status register. In most situations, framing errors can occur if there is a substantial amount of electromagnetic interference that invalidates the data being transmitted.
One of the most common configurations seen for UARTs is referred to as 8N1. This stands for 8 data bits, no parity bit, and one stop bit. 8N1 transmits 8 bits of data for every 10 bits that are transmitted. The addition of a parity bit and extra stop bit increases the overhead per packet and reduces the overall throughput of actual data.