UNIT 10 · LESSON 1 OF 6

Serial Data, Framing, and Synchronization

How does the receiver know?

INTERACTIVEOne byte on a UART line
The bits of one UART frame on the lineidleS00110203040506170T1idlelineS start, 0–7 data bits (bit 0 first), no parity, T stop10 bits carry 8 data bits: 80 % efficiency; at 115 200 baud that is 11 520 bytes/s
The bits of one UART frame on the lineidleS00110203040506170T1idlelineS start, 0–7 data bits (bit 0 first), no parity, Tstop10 bits carry 8 data bits: 80 % efficiency; at 115200 baud that is 11 520 bytes/s

Try this

Byte
Data bits
Parity
Stop bits
10-bit frame, 80 % efficient.

An asynchronous serial line idles high. A frame starts with one low start bit, sends the data bits least significant bit first, optionally a parity bit, and ends with one or two high stop bits. The receiver has no clock wire: it times every bit from the falling edge of the start bit.

What you will be able to do
  • Explain why serial links dominate between chips, and distinguish synchronous from asynchronous links.
  • Draw a UART frame for a byte, including start, data (least significant bit first), parity and stop bits.
  • Compute the parity bit and the useful throughput of a frame format at a given baud rate.
  • Compare ways of giving a receiver its bit timing: a clock wire, start-bit resynchronisation, Manchester coding and bit stuffing.
  • Explain what parity can and cannot detect.
Before you start
  • Logic levels (unit 1) and digital inputs and outputs (unit 7).
  • Clocks and bit rates (unit 8, lesson 1).
Steps in this lesson
  1. One bit at a time
  2. The asynchronous frame
  3. Throughput
  4. Parity
  5. Other ways to carry the timing
  6. Worked example: a GPS module at 9600 baud, 8N1
  7. Common misconceptions

The puzzle

A sensor on the same board, a GPS module on a cable, a motor controller at the far end of a machine: all of them send bytes to the microcontroller one bit at a time over a wire or two. Nothing on that wire says where one bit ends and the next begins, or where a byte starts. How does the receiver know?

STEP 1

One bit at a time

Sending eight bits side by side needs eight wires plus a strobe, and over any distance the wires’ slightly different delays smear the bits into each other. A serial link sends them one after another on one wire (or one pair), so it needs few pins, few traces and cheap cables, and it can run fast because there is no skew between parallel lines to worry about. The price is that the receiver must recover two things from the stream: bit timing (when to sample) and framing (which bits form a byte, and which bytes a message).

A synchronous link sends a clock alongside the data: SPI and I²C have a clock wire, and the receiver samples on its edges. An asynchronous link has no clock wire: a UART receiver times the bits itself, from an agreed baud rate.

STEP 2

The asynchronous frame

A UART line idles high. Each character is a frame:

  1. one start bit, low: its falling edge tells the receiver a frame has begun and starts its bit timer;
  2. 5 to 8 data bits, least significant bit first;
  3. optionally a parity bit;
  4. one or two stop bits, high, which return the line to idle and guarantee that the next start bit produces a falling edge.

The format is written data bits, parity, stop bits: 8N1 is 8 data bits, no parity, 1 stop bit, the pico-sdk’s default in uart_init().

↑ This step uses the figure at the top of the page.

A receiver that finds the stop bit low reports a framing error: the RP2040’s UART defines it as a character that “did not have a valid stop bit”. A line held low for longer than a whole frame is a break, which some protocols use deliberately as a reset or attention signal.

STEP 3

Throughput

Every frame spends bits on start, parity and stop, so the useful byte rate is lower than the baud rate divided by eight:

bytes per second=baud ratebits per frame,\text{bytes per second} = \frac{\text{baud rate}}{\text{bits per frame}}, efficiency=data bitsbits per frame\text{efficiency} = \frac{\text{data bits}}{\text{bits per frame}}

For a UART, one symbol is one bit, so the baud rate equals the bit rate. 8N1 at 115 200 baud carries 11 520 bytes per second, 80 % efficiency.

STEP 4

Parity

The parity bit makes the number of 1s in the data plus parity even (even parity) or odd (odd parity). Any single flipped bit changes the count and is detected. Two flipped bits restore it and are not: parity detects every odd number of errors in a frame and misses every even number. It is a cheap first line of defence; messages need stronger checks (lesson 6).

STEP 5

Other ways to carry the timing

INTERACTIVEHow does the receiver know when to sample?
Ways of giving a serial receiver its bit timingclockdataThe receiver samples on one edge of each clock cycle; a long run of equal bits isharmless. Costs an extra wire.
Ways of giving a serial receiver its bit timingclockdataThe receiver samples on one edge of each clockcycle; a long run of equal bits is harmless. Costsan extra wire.
Method
The receiver samples on one edge of each clock cycle.

Every serial link must tell the receiver where each bit is. A separate clock wire does it directly (SPI, I²C). An asynchronous UART re-synchronises on every start bit and relies on both ends having nearly the same baud rate. Line codes put transitions into the data itself: Manchester coding has one in every bit, and bit stuffing (used by CAN) inserts an opposite bit after five equal bits so edges never stop for long.

  • A clock wire (SPI, I²C) makes timing trivial and tolerates any clock rate, at the cost of a wire.
  • Start-bit resynchronisation (UART) needs both ends to agree on the baud rate within a few per cent, because the receiver runs freely for a whole frame (lesson 2).
  • Line codes such as Manchester put a transition in every bit, so the receiver can recover the clock from the data, at the cost of twice as many transitions.
  • Bit stuffing (CAN, USB) inserts an opposite bit after a run of equal bits so edges keep coming; CAN inserts one after five. Six equal bits then never occur in valid data, and CAN uses exactly that violation to signal errors.

STEP 6

Worked example: a GPS module at 9600 baud, 8N1

Each byte takes 10 bits, so

9600 bit/s10 bits=960 bytes/s\frac{9600\ \text{bit/s}}{10\ \text{bits}} = 960\ \text{bytes/s}

A module that sends 450 bytes of position sentences once a second uses 450 / 960 ≈ 47 % of the link. Changing the format to 8E1 adds a parity bit per byte (11 bits, 873 bytes/s) and raises the load to about 52 %. Switching the module to 38 400 baud would cut it to about 12 %, if both ends support that rate.

MYTHS AND FACTS

Common misconceptions

115 200 baud moves 14 400 bytes per second

Only if there were no start and stop bits: 8N1 gives 11 520.

Serial means slow

Serial links run from kilobits to gigabits per second; fewer wires make higher rates easier, not harder.

Parity catches corrupted bytes

Only an odd number of flipped bits; two errors in one frame pass unnoticed.

Every serial link sends the most significant bit first

UARTs send the least significant bit first; SPI devices usually send the most significant bit first (the RP2040’s SPI supports only that order).

Check yourself

Answer in your head, then open the card.

What bits appear on the line for the byte 0x41 in 8E1, in order?

Start 0; data 1, 0, 0, 0, 0, 0, 1, 0 (0x41 = 0100 0001, least significant bit first); parity 0 (two 1s, already even); stop 1.

How many bytes per second does 8N2 carry at 19 200 baud?

11 bits per frame: 19 200 / 11 ≈ 1745 bytes per second.

Why does a UART need a stop bit at all?

It returns the line to the idle (high) level, so the next start bit is always a falling edge the receiver can detect, and it lets the receiver check framing: a low stop bit means the timing or the format is wrong.

CAN nodes send long runs of identical bits in their identifiers. How do the receivers stay synchronised?

Bit stuffing: after five equal bits the sender inserts an opposite bit, which the receivers remove. The guaranteed edges let every receiver resynchronise its bit timing.

Sources (4)
  1. Raspberry Pi Ltd, pico-sdk 1.5.1, hardware_uart/uart.h — uart_set_format(uart, data_bits, stop_bits, parity): data bits 5..8, stop bits 1..2, parity none, even or odd; uart_init defaults to 8 data bits, no parity, 1 stop bit; PICO_DEFAULT_UART_BAUD_RATE 115200
  2. Raspberry Pi Ltd, pico-sdk 1.5.1, rp2040/hardware_regs/uart.h (PL011 registers) — UARTDR FE: “the received character did not have a valid stop bit (a valid stop bit is 1)”; BE: the input “held LOW for longer than a full-word transmission time (defined as start, data, parity and stop bits)”
  3. Linux kernel, Documentation/spi/spi-summary.rst — SPI’s “three signal wires hold a clock (SCK, often on the order of 10 MHz), and parallel data lines”; “Each clock cycle shifts data out and data in; the clock doesn’t cycle except when there is a data bit to shift”
  4. Zephyr Project, doc/hardware/peripherals/can/controller.rst — CAN nodes resynchronise on edges (resynchronisation jump width); an active error frame is “six consecutive dominant bits, which is a violation of the stuffing rule that all nodes can detect”