Every SPI transfer is governed by two one-bit parameters — CPOL (Clock Polarity) and CPHA (Clock Phase) — that together define exactly when data is driven onto the bus and when it is sampled. Choosing the wrong combination means your master samples bits on the wrong clock edge, producing corrupted bytes, all-zero reads, or apparently random data. Before writing a single line of code, look up the required mode in your slave’s datasheet and configureDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/manish04-mu/TheEmbeddedInsights/llms.txt
Use this file to discover all available pages before exploring further.
SPISettings to match.
CPOL — Clock Polarity
CPOL controls the idle state of SCK — the voltage level the clock line rests at when no transaction is in progress (i.e., while CS is HIGH).- CPOL = 0 — SCK idles LOW. The first clock edge of a transaction is a rising edge.
- CPOL = 1 — SCK idles HIGH. The first clock edge of a transaction is a falling edge.
CPHA — Clock Phase
CPHA controls when data is sampled relative to the clock transitions within an active transaction.- CPHA = 0 — Data is sampled on the leading (first) clock edge of each bit period and driven on the trailing edge. The master and slave must present their data bits before the first active edge.
- CPHA = 1 — Data is driven on the leading clock edge and sampled on the trailing (second) edge of each bit period.
The Four Modes
| Mode | CPOL | CPHA | Clock Idle State | Data Sampled On | Arduino Constant |
|---|---|---|---|---|---|
| 0 | 0 | 0 | LOW | Rising edge | SPI_MODE0 |
| 1 | 0 | 1 | LOW | Falling edge | SPI_MODE1 |
| 2 | 1 | 0 | HIGH | Falling edge | SPI_MODE2 |
| 3 | 1 | 1 | HIGH | Rising edge | SPI_MODE3 |
Setting the Mode in Arduino
The Arduino SPI library encapsulates clock speed, bit order, and mode into anSPISettings object passed to SPI.beginTransaction(). The transaction API ensures the bus is configured correctly before the first SPI.transfer() call and releases it cleanly afterward.
All sketches in this series use a clock speed of 100,000 Hz (100 kHz) — well within the Arduino UNO’s 16 MHz maximum and comfortably below the typical logic analyzer’s sampling rate ceiling.
Mode 0 — CPOL=0, CPHA=0, MSBFIRST (most common)
SPISettings arguments — the CS assertion/deassertion pattern and SPI.endTransaction() call remain identical across all four modes.
Choosing a Mode
How do I know which mode my slave needs?
How do I know which mode my slave needs?
Check the slave device’s datasheet. Look for a section titled “SPI Interface”, “Serial Interface”, or “Timing Diagram”. The datasheet will either state the mode number directly (e.g. “supports SPI Mode 0 and Mode 3”) or provide CPOL and CPHA values in the electrical characteristics table. Map those values to the table above to find the correct Arduino constant.
What happens if I use the wrong mode?
What happens if I use the wrong mode?
The master will sample each incoming bit on the wrong clock edge. In practice this produces one of three symptoms: all bytes read back as
0x00 or 0xFF, a fixed bit-shifted version of the expected value (e.g., every byte appears rotated by one bit), or seemingly random data that changes between reads. A logic analyzer makes the problem obvious — if the idle level of SCK contradicts the CPOL setting you can spot it instantly on the waveform.Can I change modes mid-program?
Can I change modes mid-program?
Yes. Call
SPI.endTransaction() to release the bus, then call SPI.beginTransaction() again with a new SPISettings object containing the updated mode. This is common when a single Arduino master communicates with two different slave devices that require different SPI modes — each transaction simply re-configures the bus before asserting that slave’s CS line.