I. SPI basic principles
1. What is SPI?
SPI (Serial Peripheral Interface) is a synchronous serial communication protocol, commonly used for high-speed data transmission between microcontrollers and peripherals (such as sensors, memory, display screens).
Features:
Full-duplex communication (simultaneous transmission and reception).
Master-slave architecture (one master device controls multiple slave devices).
Four-wire system: SCK (clock), MOSI (master output slave input), MISO (master input slave output), SS (slave device selection).
2. SPI mode
SPI has 4 operating modes, determined by clock polarity (CPOL) and clock phase (CPHA):
model |
CPOL |
CPHA |
Clock idle state |
Data sampling timing |
Mode 0 |
0 |
0 |
Low level |
SCK first edge (rising edge) |
Mode 1 |
0 |
1 |
Low level |
SCK second edge (falling edge) |
Mode 2 |
1 |
0 |
High level |
SCK first edge (falling edge) |
Mode 3 |
1 |
1 |
High level |
SCK second edge (rising edge) |
Key points: CPOL: The level when the clock is idle (0 = low level, 1 = high level).
CPHA: The edge of data sampling (0 = first edge, 1 = second edge).
Ⅱ. SPI configuration steps
1. Hardware connection
Master device pins: SCK, MOSI, MISO, SS (usually controlled by the master device).
Slave device pins: SCK, MOSI, MISO, SS (need to be grounded or pulled down by the master device).
Notes:
SCK, MOSI, MISO of the master and slave devices must be directly connected (no pull-up/pull-down resistors).
SS pin needs to be manually controlled (software or hardware trigger).
2. Software configuration
Take STM32 and Arduino as examples:
(1) STM32 HAL library configuration
// Initialize SPI parameters
SPI_HandleTypeDef hspi1;
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER; // Main Mode
hspi1.Init.Direction = SPI_DIRECTION_2LINES;// Full Duplex
hspi1.Init.DataSize = SPI_DATASIZE_8BIT; // 8-bit data
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; // CPOL=0
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; // CPHA=0(Mode 0)
hspi1.Init.NSS = SPI_NSS_SOFT; // Software Control SS
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; //Baud rate division
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; // MSB First
hspi1.Init.TIMode = SPI_TIMODE_DISABLE; // Turn off TI mode
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; // Turn off CRC
// Initialize SPI
HAL_SPI_Init(&hspi1);
(2) Arduino configuration
#include <SPI.h>
void setup() {
SPI.begin(); // Initialize SPI pins (SCK, MOSI, MISO, SS)
pinMode(SS, OUTPUT); // SS must be set as output (to avoid entering slave mode)
digitalWrite(SS, HIGH); // Initially disable the slave device
}
// Send data (SPI transfer function)
byte transferData(byte data) {
digitalWrite(SS, LOW); // Activate slave device
byte received = SPI.transfer(data); // Sending and receiving data
digitalWrite(SS, HIGH); // Release slave device
return received;
}
III. SPI communication process
The master pulls down SS: activates the slave.
The master generates a clock signal: synchronizes data transmission through SCK.
Data transmission:
The master sends data through MOSI, and the slave returns data through MISO.
Data is sampled at the specified edge of SCK (determined by CPHA).
The master pulls up SS: ends communication.
IV. Key configuration parameters
Baud rate (clock frequency):
The master sets the SCK frequency through a frequency divider (such as STM32's BaudRatePrescaler).
Make sure it does not exceed the maximum supported frequency of the slave.
Data order:
MSB (high bit first) or
LSB (low bit first).
Chip select signal (SS) management:
Hardware SS (dedicated pin) or software SS (general GPIO).
V. Common Problems and Solutions
1. Communication failure (data error)
Possible causes:
SPI mode mismatch (CPOL/CPHA setting error).
Pin connection error (such as MOSI/MISO reverse connection).
Clock frequency is too high (slave device cannot respond).
Solution:
Check the SPI mode requirements in the slave device data sheet.
Use a logic analyzer to check the SCK, MOSI, and MISO waveforms.
2. Unstable data transmission
Possible causes:
Long-distance wiring causes signal interference.
Lack of pull-up resistors (MISO/MOSI lines are floating).
Solution:
Shorten the wiring or use shielded wires.
Connect a 4.7kΩ pull-up resistor to the MOSI/MISO line.
3. The SS pin is automatically pulled low
Possible causes:
In hardware mode, the SS pin level change triggers the slave mode (such as the SS pin level sensitivity of AVR).
Solution:
Set to software SS of master device (such as pinMode(SS, OUTPUT) of Arduino).
VI. Debugging Tools
Logic Analyzer: Capture SPI waveforms and analyze clock and data timing.
Recommended tools: Saleae Logic, DSLogic.
Oscilloscope: Check SCK frequency and signal integrity.
VII. Application Scenario Examples
Sensor reading: such as temperature sensor (MAX31865), accelerometer (MPU6050).
Memory access: such as Flash (W25Q64), EEPROM (AT25DF041).
Display control: such as TFT LCD with SPI interface.
Summary
SPI configuration core: correctly set mode (CPOL/CPHA), baud rate, and data sequence.
Hardware Note: Ensure that the SS pin is managed correctly to avoid signal interference.
Debugging tips: Use a logic analyzer to verify timing and refer to the slave device data sheet.
Through reasonable configuration and debugging, SPI can achieve efficient and stable data transmission and is widely used in embedded systems.