UART Frame Format

Each UART transmission carries data inside a precisely defined frame. Understanding the purpose of every field — not just its name — is what separates a developer who can implement UART from scratch from one who only configures a vendor IP. This episode dissects the frame bit by bit, covering the transmission order convention, parity computation, and the overhead implications of different format choices.

UART Frame Structure

Every UART transmission is based on a fixed Frame structure.

  Idle  Start   D0   D1   D2   D3   D4   D5   D6   D7  Parity  Stop  Idle
───────┐                                                                ┌────
  1    │  0  │ b0 │ b1 │ b2 │ b3 │ b4 │ b5 │ b6 │ b7 │   P   │  1  │  1 |
       └─────┴────┴────┴────┴────┴────┴────┴────┴────┴───────┴──────────┘
            ←──────────────── 1 Frame ─────────────────────────────→
              1bit   ←──── 8 bits (LSB first) ────→   1bit   1bit
FieldBitsValuePurpose
Start Bit1Always 0Signals start of frame (falling edge)
Data Bits5–9DataActual data payload (LSB first)
Parity Bit0–1Even/OddOptional error detection
Stop Bit1–2Always 1Signals end of frame, returns to idle

Frame Transmission — Animated

0xA5 frame (8E1) — bits transmitted one at a time, LSB first. Watch each field highlighted in sequence.

Start Bit & Stop Bit

Start Bit

  • Line is normally High (1, Idle)
  • Transmission begins with a Low (0)Falling Edge
  • Receiver uses this falling edge to re-synchronize its timing

Stop Bit

  • Always High (1)
  • Returns the line to Idle state
  • 1 Stop bit (standard), 2 Stop bits (legacy devices, slow MCUs)
  Idle      Start      Data ...      Stop     Idle
───┐          ↓                       ↑──────────
   └──────────┘   ~~~data~~~   ───────┘
       Falling Edge                  Back to High

Data Bits & Bit Order

Data Width Options

  • 5, 6, 7, 8 bits — 8-bit is most common (ASCII, byte data)
  • 9 bits — special use (e.g., multi-drop address flag)

Transmission Order: LSB First

Data to send: 0xA5 = 1010_0101b

Bit order:   D0  D1  D2  D3  D4  D5  D6  D7
TX value:     1   0   1   0   0   1   0   1
              ↑ LSB                  MSB ↑

TX waveform: D0 → D1 → D2 → D3 → D4 → D5 → D6 → D7
  • The LSB (D0) is always transmitted first
  • For 0xA5, the first bit on the wire is: 1 (LSB)

Why LSB first? Early UART hardware used a shift register that naturally shifted bits out from the LSB end. This is opposite to the MSB-first convention most software developers expect — so always verify bit ordering explicitly in simulation waveforms before assuming the RX design is correct.

Parity Bit

Optional field for single-bit error detection

Even Parity

Set parity bit so that the total number of 1s (data + parity) is even

Odd Parity

Set parity bit so that the total number of 1s (data + parity) is odd

Data (0b10010100)Count of 1sEven ParityOdd Parity
1 0 0 1 0 1 0 03 (odd)1 (make even)0 (keep odd)
1
2
3
4
// Even parity using reduction XOR
parity_bit = ^tx_data;       // 1 if count of 1s is odd
// Odd parity
parity_bit = ~^tx_data;

Parity detects single-bit errors only. Any even number of bit errors (2, 4, …) cancel out and go undetected. For reliable data integrity over longer payloads, use a CRC checksum at the application layer.

Checksum for Multi-Byte Data

For longer payloads, use a Checksum instead of per-byte parity

Checksum Calculation Example

Data bytes: 0x12, 0x34, 0x56

Sum:  0x12 + 0x34 + 0x56 = 0x9C

Checksum (1 byte): 0x9C  (discard overflow beyond 1 byte)

Advantages over Parity

  • Block-level protection: verifies integrity of the entire data block
  • Detects multiple bit errors that simple parity cannot catch
  • Lower overhead for long transfers: one checksum per block

UART Communication Overhead

8N1 format (8 data bits, No parity, 1 stop bit) — most common configuration

$$\text{Overhead} = \frac{\text{Non-data bits}}{\text{Total bits}} = \frac{2}{10} = 20%$$

ConfigTotal BitsData BitsOverhead
8N110820%
8E111827%
8N211827%
7E110730%

Effective Throughput (115200 bps, 8N1)

$$\text{Effective throughput} = 115200 \times \frac{8}{10} = 92{,}160 \text{ bps} = 11{,}520 \text{ bytes/s}$$

Frame Format Summary

115200 bps, 8E1:

  Idle  │S│ D0 │ D1 │ D2 │ D3 │ D4 │ D5 │ D6 │ D7 │ Par│Stp│  Idle
────────┘ └────┴────┴────┴────┴────┴────┴────┴────┴────┴───┘ ──────
         │←────────────────── 8.68µs × 11 = 95.5µs ──────────────→│
         1bit              8 data bits               1bit  1bit
        (Start)                                    (Parity)(Stop)

Key Points

  • Start Bit: always 0, falling edge → timing synchronization
  • Data Bits: 8 bits, LSB first, actual payload
  • Parity Bit: even parity, detects 1-bit errors
  • Stop Bit: always 1, returns to idle

Episode 2 Summary

  • UART frame = Start(1) + Data(5–9) + Parity(0–1) + Stop(1–2)
  • Start Bit: always 0; falling edge resets receiver timing
  • Data: LSB transmitted first; 8 bits is the standard
  • Parity: even/odd for 1-bit error detection (optional)
  • Stop Bit: always 1; returns line to idle
  • 8N1 overhead: 20% (10 bits total, 8 data bits)

Next Episode

Episode 3: RS-232 & RS-485 Converting UART logic signals to physical electrical standards

Key Takeaways

  • UART frame = Start (1b, always 0) + Data (5–9b, LSB first) + Parity (1b, optional) + Stop (1–2b, always 1) — every field at exactly the right timing; missing any field causes a framing error
  • LSB-first transmission is counterintuitive for software developers — verify the bit order explicitly in simulation before signing off on the RX design
  • Even parity is the reduction XOR of all data bits: parity = ^data[7:0]; the receiver recalculates and compares on every received byte
  • 8N1 carries 20% overhead (2 framing bits per 10-bit frame); 8E1 adds 1 more bit but enables hardware parity error detection at the receiver

Code and References