Almost every sensor, display, or module you connect to an STM32 speaks one of three protocols: I2C, SPI, or UART. They solve the same basic problem — moving bytes between chips — but differ enough in wiring, speed, and complexity that picking the wrong one costs you either pins, performance, or debugging time. Here is how to choose.
I2C: Fewer Wires, More Devices
I2C uses just two wires — SDA and SCL — shared across every device on the bus, with each device identified by a 7-bit address. That makes it the obvious choice when you are connecting many sensors and running low on pins: a temperature sensor, an IMU, and an RTC can all share the same two wires.
The tradeoff is speed and complexity. Standard I2C tops out around 400kHz (Fast Mode) or 1MHz (Fast Mode Plus on newer STM32 parts), and the protocol’s addressing, acknowledge bits, and clock stretching make it more fragile on long wires or in electrically noisy environments than SPI.
SPI: Fast and Simple, at the Cost of Pins
SPI uses four wires — MOSI, MISO, SCK, and a chip-select line per device — and pushes data far faster than I2C, commonly tens of MHz. There is no addressing scheme to negotiate; the chip-select line does that job by simply enabling one device at a time. This makes SPI the default choice for anything that needs bandwidth: SD cards, displays, high-speed ADCs, and external flash chips like the W25Q128 covered in our QSPI flash guide.
The cost is pin count. Every additional SPI device needs its own chip-select line, so a project with six SPI sensors needs nine pins (MOSI, MISO, SCK, plus six CS lines) versus just two for I2C.
UART: Point-to-Point, No Clock Line Needed
UART is asynchronous — there is no shared clock line, just TX and RX, with both sides agreeing on a baud rate ahead of time. It is inherently point-to-point: one UART peripheral talks to exactly one other device, which makes it the natural choice for GPS modules, Bluetooth/Wi-Fi modules, and debug consoles, but a poor fit for connecting multiple sensors on one bus.
UART’s real advantage is simplicity and long-cable tolerance. Because there is no shared clock to stay synchronized with, UART links tolerate longer wire runs and slightly noisier environments better than SPI, which is why RS-232 and RS-485 (both UART-based) remain standard in industrial equipment.
Quick Decision Guide
- Many low-speed sensors, few free pins → I2C
- High-speed peripheral, displays, external memory → SPI
- Single external device, long cable run, or human-readable debug link → UART
- Sensor supports more than one protocol → pick SPI if you have the pins and need speed, I2C if you do not
They Are Not Mutually Exclusive
Most real STM32 projects use all three at once: I2C for a cluster of low-speed sensors, SPI for a display or SD card, and UART for a GPS module and a debug console. STM32 parts typically expose several instances of each peripheral specifically so you can mix and match without pin conflicts — check your specific part’s datasheet for how many of each you get before finalizing your board layout.
