Introduction to UART: Universal Asynchronous Receiver-Transmitter
UART (Universal Asynchronous Receiver-Transmitter) is a widely used serial communication protocol that facilitates data exchange between microcontrollers, computers, and peripheral devices. Unlike other communication protocols like I2C and SPI, UART operates asynchronously, meaning it doesn’t require a shared clock signal between devices. This makes UART ideal for simple, low-cost data transmission over relatively short distances, like connecting a GPS module to a microcontroller or a PC to a microcontroller for debugging purposes.
In serial data communication, like USB, data is sent bit by bit, but USB is typically more complex and includes its own protocols and connectors, designed for high-speed communication and often carrying additional data for device identification and power.
UART communication, on the other hand, is a simpler form of serial communication that uses two specific pins:
- TX (Transmit) – for sending data.
- RX (Receive) – for receiving data.
These TX and RX lines are directly connected between two devices, allowing them to exchange data. This setup is commonly used in microcontrollers, modules, and other embedded systems for straightforward, asynchronous data transfer over short distances.
Basics of UART Communication
In a UART-based system, each device involved has two main communication pins:
- TX (Transmit) – The pin responsible for sending data.
- RX (Receive) – The pin responsible for receiving data.
Each UART-enabled device communicates over a pair of wires, where the TX pin of one device is connected to the RX pin of the other device, and vice versa. UART transmits data in serial form, meaning it sends data one bit at a time over the TX line.
Key Features of UART Communication:
- Asynchronous Communication: Unlike synchronous protocols, UART does not require a shared clock signal between the transmitter and receiver. Instead, each device has its own clock and uses agreed-upon timing (baud rate) to match the speed of data transmission.
- Full-Duplex Communication: UART enables simultaneous bidirectional communication, allowing data to be transmitted and received at the same time.
- Baud Rate: This is the speed at which data is transmitted, measured in bits per second (bps). Both devices in UART communication need to operate at the same baud rate (e.g., 9600, 115200 bps) to ensure data integrity.
- Data Frames: Data is transmitted in frames, each typically consisting of a start bit, data bits, an optional parity bit, and one or more stop bits. The start and stop bits define the start and end of each data packet, ensuring the receiving device recognizes each complete data set.
- Parity (optional): Used for error checking, the parity bit allows the detection of simple errors by counting the number of 1s in the data bits.
Let’s give the simple idea of parity bit. why the parity bit is using? The thing is it is going to check whether the data bits is right or wrong how could it be check. There is two types parity bits either even or odd parity
Even parity: If the number of once in the data bit is even number it is called “even parity”
Odd parity: If the number of once in the data bit is odd number it is called “odd parity“
Key Uses and Applications of UART
UART has a variety of applications, primarily in embedded systems, where it is used for simple, reliable communication between devices. Some common use cases include:
- Microcontroller Communication:
- UART is commonly used to send and receive data between microcontrollers, modules, and sensors. For instance, it’s used to connect GPS modules, GSM modules, and Bluetooth modules with microcontrollers like Arduino, STM32, and ESP32.
- Debugging and Development:
- UART provides a reliable method to interface with development boards during testing and debugging. The communication allows developers to send debug messages to a computer to monitor system status and troubleshoot issues.
- PC-Peripheral Communication:
- UART is often used to establish serial communication between PCs and peripheral devices like printers, modems, and mice. This serial connection has long been used for connecting computers to terminals and modems due to its simplicity and low overhead.
- Serial Terminals and Consoles:
- Many devices, especially those without graphical interfaces, use UART for terminal access, allowing engineers to interact with the device using text-based commands for configuration, control, and status monitoring.
- Firmware Uploads and Flashing:
- UART interfaces are used in embedded devices for uploading firmware, where engineers use serial connections to update the software on microcontrollers and other embedded components.
How UART Works: Asynchronous Serial Communication
In UART communication, data is transmitted asynchronously, meaning that the sending and receiving devices do not use a shared clock to synchronize data transmission. Instead, the devices agree on certain communication parameters ahead of time, such as the baud rate (speed of data transmission), the number of data bits, and the presence of a parity bit.
- Serial Data Transmission:
- UART transmits data serially, sending one bit after another in a sequential stream. This approach differs from parallel communication, where data is transmitted across multiple wires simultaneously. Serial transmission conserves space and cost because fewer lines are required.
- Independent Clock Signals:
- Unlike synchronous protocols (e.g., SPI), where a clock signal is shared between devices to keep the data transmission in sync, UART relies on each device’s internal clock and timing. This is why baud rate accuracy is crucial in UART communication: both devices must stay in sync over a single line without needing external clocking.
Key Elements of UART Communication
To successfully send data, UART relies on the following components to frame the data correctly:
- Baud Rate
- The baud rate is the rate at which data bits are transmitted over the UART line, measured in bits per second (bps). Common baud rates are 9600, 19200, and 115200 bps, although many other rates exist.
- Both the transmitter and receiver must be set to the same baud rate to communicate effectively. Mismatched baud rates can lead to misinterpreted data or failed communication.
- In practice, both devices use slightly different clock frequencies, so they synchronize based on the initial start bit and remain synchronized long enough to process each data frame.
- Start Bit
- The start bit signals the beginning of a new data frame. When no data is being sent, the line remains idle (high voltage). The start bit tells the receiving device to look out for an incoming data frame, transitioning from idle (high) to low, signaling that data transmission has started.
- The start bit ensures that the receiving device knows exactly when to start reading each bit in the data frame.
- Data Bits
- Data bits are the actual data payload of the UART frame, typically ranging from 5 to 9 bits. In most applications, 8 data bits are used, but UART allows configurable data sizes to accommodate various use cases.
- The data bits carry the information being transmitted, with each bit in the data field being read sequentially after the start bit.
- Parity Bit (Optional)
- The parity bit is a form of error-checking mechanism. It allows for simple error detection by determining if the number of 1s in the data frame is even or odd.
- Even parity: The parity bit is set so that the total number of 1s in the frame (data bits + parity bit) is even.
- Odd parity: The parity bit is set so that the total number of 1s in the frame (data bits + parity bit) is odd.
- If the parity bit is not used, it is called no parity. Parity is not a guarantee of error detection but adds a layer of basic verification.
- The parity bit is a form of error-checking mechanism. It allows for simple error detection by determining if the number of 1s in the data frame is even or odd.
- Stop Bit(s)
- The stop bit indicates the end of a data frame, giving the receiver time to process the incoming data and prepare for the next frame.
- Stop bits can be 1, 1.5, or 2 bits long, with most systems using 1 stop bit. The stop bit returns the line to its idle state (high) after the data bits and optional parity bit have been read.
- The duration of the stop bit(s) helps with signal stability by providing a buffer between frames.
Data Frames in UART
The UART data frame is the structure that encapsulates each data packet sent over UART. Here’s a typical UART frame layout:
| Start Bit | Data Bits (5-9) | Parity Bit (optional) | Stop Bit(s) |
For example, a common UART data frame might look like this with 8 data bits, no parity, and 1 stop bit:
| 1 Start Bit | 8 Data Bits | 1 Stop Bit |
Each frame begins with the start bit, followed by the data bits (e.g., 8 bits for a standard byte), an optional parity bit, and finally the stop bit(s).
Step-by-Step Data Transmission Process
- Idle State:
- In an idle state, the data line remains at a high (1) logic level.
- Start Bit Transmission:
- To initiate a transmission, the transmitter pulls the line low (0) for one bit duration, signaling the start of a frame.
- The receiver detects this low signal and starts sampling bits at predefined intervals based on the baud rate.
- Data Bit Transmission:
- The transmitter sends the data bits one by one, from the LSB to the MSB. The receiver samples each bit at the baud rate intervals.
- Both devices must be configured to the same baud rate to ensure accurate timing and sampling.
- Parity Bit Transmission (If Enabled):
- After the data bits, the transmitter sends the parity bit (if parity is enabled), allowing the receiver to check for errors.
- The receiver compares the calculated parity with the transmitted parity to detect possible errors.
- Stop Bit Transmission:
- The transmitter sends one or more stop bits (high level) to signify the end of the frame.
- This high signal helps the receiver reset and prepare for the next frame or return to idle if no more data is incoming.
Reception Process
- Start Bit Detection: The receiver continuously monitors the line. When it detects a transition from high to low, it recognizes the start bit.
- Sampling Data Bits: Once the start bit is detected, the receiver samples the data bits at precise intervals based on the baud rate. Accurate timing is essential to ensure each bit is captured correctly.
- Parity Check (If Enabled): If a parity bit is present, the receiver checks it against its own calculated parity to detect any errors.
- Stop Bit Detection: The receiver checks for a stop bit at the end of the data frame. The absence of a stop bit or an incorrect value can indicate a framing error.
- Data Interpretation: Once the entire frame is received, the receiver processes the data bits, reconstructing the byte or word of data sent by the transmitter.
Timing and Baud Rate
- Baud Rate: The baud rate defines the number of bits transmitted per second. For example, a baud rate of 9600 means 9600 bits per second. Both transmitter and receiver must be configured to the same baud rate to synchronize correctly.
- Timing in Asynchronous Communication: Since UART is asynchronous, there’s no clock line. Timing is crucial for accurate data transmission, relying on the start bit to align the receiver’s sampling rate.
- Bit Duration: Each bit occupies a specific time slot, calculated as 1/baud rate. For example, at a 9600 baud rate, each bit is 1/9600 seconds or about 104.17 microseconds.
Example: Understanding a UART Frame with an ASCII Character
Suppose you want to send the ASCII character A
(which is 01000001 in binary) using UART:
- Set the baud rate (e.g., 9600 bps).
- Frame structure:
- Start bit: 0
- Data bits: 01000001 (binary representation of
A
) - Parity bit (optional, depending on configuration)
- Stop bit: 1
The full UART frame to transmit the ASCII A
might look like:
| Start (0) | 01000001 | Stop (1) |
The receiver interprets this frame, knowing where each bit starts and ends, thanks to the start and stop bits and pre-agreed baud rate.
Feature | UART | I2C | SPI |
---|
Clock Type | Asynchronous | Synchronous | Synchronous |
Number of Wires | 2 (TX, RX) | 2 (SDA, SCL) | 4+ (MOSI, MISO, SCK, SS) |
Speed | Moderate (up to 1 Mbps) | Low-Moderate (up to 3.4 Mbps) | High (up to 50 Mbps+) |
Data Direction | Full-duplex | Half-duplex | Full-duplex |
Multi-Device Support | Limited (usually 2 devices) | Yes, multiple devices | Limited by SS lines |
Error Checking | Basic (optional parity) | ACK/NACK | No native error-checking |
Common Applications | Debugging, basic peripherals | Sensors, EEPROMs, RTCs | High-speed sensors, SD cards, displays |
UART Pin Configurations
UART communication typically involves three main pins: TX (Transmit), RX (Receive), and GND (Ground). Additionally, for systems requiring flow control to manage data transmission, optional RTS (Request to Send) and CTS (Clear to Send) pins are often used. Here’s a detailed look at each:
1. TX (Transmit)
- Purpose: The TX pin is responsible for transmitting data from the device. It sends out the data bits to be received by the RX pin on the connected device.
- Direction: Output – Data goes out from the device’s TX pin to the other device’s RX pin.
- Connection: The TX of one device is connected to the RX of the other device. This cross-connection is essential for communication.
- Role in Communication: When data is to be sent, the TX pin converts parallel data from the system into a serial format and transmits it bit by bit, starting with the start bit, followed by data bits, an optional parity bit, and stop bits.
2. RX (Receive)
- Purpose: The RX pin receives data sent by the TX pin of the other device. It is where incoming data frames are captured and then processed by the device.
- Direction: Input – Data flows into the device’s RX pin from the other device’s TX pin.
- Connection: Connect the RX pin of a device to the TX pin of the other device.
- Role in Communication: The RX pin reconstructs each incoming data frame by reading the start, data, parity, and stop bits in sequence. The device then interprets this data according to the UART configuration.
3. GND (Ground)
- Purpose: The GND (Ground) pin establishes a common reference voltage between the two devices, which is critical for reliable communication.
- Role in Communication: Without a shared ground, the devices would not have a common reference for signal voltages, leading to misinterpretation of high and low states and potential errors.
- Connection: The GND of both devices must be connected to each other to synchronize the voltage levels. This pin doesn’t carry data but is essential for maintaining signal integrity.
Optional UART Flow Control Pins
In applications requiring reliable data flow without data loss, flow control pins like RTS and CTS are added to manage transmission. This is useful when dealing with high data rates or devices with limited buffer capacities.
4. RTS (Request to Send)
- Purpose: RTS is an output signal generated by the transmitting device to indicate that it is ready to send data. This pin tells the receiving device to prepare for data transmission.
- Role in Communication: When the RTS line is active (typically low), it signals the other device to get ready to receive data. If the receiving device cannot process more data (due to a full buffer, for example), it can delay the transmission by deactivating CTS.
- Connection: Connect the RTS of the transmitting device to the CTS of the receiving device.
5. CTS (Clear to Send)
- Purpose: CTS is an input signal that informs the transmitting device that the receiving device is ready to accept data. It effectively provides feedback to the transmitter to begin or continue transmission.
- Role in Communication: When the receiving device’s CTS is active (typically low), it signals that it can accept more data. If inactive (high), it indicates that the receiver needs a pause due to buffer limitations or processing delays.
- Connection: Connect the CTS pin of the transmitting device to the RTS pin of the receiving device.
Error Detection and Handling in UART
UART communication is asynchronous and relatively simple, but it does encounter errors, especially when data is transmitted over long distances or in electrically noisy environments. The most common errors in UART communication are framing errors, parity errors, and overrun errors. Understanding these errors and the mechanisms to handle them helps improve communication reliability.
1. Framing Errors
Cause:
- A framing error occurs when the expected stop bit is not found at the end of a data frame. This can happen if the baud rates between the transmitter and receiver don’t match or if there is noise on the line that distorts the signal.
Symptoms:
- The receiver detects a different bit pattern from what was expected, resulting in corrupted data or missing frames.
- Framing errors often lead to incomplete data and synchronization issues.
Detection:
- Most UART modules on microcontrollers have a Framing Error (FE) flag in the UART status register. When a framing error occurs, this flag is set, indicating that the stop bit was not detected as expected.
Handling:
- Resynchronize Baud Rate: If framing errors are frequent, verify and match the baud rates on both devices. If possible, lower the baud rate to reduce noise susceptibility.
- Clear the Error Flag: To continue communication, the FE flag should be cleared. In many microcontrollers, reading the UART data register or reinitializing the UART module can clear the error.
- Error Recovery Strategy: In software, discard frames with framing errors and, if necessary, resend or request retransmission from the other device.
- Use Additional Stop Bits: Setting two stop bits instead of one can provide additional time for synchronization, improving the receiver’s ability to detect the stop bit reliably, especially in noisy environments.
2. Parity Errors
Cause:
- Parity errors occur when the parity bit, which checks for single-bit errors in the data frame, does not match the expected parity. Parity is an optional feature in UART and can be set to even parity, odd parity, or no parity.
- This error is often due to bit flips caused by noise or electrical interference on the line.
Symptoms:
- Incorrect or missing data, particularly if the communication environment is noisy or if there are frequent voltage spikes.
- If the parity error is not handled, the data frame containing the error may be interpreted incorrectly, causing potential errors in downstream processing.
Detection:
- The UART module has a Parity Error (PE) flag in the status register that is set whenever the received parity bit does not match the expected value.
Handling:
- Verify Parity Settings: Ensure both the transmitter and receiver are configured with the same parity setting. A mismatch will cause constant parity errors.
- Error Correction Strategy: In software, discard frames with parity errors. Request retransmission if the protocol allows.
- Clear the Error Flag: On many microcontrollers, the PE flag must be cleared by reading the status register or the data register.
- Disable Parity if Not Critical: If parity checking isn’t crucial to your application, disabling it can simplify communication and reduce potential errors.
3. Overrun Errors
Cause:
- Overrun errors occur when the UART receiver’s buffer is full and cannot store incoming data. This happens when data is received faster than it is processed, leading to data loss.
- Overrun errors are common in applications where data is sent at high baud rates without sufficient buffering or interrupt handling.
Symptoms:
- Missing data, where some frames are dropped and not processed by the receiver.
- In some systems, the UART stops receiving further data until the overrun condition is cleared.
Detection:
- UART modules have an Overrun Error (ORE) flag in the status register, which is set when a data byte arrives while the receiver buffer is still full.
Handling:
- Enable Hardware Flow Control: Using RTS/CTS flow control prevents the transmitter from sending data when the receiver’s buffer is full, effectively preventing overrun errors.
- Use Interrupts or DMA: Configure the UART receiver to use interrupts or Direct Memory Access (DMA), allowing data to be processed and moved quickly from the UART buffer to memory.
- Clear the Error Flag: The ORE flag should be cleared by reading the UART status register and the data register, ensuring the UART buffer is ready to receive more data.
- Lower Baud Rate: If overrun errors persist, reducing the baud rate can give the system more time to handle each data byte before the next arrives.
Setting Up UART on STM32 Microcontrollers
1. Configuring UART Registers Directly
For more control, you can configure the UART peripheral registers directly.
Step-by-Step Guide (Direct Register Access)
- Enable UART Clock:
- Enable the clock for the UART peripheral (e.g., USART2) by setting the appropriate bit in the RCC (Reset and Clock Control) register.
RCC->APB1ENR |= RCC_APB1ENR_USART2EN; // Enable USART2 clock
2. Configure UART Baud Rate:
Set the UART baud rate by configuring the USART_BRR
register. Calculate this based on the peripheral clock and desired baud rate.
USART2->BRR = SystemCoreClock / 9600; // Set baud rate to 9600
3. Configure UART Control Register:
Enable the transmitter and receiver by setting the TE
and RE
bits in USART_CR1
Set the desired word length, parity, and stop bits in the USART_CR1
register.
USART2->CR1 = USART_CR1_TE | USART_CR1_RE; // Enable transmitter and receiver
4. Enable UART:
Set the UE
(USART Enable) bit in USART_CR1
to enable UART.
USART2->CR1 |= USART_CR1_UE; // Enable USART
2. Setting Up UART on Arduino
Arduino provides a much simpler UART setup process, as it includes a built-in Serial
library. Most Arduino boards have a single UART, but some have multiple UARTs (e.g., Arduino Mega).
Step-by-Step Guide (Arduino)
- Initialize Serial Communication:
- In the Arduino
setup()
function, initialize UART communication with theSerial.begin()
function, which sets the baud rate.
- In the Arduino
void setup() {
Serial.begin(9600); // Set baud rate to 9600
}
2. Transmit Data over UART:
Use the Serial.print()
or Serial.println()
function to send data from the microcontroller to the UART serial monitor or another device.
void loop() {
Serial.println("Hello, UART!"); // Transmit a message
delay(1000); // Delay for 1 second
}
3. Receive Data over UART:
Use Serial.available()
to check if data is in the receive buffer. If data is available, read it with Serial.read()
.
void loop() {
if (Serial.available() > 0) {
char received = Serial.read(); // Read a byte from UART
Serial.print("Received: ");
Serial.println(received); // Echo the received data
}
}
4. Multiple UARTs on Arduino Mega:
If using Arduino Mega or similar, use Serial1
, Serial2
, or Serial3
to access additional UART interfaces.
void setup() {
Serial.begin(9600); // UART0
Serial1.begin(9600); // UART1
}
void loop() {
Serial.println("Using UART0");
Serial1.println("Using UART1");
delay(1000);
}
Common Issues and Debugging UART
Issue | Symptoms | Solution |
---|
Mismatched Baud Rates | Garbled or missing data | Match baud rates, use standard rates |
Noisy Signal Lines | Corrupted or lost data | Use shielding, reduce baud rate, add capacitors |
Incorrect Logic Levels | No data or garbled communication | Use level shifters, check voltage compatibility |
Overrun Errors | Lost data frames | Enable flow control, clear ORE flag |
Stop/Parity Mismatch | Framing/parity errors | Ensure same stop bits and parity settings |
Faulty Connections | Sporadic data loss | Check connections, use soldered joints |
Applications and Real-World Examples of UART
UART (Universal Asynchronous Receiver-Transmitter) is commonly used in embedded systems and devices where straightforward, serial communication is required. Below are key real-world applications of UART, with a focus on practical modules and devices.
1. GPS Modules
- Use Case: UART is widely used in GPS modules to send satellite data to a microcontroller or a computer. These modules continuously transmit latitude, longitude, altitude, and time data in NMEA (National Marine Electronics Association) sentences.
- Example: GPS modules like the NEO-6M use UART to connect with microcontrollers such as Arduino or STM32. The module streams data at a set baud rate (e.g., 9600 bps), which the microcontroller reads, parses, and uses for navigation or tracking.
2. Bluetooth Modules
- Use Case: Bluetooth modules, especially for basic data transmission, commonly use UART. This allows for simple wireless data exchange between devices such as phones, computers, and microcontrollers.
- Example: The HC-05 Bluetooth module uses UART to communicate with microcontrollers. Data sent from a microcontroller over UART is wirelessly transmitted to paired Bluetooth devices, enabling remote control or monitoring applications, such as wireless sensor networks and remote-controlled robots.
3. Debugging and Console Interfaces
- Use Case: UART serves as a debugging interface for many embedded systems, allowing developers to send diagnostic messages to a console or terminal.
- Example: Development boards like Raspberry Pi and STM32 microcontrollers commonly use UART for debugging. By connecting a UART cable from the microcontroller to a computer, developers can log output, monitor system states, and troubleshoot issues via serial communication.
4. Communication with Sensors and Actuators
- Use Case: Many sensors and actuators use UART for data transmission, particularly when they need to send formatted data over serial communication channels.
- Example: Some temperature and humidity sensors (e.g., DHT22) can transmit data using UART, making it easy to integrate with microcontrollers for monitoring applications. Ultrasonic sensors for distance measurement can also use UART to send precise distance data to microcontrollers in applications like robotic navigation.
5. Microcontroller-to-Microcontroller Communication
- Use Case: UART enables communication between multiple microcontrollers for synchronized operations, data sharing, or load distribution.
- Example: In complex systems where tasks are split among microcontrollers (e.g., in robotics or automation), UART links them. One microcontroller might handle sensor inputs while another handles motor control, and they exchange status and command data over UART.
6. Display Interfaces
- Use Case: Displays like LCDs and LED screens use UART to receive commands and data from a controlling microcontroller.
- Example: Some serial LCDs and OLED displays use UART, simplifying wiring by allowing the display to receive both power and data over a few connections. These displays are often used in kiosks, meters, and embedded devices with limited interface requirements.
7. Wireless Communication Modules
- Use Case: Many wireless transceivers (e.g., LoRa, Zigbee) use UART to exchange data with microcontrollers, supporting long-range communication or networked sensor applications.
- Example: LoRa modules like SX1278 connect with microcontrollers over UART, providing long-range, low-power communication in IoT applications such as environmental monitoring, smart agriculture, and asset tracking.
8. USB-to-Serial Converters
- Use Case: USB-to-UART converters provide a bridge between USB ports on computers and UART-based devices.
- Example: Adapters like the FT232 and CP2102 convert USB signals to UART, allowing laptops or computers to communicate with UART-based microcontrollers, sensors, and other devices. These adapters are essential for interfacing with devices that lack a USB port directly.
9. Point-of-Sale (POS) and Industrial Equipment
- Use Case: UART is frequently used in industrial equipment and POS systems for simple, direct communication with peripheral devices.
- Example: Barcode scanners, receipt printers, and card readers often use UART to send data to POS systems in retail environments. In industrial settings, UART can interface with equipment like sensors, actuators, and logging systems for monitoring or control purposes.
10. Modems for Telecommunications
- Use Case: Modems use UART to transmit and receive data over telecommunication lines.
- Example: In cellular or GSM modules, such as the SIM800L, UART is used to send AT commands and receive data from the network. This allows microcontrollers to perform tasks like SMS sending, data connectivity, and calls, which are essential for remote and IoT applications.