Electronics Design AU
Communications

SPI vs I2C vs UART: Which Protocol Should You Use?

Last updated 28 June 2026 · 9 min read

Direct Answer

Choose SPI when throughput matters — displays, ADCs, and flash chips all benefit from its ability to run at tens of MHz with a dedicated chip-select per device. Choose I2C when multiple peripherals must share a two-wire bus and moderate speed (up to 400 kHz or 1 MHz) is acceptable. Choose UART for point-to-point links to a single device — GPS modules, Bluetooth adapters, and debug consoles — where simplicity and cable-length tolerance matter more than multi-device support. Most embedded systems end up using all three protocols for different peripheral types.

The Key Differences at a Glance

SPII2CUART
Signal lines4+ (SCLK, MOSI, MISO, + 1 CS per device)2 (SDA, SCL, shared)2 (TX, RX)
ClockSynchronous (shared)Synchronous (shared)Asynchronous (each side independent)
Typical max speed10–80 MHz100 kHz–3.4 MHz115 kbaud–4 Mbaud
Devices per busOne per CS lineUp to 112 (7-bit addressing)1 (point-to-point only)
DuplexFull-duplexHalf-duplexFull-duplex
Cable lengthPCB only (< 30 cm)PCB only (< 400 pF limit)~1 m TTL; ~15 m RS-232
GPIO cost3 shared + 1 per device2 shared for all devices2 per connected device

When to Choose SPI

SPI is the right choice when throughput is the constraint.

The protocols that need SPI are usually those that move large amounts of data quickly: colour displays (ILI9341, ST7789 — for high-resolution panels above what SPI can support, see MIPI DSI), high-resolution ADCs, SPI flash chips, SD cards, and long-range radio modules (SX127x LoRa). At tens of MHz, SPI can sustain data rates that I2C or UART cannot come close to matching.

The cost of SPI is GPIO: each additional peripheral requires its own chip-select line. A microcontroller with 5 SPI peripherals needs 5 CS GPIO pins plus the 3 shared bus lines — 8 pins total, versus I2C's 2. On a pin-limited part, this constraint matters.

Reach for SPI when:

  • The peripheral needs throughput SPI can provide that I2C or UART cannot (displays, ADCs, flash)
  • You have enough GPIO pins to assign one CS per device
  • The peripheral is close to the MCU (on the same PCB)
  • Full-duplex communication is useful (e.g. streaming ADC samples while simultaneously commanding the device)

When to Choose I2C

I2C is the right choice when bus efficiency matters more than speed.

The key I2C advantage is that any number of devices share just two wires — SDA and SCL — distinguished by their 7-bit addresses. A single I2C bus can carry a temperature sensor, a humidity sensor, an OLED display, a real-time clock, and an EEPROM simultaneously, using exactly 2 MCU GPIO pins regardless of device count. Adding the fifth sensor costs zero extra pins; adding a fifth SPI device costs one more CS GPIO.

The trade-off is speed. I2C's Fast Mode (400 kHz) and Fast Mode Plus (1 MHz) are adequate for most sensor applications, but they are not suitable for the kinds of high-bandwidth data transfers SPI handles. I2C is also half-duplex — the bus can carry data in only one direction at a time.

Reach for I2C when:

  • You have multiple peripherals that all need to be addressed from one interface
  • GPIO pin count is tight and you want to minimise it
  • The data rate at 100–400 kHz is sufficient for all devices on the bus
  • Peripheral addressing is a natural fit (sensors, EEPROMs, PMICs)

When to Choose UART

UART is the right choice for point-to-point links where simplicity is the priority.

UART requires no shared clock and no addressing — both ends just need to agree on a baud rate. This makes it the simplest protocol to get working, and the most tolerant of long cables (RS-232 UART extends to ~15 m; RS-485, which is UART-based, can go much further).

UART is the go-to for peripherals that present a command-response interface rather than a register-map: GPS modules, GSM/cellular modems, Bluetooth serial modules, Wi-Fi AT-command modules, and debug consoles all typically use UART. The hard constraint is that UART is strictly one-to-one — one TX line talks to exactly one RX line; it cannot address multiple devices from a single port the way SPI and I2C can. For multi-node topologies, RS-485 (a differential, half-duplex bus supporting up to 32 nodes on a two-wire run) or CAN bus (automotive and industrial, with built-in arbitration) are the natural next step.

Reach for UART when:

  • Communicating with a single external module (GPS, cellular, Bluetooth, Wi-Fi AT)
  • Outputting debug information (printf via serial terminal)
  • The link needs to travel off the PCB over a cable
  • Simplicity and ease of debugging are more important than throughput
  • The peripheral's interface is command-response rather than register-mapped

Practical Decision Guide

Work down this list when choosing a protocol for a new peripheral:

  1. Is this a point-to-point link to one external module? → Yes: UART is simplest. Check if the module exposes SPI or I2C as an alternative only if UART throughput is a concern.

  2. Is throughput the primary requirement? (display refresh, ADC streaming, flash read/write) → Yes: SPI. No other standard protocol matches its data rate.

  3. Do you have multiple peripherals and want to minimise GPIO pin count? → Yes: I2C. Confirm no two devices share the same 7-bit address before committing.

  4. Is the device slow (sensor polled infrequently, EEPROM, RTC)?I2C at 100–400 kHz is more than fast enough and saves pins.

  5. Does the design use a mix of fast and slow peripherals?SPI for the fast ones (display, flash), I2C for the slow shared sensors.

Using All Three Together

In practice, most non-trivial embedded designs use all three protocols simultaneously. A common pattern:

PeripheralProtocolWhy
OLED or TFT displaySPINeeds 2–8 MHz minimum for acceptable refresh
ADC (precision, ≥ 16-bit)SPII2C speed too low for high sample rates
SPI flash / EEPROMSPIShares the same SPI bus as the ADC and display
BME280 environment sensorI2CPolled every 30 s; no speed requirement
DS3231 real-time clockI2CLow-speed, shares the sensor I2C bus
GPS receiverUARTModule exposes UART only; outputs NMEA sentences
Debug consoleUARTA second UART port reserved for firmware printf

None of these choices conflict — the MCU handles each bus independently, and the peripheral mix naturally sorts by protocol.

Audio peripherals are the notable exception. Streaming PCM samples to an external DAC, speaker amplifier, or audio codec uses I2S rather than SPI, I2C, or UART. I2S has a dedicated word-select (LRCK) signal that marks stereo channel boundaries — framing that no general-purpose serial protocol provides natively. If your design includes audio output or a MEMS microphone, plan for an I2S peripheral on the MCU in addition to SPI, I2C, and UART.

Networking and PC connectivity call for protocols beyond the SPI/I2C/UART trio. When a design needs IP networking over a cable — SCADA, remote monitoring, data streaming — Ethernet provides a MAC/PHY data-link layer with a TCP/IP stack above it, at throughputs and cable runs that SPI, I2C, and UART cannot match. For direct PC connectivity — virtual serial ports, HID input devices, or DFU firmware update — USB provides a host-managed, high-speed interface that hosts recognise and enumerate without custom drivers.

Design Considerations

  • MCU peripheral count: before committing to a design with multiple SPI and I2C buses, verify your MCU has enough hardware UART, SPI, and I2C peripherals — not just GPIO. Software bit-banging is possible but consumes CPU time and is harder to debug.
  • Mixed-voltage buses: I2C in particular is sensitive to voltage mismatches. A 5 V I2C device on a 3.3 V MCU requires a level translator — open-drain pull-ups to 3.3 V will not drive 5 V devices. SPI has the same issue. UART level translation to RS-232 uses dedicated driver ICs (MAX3232).
  • Bus contention on I2C: address conflicts on I2C are common when multiple sensors from the same vendor family share fixed, identical addresses. Check address maps before finalising the component list.
  • Long-cable SPI: SPI is generally limited to PCB-to-PCB distance due to capacitive loading at high clock rates. If you need to cross a connector or cable, either slow the SPI clock significantly, add line drivers, or switch to a differential bus standard (RS-485 for UART-based links).
  • Protocol driver development: choosing the right protocol is only the first step — writing reliable, interrupt-driven or DMA-based drivers for production hardware requires careful attention to error handling, clock configuration, and timing. Zeus Design's embedded firmware team implements production-grade SPI, I2C, and UART drivers across STM32, ESP32, and nRF platforms.

Common Mistakes

  • Choosing I2C for a high-speed display or ADC: the 400 kHz limit of standard I2C modes is a hard ceiling — a 320×240 RGB display refreshing at 30 fps requires far more bandwidth than I2C can deliver. Use SPI.
  • Choosing SPI for a dense sensor array: 10 SPI sensors need 10 CS GPIO pins plus 3 shared lines — 13 MCU pins total. The same sensors available in I2C variants need 2. Know the GPIO budget before committing to SPI for multiple peripherals.
  • Choosing UART and then trying to address two devices on it: UART has no addressing mechanism. Connecting two peripherals to one UART TX causes bus contention. Use I2C or SPI for multi-device buses, or use separate UART peripherals for separate devices.
  • Ignoring clock speed compatibility within an I2C bus: if a fast device (1 MHz FM+) and a slow device (100 kHz standard) share the same I2C bus, the whole bus must run at 100 kHz to accommodate the slowest member. Verify every device's supported speed before combining them on one bus.

Frequently Asked Questions

Can I use SPI, I2C, and UART in the same embedded system?
Yes, and this is common in practice. A typical IoT node might use SPI for a high-resolution ADC, I2C for a handful of sensors and an EEPROM sharing the same bus, and UART for a cellular or GPS module. Each UART, SPI, and I2C peripheral on the MCU can be independently configured — there is no conflict in using all three simultaneously, subject only to the MCU's available pin count and peripheral count.
Is SPI always faster than I2C?
In practice, yes — SPI routinely runs at 10–80 MHz on short PCB traces, while I2C tops out at 3.4 MHz in its High Speed mode and 1 MHz in the widely-supported Fast Mode Plus. However, if your application runs at low data rates (a temperature sensor polled once per second), I2C at 100 kHz is entirely adequate and the throughput comparison is irrelevant.

References

Related Questions

Related Forum Discussions