UART is an asynchronous serial protocol — no shared clock. Both sides agree on a baud rate in advance. An idle line is held HIGH (logic 1). Each frame begins with a start bit (LOW), followed by 7–9 data bits (LSB first), optional parity bit, and one or two stop bits (HIGH).
Parity: Even parity — total number of 1 bits (including parity) is even. Odd parity — total is odd. Detects single-bit errors only.
SPI is a synchronous, full-duplex protocol using 4 lines: SCK (clock), MOSI (master out), MISO (master in), CS/SS (chip select, active LOW). Data is sampled on one clock edge and shifted on the other — determined by the mode (CPOL/CPHA).
SPI is faster than I²C and UART (up to hundreds of MHz) but requires more wires. Multiple slaves share SCK/MOSI/MISO; each slave has its own CS line.
I²C uses two open-drain lines (with pull-up resistors): SDA (data) and SCL (clock). The master generates the clock and initiates transactions. Up to 128 (7-bit) or 1024 (10-bit) devices share the same bus.
Start condition: SDA falls while SCL is HIGH. Stop condition: SDA rises while SCL is HIGH. Data is valid when SCL is HIGH (changed when SCL is LOW). After each byte, the receiver pulls SDA LOW during the 9th clock pulse to send ACK; if it stays HIGH, that is NACK.
| Feature | UART | SPI | I²C |
|---|---|---|---|
| Synchronous? | No (async) | Yes | Yes |
| Wires | 2 (TX, RX) | 4+ (SCK, MOSI, MISO, CS×n) | 2 (SDA, SCL) |
| Max devices | 2 (point-to-point) | Unlimited (one CS each) | 128 (7-bit) / 1024 (10-bit) |
| Full duplex? | Yes | Yes (simultaneous) | No (half-duplex) |
| Typical speed | up to ~1 Mbps | up to ~100 MHz | 100 kHz – 3.4 MHz |
| Addressing | None (dedicated wire) | None (CS pin per device) | 7-bit or 10-bit address |
| Error detection | Optional parity bit | None built-in | ACK/NACK only |
| Hardware complexity | Simple | Moderate | Moderate (pull-ups needed) |
| Typical use | Debug consoles, GPS, Bluetooth, RS-232 | Flash, SD cards, ADCs, displays | Sensors (temp, IMU), EEPROMs, RTCs |
| Pull-up resistors? | No | No | Required (on SDA & SCL) |
| Clock stretching | N/A | N/A | Supported by slave |
| Long-distance? | RS-232 up to 15m; RS-485 up to 1.2km | Short (high-speed, board-level) | Short (board-level, <1m typical) |
UART: Simple two-device communication, debug output, connecting to legacy serial equipment (GPS modules, RS-232). No clock signal, so both sides must agree on baud rate. Easy to implement in software ("bit-bang").
SPI: Fast data transfer to a single peripheral (SD card, external flash, high-speed DAC/ADC). Needs more pins for multiple devices but supports very high clock rates. Best for applications where speed matters more than pin count.
I²C: Multiple sensors on a single bus with minimal wiring. Ideal for slow peripherals (temperature sensors, IMUs, EEPROMs) where you need many devices but speed is not critical. Requires careful pull-up resistor selection based on bus capacitance.