UART Serial Communication Explained: Framing, Timing, and Hardware Design
A deep dive into the ubiquitous UART interface, its asynchronous timing mechanism, electrical layers, and critical design considerations for robust data transmission.
UART (Universal Asynchronous Receiver/Transmitter) is the workhorse “serial port” found in almost every embedded system. Unlike synchronous buses like I²C or SPI, UART is asynchronous—there is no shared clock. The receiver reconstructs timing from the start bit and its own local clock, which is why baud-rate accuracy and framing settings matter so much.
UART is commonly used for debug consoles, bootloaders, GPS modules, radio modems, and “just get bytes from A to B” links. When it fails, the root cause is almost always one of these: wrong voltage levels, wrong framing (8N1 vs 7E1/8E1, etc.), baud mismatch, inverted polarity (RS-232 vs TTL), or flow control unexpectedly enabled.
🧠UART vs. USART vs. “Serial”
You’ll see these terms used interchangeably, but they aren’t identical:
- UART: the asynchronous framing engine (start bit, data bits, optional parity, stop bit).
- USART: a UART that can also run in a synchronous mode (clocked). Many MCU peripherals are called USARTs even if you only use the UART mode.
- “Serial”: informal shorthand that can mean TTL UART, RS-232, a USB virtual COM port, or even higher-level serial protocols—always check the electrical interface.
🚦 Core UART Signals (The "3-Wire" Interface)
A minimal UART connection requires only three wires: Transmit (TX), Receive (RX), and a common Ground (GND). It is a point-to-point interface, typically connecting two devices directly.
1. TX (Transmit)
- Function: Output pin. Carries data from the device to the remote receiver.
- Idle State: HIGH (logic 1) in standard TTL UART.
- Drive: Push-pull driver (can source and sink current).
2. RX (Receive)
- Function: Input pin. Receives data from the remote transmitter.
- Impedance: High-impedance input (Hi-Z).
- Note: Never leave a floating RX pin if the UART peripheral is enabled; noise can trigger false "start bits". Ideally, use a weak pull-up.
3. GND (Ground)
- Function: Provides the common voltage reference.
- Criticality: Without a common ground, the logic levels (0V/3.3V) have no reference, leading to garbage data or no communication.
📦 Frame Format: The "8N1" Standard
Since there is no clock line to say “sample now”, UART uses a strict frame structure. In a non-inverted (TTL) UART, the line stays HIGH (idle) until a transaction begins. The receiver detects the falling edge of the start bit and uses that edge to align its sampling clock.
Standard Frame Components
- Start Bit: Always 1 bit, logic 0 (Low). It synchronizes the receiver.
- Data Bits: Usually 8 bits (can be 5-9). Sent LSB First.
- Parity Bit (Optional): A simple error-detection bit (odd/even are common).
- Stop Bit(s): Logic 1 (High). Returns the line to idle. Commonly 1 bit; 1.5 and 2 stop bits exist for compatibility/legacy use.
"115200 8N1"
The most common configuration shorthand:
- 115200 : Baud rate (bits/sec)
- 8 : Data bits
- N : No parity
- 1 : One stop bit
Parity is often abbreviated as N (none), E (even), or O (odd). Some UARTs also support mark (parity bit always 1) and space (parity bit always 0), which can be useful for legacy protocols.
Also remember: baud rate is not throughput. With 8N1, you spend 10 bits on the wire for every 8 data bits, so payload efficiency is 80% (a 25% overhead).
⏱️ Baud Rate & The "Clock Error Budget"
UART works because the receiver measures the start-bit edge, then samples each subsequent bit at a fixed interval based on its local clock. If the transmitter is slightly fast and the receiver is slightly slow (or vice versa), the sampling point drifts over the frame. Too much drift and the stop bit won’t land where the receiver expects it.
How much mismatch is “OK”?
With 8N1, you have roughly half a bit-time of sampling margin across the whole frame, so the theoretical combined baud mismatch limit can be on the order of a few percent. Real systems need margin for noise, edge distortion, interrupt latency, and longer frames.
- Good target: keep combined mismatch (|TX error| + |RX error|) around ≤ 2% when you can.
- Longer frames reduce margin: parity and extra stop bits increase drift time.
- Oversampling helps (often 8×/16×), but it can’t compensate for large baud errors.
How to sanity-check baud error
UARTs generate baud from a clock divider. Some dividers are fractional, some are integer-only. You can estimate the error with:
baud_error(%) = (actual_baud - target_baud) / target_baud × 100 - Internal RC oscillators: often the culprit (temperature/voltage drift). Prefer a crystal/TCXO for “it must always work” links.
- Divider rounding: some baud rates are “easy” with your clock, others aren’t. Check the MCU’s reference manual or HAL calculator output.
- Edge distortion: long cables + noise can move threshold crossings and shrink timing margin.
Flow Control (RTS / CTS)
When transferring large amounts of data, the receiver's buffer might fill up. Flow control allows the receiver to say "Stop!" before data is lost.
Hardware Flow Control
Uses two extra wires. This is the robust, preferred method when you can spare GPIOs and you’re streaming data continuously.
- RTS: output that throttles the other side (often “I’m ready to receive / pause sending”). Polarity and exact meaning depend on the device/driver.
- CTS: input that tells your transmitter whether it is allowed to send.
If you see “nothing prints” but the wiring looks right, check whether one side has flow control enabled and the other doesn’t—some UART stacks will refuse to transmit without CTS asserted.
Software Flow Control (XON/XOFF)
No extra wires. Sends special ASCII characters (0x11 XON / 0x13 XOFF) in the data stream.
Warning: Dangerous for binary data (images, compiled code) because a random byte might look like XOFF and freeze the connection.
Other “serial” control pins
Classic RS-232 ports also expose DTR/DSR, DCD, and RI. Many USB-UART adapters break these out too. They’re not part of UART framing, but they can be used for reset/boot straps or modem-style signaling.
Electrical Standards: TTL vs. RS-232 vs. RS-485
“UART” describes the protocol framing, but not the voltage. Connecting incompatible electrical layers can damage hardware (and is one of the most common causes of “my serial doesn’t work”).
| Standard | Voltage Levels | Logic | Topology |
|---|---|---|---|
| TTL UART | 0V to 3.3V (or 5V) | Active High (1=VCC) | Point-to-Point (Short) |
| RS-232 | ±3V to ±15V | Inverted (1 = Negative) | Point-to-Point (Longer) |
| RS-485 | Differential (wide common-mode range) | Differential | Multi-drop Bus |
Logic-level (TTL) UART
- Usually 3.3 V or 5 V CMOS levels, non-inverted.
- Keep it short and local (on-board, short cable, dev headers).
- Level shifting: a 5 V TX → 3.3 V RX often needs a divider or level shifter; the reverse is often OK but depends on input thresholds—check the datasheet.
RS-232
- Higher voltages (typically positive and negative swings) and inverted polarity.
- Use a proper transceiver (e.g., MAX3232-class) between MCU UART pins and an RS-232 connector.
- Great for point-to-point links with classic equipment and longer cables than TTL UART.
RS-485
- Differential signaling, tolerant to noise and ground shifts; supports multi-drop buses.
- Often half‑duplex: you may need DE/RE direction control in addition to TX/RX.
- Requires proper termination and biasing on long buses. See the RS-485 termination & bias planner.
PCB Layout & Routing Best Practices
While UART is slow compared to USB or Ethernet, signal integrity still matters, especially in noisy industrial environments.
- Series Resistors: Place a 22Ω to 100Ω resistor in series with the TX line, close to the MCU. This dampens ringing and reduces EMI (UART edges can be surprisingly sharp).
- ESD Protection: If the UART lines go to a connector (for external logging/debug), add TVS diodes. This is the #1 way developers blow up MCU pins.
- Return Path: Ensure a solid ground connection runs parallel to the TX/RX lines. Do not route UART across gaps in the ground plane.
- Crosstalk: Avoid routing TX and RX parallel for long distances without a ground trace between them, or they might couple into each other.
- Make it debuggable: Add labeled test pads (TX, RX, GND) and keep the connector pinout consistent across boards. It saves hours when you need a serial console in the field.
Pros & Cons Summary
Advantages
- Simplicity: Only two data wires + ground, and no clock signal to manage.
- Hardware Support: Available on almost every MCU, module, and PC (via USB).
- Distance: With transceivers (RS-485), can go hundreds of meters.
- Debugging: Human-readable ASCII is easy to debug.
Disadvantages
- Speed: Generally slower than SPI for on-board links. Common rates are 9.6 kbaud to a few Mbaud; some MCUs and short traces can go higher.
- Critical Timing: Requires accurate clocks on both ends.
- Point-to-Point: Basic UART is not a bus; addressing isn't built-in.
- Overhead: Framing adds overhead (8N1 is 10 bits per byte ⇒ 25%).
Common Pitfalls & Debugging
- TX/RX Swap: The classic error. If it doesn't work, swap the lines.
- Baud Rate Mismatch: If you see garbage characters, one side is likely at the wrong speed (e.g., 9600 vs 115200).
- Wrong Framing: 8N1 vs 7E1/8E1/8O1 mismatches often look like “almost readable, but wrong”.
- Missing Ground: If characters appear randomly or system resets, check the common ground.
- Level Mismatch: Logic-level UART is not RS-232. A 5 V TX into a 3.3 V RX can damage the input—use a divider/level shifter.
- Floating Input: If you receive random data when nothing is connected, your RX pin is floating. Enable the internal pull-up resistor.
- Inverted Polarity: RS-232 (and some “inverted UART” modules) flips logic. If your UART supports inversion, try it—or use the correct transceiver.
- Flow Control Stalls: If RTS/CTS is enabled on one side, the other must drive the pins correctly or transmission may stop completely.
- Use a loopback test: Short TX to RX on a USB-UART adapter. If the terminal echoes, the adapter and settings are OK.
- Use a logic analyzer: Being able to see the start bit, bit time, and idle level is often faster than guessing.
References & Further Reading
- "The Art of Electronics" (Horowitz & Hill) - Chapter on digital communication.
- MCU reference manuals/datasheets (STM32, AVR, ESP32, etc.) - “UART/USART” peripheral sections and baud-rate generator details.
- RS-232 and RS-485 physical-layer specs (TIA/EIA-232, TIA/EIA-485) and vendor application notes.
- USB-UART bridge notes (FTDI, Silicon Labs, WCH) and driver documentation.
Related tools & guides
- WebSerial ConsoleTool
Connect to your UART devices directly from the browser for debugging.
- RS-485 PlannerTool
Calculate termination and bias for industrial UART links.
- I²C Communication GuideGuide
Compare UART with the synchronous I²C bus for on-board chips.
- SPI Interface GuideGuide
Learn about high-speed synchronous serial communication.