SPI (Serial Peripheral Interface): A four-wire synchronous serial bus using MOSI, MISO, SCLK, and CS lines; faster than I²C but requires a separate CS line per slave
MOSI (Master Out Slave In): The data line from the master to the slave device
MISO (Master In Slave Out): The data line from the slave to the master device
SCLK (Serial Clock): The clock signal generated by the master that synchronises data transfer
CS (Chip Select): An active-low signal from the master that enables a specific slave device; one CS line required per slave
SPI Mode: The combination of clock polarity (CPOL) and clock phase (CPHA) settings; must match between master and slave (4 modes: 0, 1, 2, 3)
Full-Duplex Operation: SPI transfers data simultaneously in both directions (MOSI and MISO active at the same time) in every clock cycle
57.1 In 60 Seconds
SPI (Serial Peripheral Interface) is a 4-wire, full-duplex synchronous protocol using MOSI, MISO, SCLK, and one chip-select (SS) line per slave device. It achieves speeds of 10+ Mbps – much faster than I2C – making it ideal for high-throughput peripherals like SD cards, displays, and ADCs. The trade-off is more wires: each additional slave needs its own SS line, and there is no standardized addressing or acknowledgment mechanism.
57.2 Learning Objectives
By the end of this chapter, you will be able to:
Explain SPI Architecture: Identify the four-wire structure (MOSI, MISO, SCK, SS) and describe the role of each signal in full-duplex data transfer
Configure SPI Modes: Select the correct clock polarity (CPOL) and phase (CPHA) combination for a given device datasheet
Construct SPI Wiring: Connect multiple slave devices to a single master using individual chip-select lines
Distinguish Protocol Trade-offs: Compare SPI, I2C, and UART across speed, pin count, device capacity, and duplex mode to justify the best choice for a given application
Diagnose SPI Faults: Identify the root cause of mode mismatch, chip-select conflicts, and signal-integrity problems from observed symptoms
Implement SPI Code: Build and configure Arduino/ESP32 firmware to communicate with SD cards and displays using the SPI library
For Beginners: The SPI Protocol
SPI (Serial Peripheral Interface) is a fast communication method that connects a main controller to sensors and displays using four wires. Think of it as a one-on-one conversation where the controller picks which device to talk to by tapping it on the shoulder. SPI is faster than I2C but uses more wires, so it is great when speed matters.
Sensor Squad: The Speed Demon!
“When I need to go FAST, I use SPI,” said Max the Microcontroller. “It can do over 10 Mbps – way faster than I2C’s 400 kHz! That is why SD cards, color displays, and high-speed ADCs use SPI.”
“SPI has four wires,” explained Sammy the Sensor. “MOSI sends data from Max to me, MISO sends data from me back to Max, SCLK is the shared clock, and SS is my personal select wire. When Max pulls my SS line low, it means ‘Sammy, you are up!’ and I start responding.”
Lila the LED noticed a trade-off. “The cool thing is SPI is full-duplex – Max can send and receive data at the SAME time. But the downside is each device needs its own SS wire. With 10 sensors, Max needs 10 extra wires just for chip selects!”
“So here is the rule of thumb,” said Bella the Battery. “Use SPI when you need speed – reading from an SD card, driving a fast display, or sampling audio data. Use I2C when you have lots of slow sensors and want minimal wiring. And use UART for simple two-device connections like a GPS module. Each protocol has its sweet spot!”
57.3 Prerequisites
Before diving into this chapter, you should be familiar with:
This allows clock frequencies up to: \[f_{max} = \frac{0.35}{t_r} = \frac{0.35}{2.2 \times 10^{-9}} = 159 \text{ MHz}\]
For I2C with 4.7 kΩ pull-up and same 50 pF load: \[t_r = 2.2 \times 4700 \times 50 \times 10^{-12} = 517 \text{ ns}\]\[f_{max} = \frac{0.35}{517 \times 10^{-9}} = 677 \text{ kHz}\]
This explains why SPI routinely runs at 10-80 MHz while I2C maxes out at 400 kHz (standard) or 3.4 MHz (high-speed with active pull-ups). With the parameters above, SPI is ~235× faster than standard I2C; in general the speed ratio scales with the pull-up resistance value and is driven entirely by the RC time constant of the open-drain pull-up network.
SPI uses four dedicated lines between master and slave. Figure 57.1 shows the four signals, and Figure 57.2 shows how a single master connects to multiple slaves using shared data lines with individual chip-select lines.
Figure 57.1: SPI signal lines showing MOSI, MISO, SCK, and SS connections
Figure 57.2: SPI Bus Architecture with Multiple Slaves
Signal names (vary by manufacturer):
Function
Alternative Names
SCLK
SCK, CLK (Serial Clock)
MOSI
SDI, DI, SI (Master Out Slave In)
MISO
SDO, DO, SO (Master In Slave Out)
SS
CS, CE (Slave Select / Chip Select)
SCLK (Serial Clock):
Clock signal from master
Slaves synchronize to this clock
MOSI (Master Out, Slave In):
Data from master to slave
Master writes, slaves read
MISO (Master In, Slave Out):
Data from slaves to master
Slaves write, master reads
SS (Slave Select):
Active LOW (usually)
Master pulls LOW to select specific slave
Separate SS line for each slave
57.6 SPI Modes
SPI has 4 modes based on clock polarity (CPOL) and phase (CPHA). Figure 57.3 illustrates how each combination of CPOL and CPHA determines when data is sampled relative to the clock edge.
Figure 57.3: SPI clock mechanism and timing showing clock polarity and phase
Mode
CPOL
CPHA
Clock Idle
Data Sampled
0
0
0
LOW
Rising edge
1
0
1
LOW
Falling edge
2
1
0
HIGH
Falling edge
3
1
1
HIGH
Rising edge
CPOL (Clock Polarity):
0 = Clock idle state is LOW
1 = Clock idle state is HIGH
CPHA (Clock Phase):
0 = Data sampled on leading edge (first transition)
1 = Data sampled on trailing edge (second transition)
Most common: Mode 0 and Mode 3
Important: Master and slave must use same mode!
57.7 SPI Data Transfer
Full-duplex simultaneous transfer:
SS ____ ________
\______________________/
SCLK ___ _ _ _ _ _ _ _ ___
\_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
MOSI ====X===X===X===X===X===X===X===X=====
(Master sends data to slave)
MISO ====X===X===X===X===X===X===X===X=====
(Slave sends data to master)
Bit: 7 6 5 4 3 2 1 0
Process:
Master pulls SS LOW (select slave)
Master generates clock pulses on SCLK
On each clock pulse:
Master outputs bit on MOSI
Slave outputs bit on MISO
Both sides shift data simultaneously
After 8 (or 16) bits, transaction complete
Master pulls SS HIGH (deselect slave)
Data transmitted MSB first (most significant bit first) - can be configured.
57.8 Arduino/ESP32 SPI Example
#include <SPI.h>// SS (Chip Select) pin#define SS_PIN 5void setup(){ Serial.begin(115200);// Initialize SPI SPI.begin();// Configure SS pin pinMode(SS_PIN, OUTPUT); digitalWrite(SS_PIN, HIGH);// Deselect Serial.println("SPI Initialized");}void loop(){// Begin transaction BEFORE asserting CS (required by Arduino SPI library) SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));// Select slave digitalWrite(SS_PIN, LOW);// Transfer data (sends 0xAA, receives slave's response simultaneously) byte response = SPI.transfer(0xAA);// Deselect slave BEFORE ending transaction digitalWrite(SS_PIN, HIGH); SPI.endTransaction(); Serial.print("Sent: 0xAA, Received: 0x"); Serial.println(response, HEX); delay(1000);}
Understanding Check: SPI Signal Integrity at High Speeds
Scenario: Your data logger uses an SPI flash memory (Winbond W25Q128) rated for 133 MHz clock. Tests at 80 MHz work reliably (98% success rate), but at 133 MHz you see 40% corruption. A logic analyzer reveals clock signal overshoot (+5.8V on 3.3V logic) and ringing (+/-0.8V oscillations lasting 12 ns).
Think about:
Why do PCB traces behave differently at 133 MHz vs 10 MHz?
What physical phenomena cause the overshoot and ringing?
Key Insight: At high frequencies, transmission line effects dominate PCB design. A 10 cm trace at 133 MHz becomes an antenna:
Ground plane: Continuous plane under signal reduces loop inductance
Verify Your Understanding:
Why does this matter more at 133 MHz than 10 MHz? Because lambda/10 at 10 MHz = 3 meters (trace is insignificant). At 133 MHz, lambda/10 = 22 cm (trace is significant fraction).
Calculate required series resistor: Source impedance (5 ohm) + resistor (27 ohm) = 32 ohm approximately equal to 50 ohm trace impedance (minimizes reflections).
57.11 Protocol Comparison for IoT
Understanding SPI in isolation is only half the story. Every IoT design involves choosing the right protocol for each peripheral. The table below summarizes the primary wired protocols covered in this module.
57.11.1 When to Use Each Protocol
Protocol
Best For
Avoid When
RS-232
GPS modules, serial debugging, industrial legacy systems
Weather station: I2C (BME280, OLED display on same bus)
Data logger: SPI (SD card for fast writes)
GPS tracker: UART (GPS module + serial debug)
Robot: Mixed (I2C for sensors, SPI for displays, UART for debug)
57.12 Quiz: SPI and Protocol Comparison
Quiz Questions
Interactive: SPI Communication Protocol
Interactive Animation: This visualization is under development.
57.13 Decision Framework: SPI vs I2C vs UART
Choosing the right wired protocol is one of the first design decisions in any embedded IoT project. The wrong choice leads to either inadequate performance or unnecessary wiring complexity.
57.13.1 Quick Decision Table
Question
SPI
I2C
UART
How many devices?
1-4 (limited by SS pins)
1-112 (bus addressing)
1 (point-to-point)
Need speed >1 Mbps?
Yes (10+ Mbps)
No (max 3.4 MHz, usually 400 kHz)
No (max ~1 Mbps)
Board space tight?
No (4+ wires)
Yes (2 wires)
OK (2 wires)
Full-duplex needed?
Yes (simultaneous TX/RX)
No (half-duplex)
Yes (separate TX/RX)
Distance >1 meter?
No
No
Yes (RS-485: up to 1200 m)
Need acknowledgment?
No (no ACK mechanism)
Yes (ACK/NACK per byte)
No (unless added in software)
57.13.2 Worked Example: Weather Station Design
A weather station needs to connect these peripherals to an ESP32:
Peripherals:
1. BME280 (temperature/humidity/pressure) - supports I2C and SPI
2. SSD1306 OLED display (128x64) - supports I2C and SPI
3. SD card module (data logging) - SPI only
4. GPS module (NEO-6M) - UART only
5. Wind speed sensor (pulse counter) - GPIO (not a bus protocol)
Analysis:
Peripheral
I2C
SPI
UART
Best Choice
Why
BME280
Supported
Supported
No
I2C
Low data rate (14 bytes per read), saves 2 pins vs SPI
SSD1306 OLED
Supported (slow)
Supported (fast)
No
SPI
Display refresh at I2C 400 kHz takes ~23 ms per frame (1024 bytes × 9 bits/byte / 400 kHz); SPI at 8 MHz takes ~1 ms (~22× faster)
SD card
No
Required
No
SPI
SD cards only support SPI (and native SD interface)
GPS
No
No
Required
UART
GPS modules output NMEA sentences over serial
Pin allocation:
I2C bus (2 pins): GPIO21 (SDA), GPIO22 (SCL) -> BME280
SPI bus (3 pins): GPIO18 (SCK), GPIO23 (MOSI), GPIO19 (MISO)
SD card SS: GPIO5
OLED SS: GPIO15
OLED DC (data/cmd): GPIO4
UART (2 pins): GPIO16 (RX), GPIO17 (TX) -> GPS
Total pins used: 10 out of 34 available GPIO
Why not put everything on I2C? The OLED display would bottleneck. At I2C 400 kHz, writing 1 KB of display data takes ~23 ms (1,024 bytes × 9 bits/byte ÷ 400,000 bps). The SD card does not support I2C at all. The GPS module outputs continuous serial data that would block the I2C bus if it were somehow connected.
Why not put everything on SPI? The BME280 would waste 2 pins (SS + the SPI bus is already used by 2 other devices). Since BME280 reads are infrequent (every few seconds) and tiny (14 bytes), I2C is perfectly adequate and saves wiring.
A sensor expecting SPI Mode 0 (CPOL=0, CPHA=0) connected to a master configured for Mode 3 will produce corrupted data. Fix: always check the sensor’s datasheet for the required SPI mode and configure the master to match before testing.
2. Running SPI at Maximum Clock Speed on Long PCB Traces
High SPI clock speeds (> 10 MHz) on PCB traces longer than 10 cm cause signal integrity issues (ringing, reflections). Fix: add a series resistor (33–100 Ω) on the SCLK line near the driver and reduce clock speed for long traces or off-board connections.
3. Not Asserting CS Low Before the First Clock Edge
The CS line must be low before the first SCLK edge for the slave to latch data correctly. Some implementations assert CS mid-transaction. Fix: verify CS assertion timing with an oscilloscope or logic analyser before relying on SPI data integrity.
🏷️ Label the Diagram
Code Challenge
57.14 Summary
This chapter covered SPI (Serial Peripheral Interface) protocol and protocol comparison:
Four-wire interface (SCLK, MOSI, MISO, SS) enables high-speed full-duplex communication
SPI modes (0-3) define clock polarity and phase - must match between master and slave
Chip select (SS/CS) lines enable multi-slave configurations with separate select per device
Speed advantage: 10+ Mbps vs I2C’s 400 kbps, ideal for SD cards, displays, and fast sensors
Trade-off: More pins (4+ wires) vs I2C’s 2 wires, no multi-master, no addressing
Protocol selection: Use SPI for high-throughput peripherals (SD cards, displays), I2C for multi-sensor buses, UART for serial-output modules (GPS, cellular modems)
57.15 What’s Next
Having mastered SPI and wired protocol selection, explore these complementary topics: