Skip to main content

Microcontrollers

Section 10.3 ATmega328P Universal Synchronous/Asynchronous Receiver/Transmitter (USART)

The universal synchronous/asynchronous receiver/transmitter (USART) is a serial protocol commonly included in microcontrollers. The ATmega328P USART is a full duplex protocol that is capable of operating either asynchronously or synchronously. The USART on the ATmega328P is also capable of operating in an SPI mode as a primary device. Regardless of the mode of operation, the USART protocol operates by sending frames of information. A frame consists of
The number of data bits that can be transmitted or received can vary between 5-9 bits, and is configured using the USART character size (UCSZ0) bits in the USART control and status registers B and C (UCSR0B and UCSR0C).
When configured as a transmitter, the microcontroller can generate either an even or odd parity bit to include in the frame. When configured as a receiver, the microcontroller will receive a parity bit, if configured, and use it to for parity error detection.
The number of stop bits included in the frame is also configureable.
Flags are generated upon completion of transmission or receiving data, or when the transfer data register is empty. When enabled, these flags can generate interrupts.
A block diagram of USART features and functionality is depicted in FigureΒ 10.3.1.
A thick data bus is drawn vertically on the left side of the figure from top to bottom. The top third of the block diagram is drawn with a dashed outline and labeled "clock generator." This contains a clock direction block, UDRR0 register block, and baud rate generator block. External to this component is the XCK pin. The XCK pin connects bidirectionally to the clock direction block. UBRR0 connects bidirectionally to the data bus. UBRR0 writes to the baud rate generator block. The middle third of the block diagram is drawn with a dashed outline and labeled "transmitter." This contains a block for the UDR0 register to transmit, a transmit shfit register, and parity generator block. External to this component is the TXD pin. The data bus writes to UBR0 to transmit. UBR0 writes to the transmit shift register. The clock direction block acts as the clock input to the transmit shift register. The transmit shift register writes to the parity generator. The parity generator writes to TXD. The bottom third of the block diagram is drawn with a dashed outline and labeled "receiver." This contains a receive shift register, UDR0 register to receive, and parity checker block. External to this component is the RXD pin. The RXD pin writes to the parity checker block. The parity checker writes to the receive shift register. The clock direction block acts as the clock input to the receive shift register. The receive shift register writes to the UDR0 register. UDR0 writes to the data bus.
Figure 10.3.1. USART block diagram.

Subsection 10.3.1 USART I/O pins

In asynchronous mode, two I/O pins are used, one to transmit data (TXD), and one to receive data (RXD). In synchronous mode, an additional pin is required for the clock signal (XCK). These I/O pins are listed below.
When the USART transmitter is enabled, the TXD pin is configured as an output, overriding any other value on the DDRD register. When the USART receiver is enabled, the RXD pin is configured as an input, overriding any other value on the DDRD register.
When the microcontroller is configured in synchronous primary mode, a clock signal will be generated on the XCK pin. When configured in synchronous secondary mode, a clock signal needs to be supplied to the XCK pin.

Subsection 10.3.2 USART Clock and Baud Rate Generator

Regardless of whether or not the USART is operated synchronously or asynchronously, the data must be received or transmitted at a consistent rate. (The difference is that in synchronous mode, the primary device on the USART supplies a clock source consistent with this data transmission/receive rate.) In the USART, this is known as a baud rate, which is defined in bits per second (bps). The baud rate should always be configured prior to writing to the USART control and status registers. [16.5]
The baud rate can be set using the USART baud rate register (UBRR0), and the baud rate that is generated depends on the mode of operation. In asynchronous normal mode, the baud rate is defined by (10.3.1) and the value to store in UBRR0 is defined by (10.3.2).
\begin{align} \textrm{BAUD} \amp= \frac{f_{CLK,I/O}}{16 \times (\texttt{UBRR0} + 1)}\tag{10.3.1}\\ \texttt{UBRR0} \amp= \frac{f_{CLK,I/O}}{16 \times \textrm{BAUD}} - 1\tag{10.3.2} \end{align}
In asynchronous double-speed mode, the baud rate is defined by (10.3.3) and the value to store in UBRR0 is defined by (10.3.4).
\begin{align} \textrm{BAUD} \amp= \frac{f_{CLK,I/O}}{8 \times (\texttt{UBRR0} + 1)}\tag{10.3.3}\\ \texttt{UBRR0} \amp= \frac{f_{CLK,I/O}}{8 \times \textrm{BAUD}} - 1\tag{10.3.4} \end{align}
In synchronous primary mode, the baud rate is defined by (10.3.5) and the value to store in UBRR0 is defined by (10.3.6).
\begin{align} \textrm{BAUD} \amp= \frac{f_{CLK,I/O}}{2 \times (\texttt{UBRR0} + 1)}\tag{10.3.5}\\ \texttt{UBRR0} \amp= \frac{f_{CLK,I/O}}{2 \times \textrm{BAUD}} - 1\tag{10.3.6} \end{align}
Depending on the I/O clock frequency, and the fact that the UBRR0 register can only store integer values, there may be an error between the desired baud rate and the actual baud rate. This error is defined in (10.3.7).
\begin{equation} \textrm{error} = \frac{\textrm{actual baud rate}}{\textrm{desired baud rate}} - 1\tag{10.3.7} \end{equation}

Example 10.3.2. Baud rate error using the ATmega328P in asynchronous normal mode.

Consider running the ATmega328P in asynchronous normal mode with a 1Β MHz clock at a baud rate of 28.8Β kpbs. The value that should be stored in UBRR0 can be calculated as shown in (10.3.8).
\begin{equation} \texttt{UBRR0} = \frac{1 \times 10^6}{16 \times 28800} - 1 = 1\tag{10.3.8} \end{equation}
A more exact value of the calculation is 1.17, but fractional values cannot be stored in a register. The integer value to be stored is 1. The actual baud rate that results from this register value is shown in (10.3.9).
\begin{equation} \textrm{BAUD} = \frac{1 \times 10^6}{16 \times (1 + 1)} = 31250~\textrm{bps}\tag{10.3.9} \end{equation}
The error, calculated using (10.3.7), is calculated in (10.3.10).
\begin{equation} \textrm{error} = \left(\frac{31250~\textrm{bps}}{28800~\textrm{bps}} - 1\right) \times 100\% = 8.5\%\tag{10.3.10} \end{equation}

Subsection 10.3.3 Transmitting Data

The USART can be configured to transmit data by setting the transmitter enable (TXEN0) bit in the USART control and status register B (UCSR0B). (This configuration must occur after setting the baud rate in UBRR0.)
Prior to transmitting data, it is important to ensure that the transmit buffer is empty. This is accomplished by ensuring that the USART data register empty flag (UDRE0) is set. Data transmission between 5 and 8 bits is initiated when data is written to the USART I/O data register (UDR0). This will send a data frame out using the TXD pin.
To send 9 bits of data, first ensure that the transmit buffer is empty. Then, write the ninth bit to the transmit data bit 8 (TXB80) bit in USART control and status register B (UCSR0B). Finally, write the remaining low byte to the UDR0 register, which will initiate the transmission of the data frame using the TXD pin.

Subsection 10.3.4 Receiving Data

The USART can be configured to receive data by setting the receiver enable (RXEN0) bit in the USART control and status register B (UCSR0B). (This configuration must occur after setting the baud rate in UBRR0.)
Data is received when the USART unit detects a start bit. Each subsequent bit in the frame will be sampled either using the baud rate (asynchronous mode) or on the clock signal input to the XCK pin (synchronous mode). The sampling will continue until the first stop bit is received. When data has been written into the receive buffer, the USART receive complete flag (RXC0) will be set in USART control and status register A (UCSR0A). If interrupts are not used to determine if data is received, then polling that flag can be used to determine if new data is ready to be read out of the UDR0 register.
If 9 bits of data are to be received, the ninth bit must be read from the receive data Bit 8 (RXB80) bit before reading the remaining low byte of data from UDR0.
Data is buffered as it is received by the USART. If it’s necessary to clear the buffer, simply continue to read the contents of UDR0 until the USART receive complete flag (RXC0) is cleared.

Subsection 10.3.5 Receiver Errors

The USART on the ATmega328P has three receiver error flags that can be read in the USART control and status register A (UCSR0A). Note that this register must be read before reading data from UDR0 or the data bit 8 bit in UCSR0B. (When writing to the UCSR0A register, ensure that the flag bits are written as zero.)
The receiver errors are listed below.
  • A frame error (indicated by the frame error flag FE0) occurs when a stop bit is not recorded at the expected time.
  • A data overrun error (indicated by the data overrun flag DOR0) occurs when the receiver cannot process data quickly enough. New data is arriving before previous data has been buffered or written into the UDR0 register.
  • A parity error (indicated by the parity error flag UPE0) occurs when there is a parity error with the received data. This flag can only be set if parity check is enabled.

Subsection 10.3.6 USART in SPI Mode

The USART module can be configured to run in SPI primary mode if so configured using the USART mode select (UMSEL0) bits in the USART control and status register C (UCSR0C). When using the USART in this manner, the bits in the USART control and status registers B and C are modified to eliminate some of the features of the USART and align it with the SPI protocol. For example, frames only consist of 8 bits (it cannot be configured for 5, 6, 7, or 9-bit mode) and parity generation and detection is removed. When operating the USART in SPI mode, the registers give the option to set the clock polarity and phase, which is consistent with the descriptions provided in TableΒ 10.2.5.