UART vs SPI vs I2C
UART, SPI, and I2C are the three most common serial protocols for embedded systems. Each was designed for a different use case: UART for point-to-point asynchronous links, SPI for high-speed peripheral buses, and I2C for multi-device communication over two wires. Choosing the right one depends on speed, pin count, and topology.
UART (Universal Asynchronous Receiver/Transmitter)
UART is a point-to-point asynchronous serial protocol using separate TX and RX lines. No shared clock — both sides must agree on baud rate. Standard speeds from 9600 to 4 Mbps. Used for debug consoles, GPS modules, and Bluetooth modules.
Advantages
- Simple hardware — just two wires (TX, RX)
- No clock signal required — asynchronous operation
- Universally supported — nearly every MCU has a UART
- Works over long cables and is easy to debug with a terminal
Disadvantages
- Point-to-point only — no native multi-device bus
- Both sides must agree on baud rate — misconfiguration causes garbled data
- Lower speed than SPI for bulk transfers
- Requires framing bytes and start/stop bits — ~20% overhead
When to use
Use UART for point-to-point links: GPS receivers, Bluetooth/WiFi modules, debug logging, and industrial devices with RS-232/RS-485. Ideal when simplicity and long-range communication matter more than speed.
I2C (Inter-Integrated Circuit)
I2C is a two-wire bus protocol (SDA + SCL) supporting multiple masters and up to 127 devices on a single bus. Standard speeds: 100 kbps, 400 kbps, 1 Mbps (Fast+), 3.4 Mbps (High Speed). Uses 7-bit addressing.
Advantages
- Only two wires (SDA + SCL) regardless of device count
- Multi-device bus — up to 127 devices addressable
- No chip-select lines needed — addressing is in-band
- Well-suited for sensors, EEPROMs, RTCs, and display controllers
Disadvantages
- Slower than SPI for bulk data transfers
- Open-drain bus requires pull-up resistors — limits speed on long traces
- Address conflicts possible with fixed-address devices
- Not suitable for high-speed data streams
When to use
Use I2C when you have multiple slow-to-medium-speed peripherals sharing a bus and want to minimize pin count. Perfect for sensors (IMUs, temperature, humidity), EEPROMs, RTCs, and display drivers.
Key Differences
- ▸Wire count: UART = 2 (TX/RX); I2C = 2 (SDA/SCL, shared bus); SPI = 4+ (MOSI/MISO/SCK + CS per device)
- ▸Speed: SPI > I2C > UART for bulk transfers; UART is fastest for simple streaming
- ▸Topology: UART = point-to-point; I2C/SPI = multi-device bus (I2C uses addressing, SPI uses chip-select lines)
- ▸UART is asynchronous; SPI and I2C are synchronous (shared clock)
- ▸SPI is full-duplex; I2C and UART can be full-duplex (UART) or half-duplex (I2C)
Summary
Use UART for point-to-point serial links and debug/log output. Use I2C when you need to connect multiple low-speed sensors or peripherals on two wires. Use SPI when you need high-speed transfers to a single peripheral (displays, flash memory, ADCs). Pin count and speed are usually the deciding factors.
Frequently Asked Questions
Which is faster: SPI, I2C, or UART?
SPI is fastest — typical implementations run at 10–50 MHz (10–50 Mbps), limited mainly by trace capacitance. I2C tops out at 3.4 Mbps (High Speed mode). UART is typically 115.2 kbps to 4 Mbps for standard implementations.
Can I connect multiple devices on a UART bus?
Standard UART is point-to-point. RS-485 (a multi-drop extension of UART signaling) allows up to 32 nodes on a differential bus at up to 10 Mbps. Each device needs addressing at the application layer.
Why does I2C need pull-up resistors?
I2C uses open-drain signaling — devices can only pull the bus low, not high. External pull-up resistors (typically 4.7 kΩ for 100 kbps, 2.2 kΩ for 400 kbps) pull the line high when no device is driving it. The RC time constant of the pull-up and bus capacitance limits maximum speed.
What is SPI used for that I2C cannot do?
SPI is preferred for high-speed bulk data: SD cards (up to 25 MHz), SPI flash (up to 133 MHz), color displays (SPI TFT), and high-speed ADCs/DACs. I2C cannot reliably operate above 3.4 Mbps due to open-drain bus constraints.