P3 · Interfacing & Communication · Lesson 3 of 5

SPI — Synchronous & Fast

~14 min

Slide 1

SPI's four wires and the clock

SPI (Serial Peripheral Interface) is the fast one. Where UART avoids a clock wire and pays for it with baud-rate fragility, SPI does the opposite: it adds a dedicated clock line and gets self-timing, simplicity, and high speed in return.

The dedicated clock changes everything

SPI is synchronous — it has a clock line called SCK (Serial Clock). The controller (the microcontroller) generates this clock, and every pulse says to the connected device: "read the data line right now."

This solves UART's biggest headache. There's no baud rate to agree on, because the clock carries the timing. The device doesn't run its own timer hoping to stay in step — it simply reads whenever the controller clocks it. As a result:

  • No speed mismatch is possible — the controller sets the pace bit-by-bit.
  • It can run very fast — SPI is typically the highest-throughput of the three protocols, easily into the megahertz.

The data lines: MOSI and MISO

SPI separates the two directions of data onto two wires:

  • MOSIMaster Out, Slave In. Data from the controller to the device.
  • MISOMaster In, Slave Out. Data from the device back to the controller.

(You'll also see the modern names COPI/CIPO — Controller-Out/Controller-In — meaning the same lines.)

Because MOSI and MISO are separate, SPI is full-duplex: the controller and device can send to each other simultaneously on the same clock pulses. Combined with the fast clock, that's why SPI moves data so quickly.

The fourth wire: chip-select (CS)

The last standard line is CS (Chip-Select, sometimes SS for Slave-Select). The controller pulls a device's CS line LOW to say "I'm talking to you now" — activating that specific device. We'll see in the next slide how CS is the key to putting many devices on one SPI bus.

The four wires together

Microcontroller            SPI device
   SCK  ───────────────►   SCK    (clock — controller drives)
   MOSI ───────────────►   data in
   MISO ◄───────────────   data out
   CS   ───────────────►   select (LOW = active)
   GND  ─────────────────  GND

Four signal wires: a clock, two data lines, and a select. That's more wires than UART's two — the price SPI pays. But in exchange you get speed, no timing fragility, and (next slide) a clean way to address many devices. SPI's whole character is "spend a few pins, get speed and simplicity."

The next slide shows how one controller commands several SPI devices using those CS lines.

Quick check

Unlike UART, SPI includes a dedicated clock line (SCK). This makes it:

Slide 2

Master, slaves, and chip-select

SPI solves UART's "only two devices" limit in a direct, physical way: the chip-select (CS) line. Understanding how CS scales to many devices — and what that costs — is the heart of the SPI-vs-I²C decision later.

One controller, one shared bus, many devices

In SPI, the controller is the master and each peripheral is a slave (modern docs say controller and peripheral). The three signal lines — SCK, MOSI, MISO — are shared by every device on the bus. They all connect to the same three wires.

So what stops all the devices from talking at once and colliding? The chip-select lines.

CS picks exactly one device at a time

Each device gets its own CS line back to the controller. The rule is simple:

  • A device only listens and responds when its CS is pulled LOW.
  • All other devices, with CS HIGH, ignore the bus entirely — they disconnect their outputs and stay quiet.

To talk to device 2, the controller pulls CS2 low, clocks the data, then releases CS2 high. To talk to device 1, it pulls CS1 low instead. Only one CS is active at any moment, so only one device ever drives the shared MISO line — no collisions.

                 ┌─ SCK  ─┬─────────┬─────────┐
Microcontroller ─┼─ MOSI ─┼─────────┼─────────┤
                 └─ MISO ─┴─────────┴─────────┘   (these 3 shared)
        CS1 ─────────────► Device 1
        CS2 ─────────────► Device 2
        CS3 ─────────────► Device 3              (one CS each)

The cost: one pin per device

Here's the catch, and it's the defining trade-off of SPI: every device needs its own CS pin on the microcontroller. Three devices = three CS pins (plus the three shared lines). Eight devices = eight CS pins.

For a few fast devices, that's fine — you have the pins, and you get speed. But as the device count climbs, SPI runs out of pins. A small microcontroller can't spare a dozen CS lines. This is precisely where I²C (Lesson 4) wins: it puts many devices on two wires using addresses instead of pins.

The mental model

Think of SPI's CS lines like calling out a name before speaking in a room: "Device 2 — go." Everyone else stays silent. It works perfectly and it's fast, but you need a separate "name wire" for each person. The more people in the room, the more wires — which is the limitation the next protocol removes.

The final SPI slide makes this trade-off explicit: when SPI is the right call, and when its pin appetite sends you to I²C.

Quick check

To talk to three SPI devices on the same bus, the controller needs:

Slide 3

SPI's trade-off: speed for pins

SPI's character comes down to one trade: it spends pins to buy speed and simplicity. Knowing when that trade is worth it — and when it isn't — is the practical skill.

What SPI is great at

  • Speed. SPI is the fastest of the three. Its dedicated clock and full-duplex data lines make it the natural choice when you need to move a lot of data quickly — graphical displays, SD cards, fast memory chips (flash), and high-rate ADC/sensor modules.
  • Simplicity of logic. No addresses, no acknowledgements, no baud agreement — just clock the bits while CS is low. The protocol itself is dead simple, which also helps it run fast.
  • A few devices, well. When you have a handful of fast peripherals and the pins to spare, SPI is clean and reliable.

What SPI is poor at

  • Many devices. Each device burns a CS pin. Past a few devices, a small microcontroller runs out of pins. SPI does not scale to "lots of peripherals."
  • Wire count. Four wires per bus (plus a CS each) is more cabling than I²C's two. Over longer distances or in tight builds, that adds up.
  • Distance. Like all these protocols, SPI is meant for on-board, short connections — chips near each other — not across a room.

The decision rule

A simple way to hold it:

Few fast devices, pins available → SPI. Many slow devices, pins scarce → I²C (next lesson).

If the job is "drive one fast display" or "read a high-speed sensor," SPI's speed wins and the pin cost is trivial. If the job is "read eight little sensors on a pin-limited board," SPI's appetite for CS pins disqualifies it, and you want addressing instead.

In a real-world context

Picture an ESP32 in a solar-monitoring build. A bright graphical display showing battery state and power flow benefits from SPI's speed — refreshing graphics needs throughput. Meanwhile a cluster of small environmental/voltage sensors would be wasteful on SPI (a CS pin each) and is better bused on I²C. Real designs often use both protocols at once — SPI for the fast, pin-affordable peripheral, I²C for the many slow ones. There's no rule that says pick only one.

Summary of SPI

  • Synchronous (clock line SCK) → self-timing, no baud fragility, very fast.
  • Four wires: SCK, MOSI, MISO, CS — full-duplex.
  • Many devices via a CS pin each → great for a few, pin-hungry for many.
  • Best for: fast single peripherals (displays, SD, flash, high-rate sensors).

You've now seen the asynchronous simple one (UART) and the fast pin-hungry one (SPI). The next lesson covers the wire-saver — I²C — which gives up some speed to put many devices on just two wires.