What Is SPI and How Does It Shift Binary Data?

Serial Peripheral Interface (SPI) is a synchronous, full-duplex communication protocol commonly used to transmit data over short distances between microcontrollers and peripheral devices like sensors, displays, and memory chips. This article explains the fundamentals of SPI architecture and details the step-by-step mechanism of how two devices use interconnected shift registers to exchange binary data bidirectionally and simultaneously over a shared clock signal.

What is Serial Peripheral Interface (SPI)?

SPI operates on a master-slave (or controller-target) architecture. A single master device controls the communication flow, generates the synchronization clock, and selects which slave device to communicate with.

An SPI bus uses four primary logic lines: * SCLK (Serial Clock): Generated by the master to synchronize data transmission. * MOSI (Master Out, Slave In): The data line used by the master to send bits to the slave. * MISO (Master In, Slave Out): The data line used by the slave to send bits back to the master. * CS / SS (Chip Select / Slave Select): An active-low line driven by the master to enable a specific slave device.

Because SPI has dedicated lines for sending and receiving data simultaneously (MOSI and MISO), it is inherently a full-duplex protocol.

The Shared Shift Register Architecture

At the hardware level, SPI bidirectional communication is driven by two shift registers: one inside the master and one inside the slave. Typically, these are 8-bit or 16-bit registers.

When the Chip Select line is pulled low (active), the MOSI and MISO lines link these two shift registers together into a single, closed circular ring buffer:

+-------------------+                      +-------------------+
|  Master Register  |                      |  Slave Register   |
|   [ 8-bit Shift ] | ---- MOSI Line ----> |   [ 8-bit Shift ] |
|                   | <--- MISO Line ----- |                   |
+-------------------+                      +-------------------+
         ^                                          ^
         |============== SCLK Clock ===============|

How Binary Data Shifts Bidirectionally

SPI communication is strictly based on data exchange; every time a bit is sent, a bit must be received. The process operates using binary logic (1s and 0s represented as high and low voltage levels) across consecutive clock cycles.

1. Initial State

Consider an 8-bit transfer where the master holds the binary value 10110001 and the slave holds the binary value 01001110.

2. Clock Edge and Bit Shifting

Depending on the configured clock polarity (CPOL) and clock phase (CPHA), data is shifted out on one clock edge (e.g., rising edge) and sampled on the opposite edge (e.g., falling edge). In standard MSB-first (Most Significant Bit) mode:

  1. Clock Pulse 1:
    • The master shifts its leftmost bit (1) out onto the MOSI line.
    • The slave shifts its leftmost bit (0) out onto the MISO line.
    • The slave samples the 1 on MOSI and shifts it into its rightmost register position.
    • The master samples the 0 on MISO and shifts it into its rightmost register position.
  2. Clock Pulses 2 through 7:
    • This shifting process repeats for each consecutive clock pulse. For every bit shifted out from one side, an incoming bit fills the vacant position on the opposite side of the register.
  3. Clock Pulse 8:
    • The final bits are transferred and latched into place.

3. Final State

After exactly 8 clock cycles, the contents of the master and slave registers have completely swapped:

If the master only intends to send data without expecting a meaningful response, the incoming data is simply discarded by software. Conversely, if the master only wants to read data from the slave, it must send dummy bytes (such as 0x00 or 0xFF) to generate the clock pulses required to shift the slave’s binary data into the master’s register.