STM32 SPI Interface Tutorial: Achieving Efficient and Stable Data Transmission

The SPI (Serial Peripheral Interface) is one of the most widely used synchronous serial communication protocols in embedded systems, playing a crucial role in STM32 development. Compared to I2C and UART, SPI is particularly suitable for high-speed data acquisition, memory expansion, and display driving due to its full-duplex communication, high transmission rates, and hardware slave selection mechanism. This tutorial will take the communication between STM32 and SPI Flash as an example, detailing how to achieve reliable data transmission through the hardware SPI interface, with solutions directly applicable to industrial data loggers, firmware storage for smart devices, and other practical projects.

Hardware Requirements

It is recommended to use the STM32F407VG Discovery development board (which has a built-in SPI1 controller) along with the W25Q128JV SPI Flash module (128M-bit capacity). Pay attention to the hardware connections: SCK (PA5), MISO (PA6), MOSI (PA7), and CS (PA4) should be directly connected, VCC should be connected to a 3.3V power supply, and a 10kΩ pull-up resistor should be added to the CS pin, along with a 100nF decoupling capacitor in parallel at the chip power supply end.

Principle Explanation

The SPI protocol is based on a master-slave architecture, achieving full-duplex communication through a four-wire system (SCK, MOSI, MISO, CS). The SPI controller in STM32 has built-in 8/16-bit data registers and supports a maximum clock speed of 42MHz (APB2 bus). Its hardware architecture includes a programmable prescaler, a CRC calculation unit, and a DMA interface, which can significantly improve transmission efficiency by automatically managing the CS pin level in continuous transmission mode.

Development Environment Setup

Use the STM32CubeIDE v1.11.0 development environment and initialize the SPI peripheral through STM32CubeMX. In the package manager, install the F4 series HAL library v1.27.0, enable the SPI1 peripheral during configuration, select full-duplex master mode, set the data width to 8 bits, and set the hardware NSS signal to Disable (using software control for CS).

Code Implementation

1. SPI Initialization Configuration

void MX_SPI1_Init(void){  hspi1.Instance = SPI1;  hspi1.Init.Mode = SPI_MODE_MASTER;  hspi1.Init.Direction = SPI_DIRECTION_2LINES;  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;    // Clock idle low  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;        // Data sampled on the first edge  hspi1.Init.NSS = SPI_NSS_SOFT;  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; // 21MHz clock  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;  HAL_SPI_Init(&hspi1);}

2. Flash Read/Write Function Implementation

#define SPI_FLASH_CS_LOW()    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET)#define SPI_FLASH_CS_HIGH()   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET)void SPI_Flash_Write(uint32_t addr, uint8_t *pData, uint16_t size){  uint8_t cmd[4] = {0x02, (addr >> 16) & 0xFF, (addr >> 8) & 0xFF, addr & 0xFF};  SPI_FLASH_CS_LOW();  HAL_SPI_Transmit(&hspi1, cmd, 4, 100); // Send write command and address  HAL_SPI_Transmit(&hspi1, pData, size, 1000);  SPI_FLASH_CS_HIGH();}void SPI_Flash_Read(uint32_t addr, uint8_t *pData, uint16_t size){  uint8_t cmd[4] = {0x03, (addr >> 16) & 0xFF, (addr >> 8) & 0xFF, addr & 0xFF};  SPI_FLASH_CS_LOW();  HAL_SPI_Transmit(&hspi1, cmd, 4, 100);  HAL_SPI_Receive(&hspi1, pData, size, 1000);  SPI_FLASH_CS_HIGH();}

Key Configuration Parameter Analysis

Clock Phase (CLKPhase) and Polarity (CLKPolarity) settings must strictly match the slave device. When CPOL=0 and CPHA=0, data is sampled on the rising edge of SCK; when CPOL=1 and CPHA=1, it is sampled on the falling edge. Incorrect configurations can lead to data misalignment; for example, if a Flash chip requires mode 3 (CPOL=1, CPHA=1), setting it to mode 0 will prevent communication.

Debugging Tips

  1. When using a logic analyzer to capture SPI waveforms, check:
  • The number of clock pulses during the CS signal active period equals (8 * number of data bytes)
  • MOSI and MISO data are aligned on the correct clock edges
  • When encountering CRC errors, first disable the CRC function to verify basic communication
  • Adding a 1us delay after HAL_SPI_Transmit() can resolve speed mismatch issues with some slave devices
  • Performance Optimization

    1. Enable DMA transmission: Change HAL_SPI_Transmit to HAL_SPI_Transmit_DMA, combined with double buffering technology to increase throughput to 15MB/s
    HAL_SPI_Transmit_DMA(&hspi1, pData, size);
    1. When adjusting the clock prescaler, ensure that t_SCK > t_SU/t_HOLD (slave device setup/hold time); for example, when the Flash requires a minimum t_SCK=50ns, the STM32 SPI clock should be ≤20MHz

    Application Extensions

    1. Multi-Master Device Communication: By configuring the NSS (chip select) signal’s hardware management mode, multiple SPI master devices can share the bus using a multiplexer. Special attention should be paid to the design of the bus arbitration mechanism, which can use hardware signal preemption or software token ring methods.

    2. Interrupt-Driven Mode: Rewrite the polling method of the HAL library, enabling SPI transmission complete interrupt (SPI_CR2_TXEIE), combined with a circular buffer to achieve non-blocking communication. This method is particularly suitable for task scheduling in real-time operating systems (such as FreeRTOS).

    Conclusion

    Mastering the SPI interface development technology of STM32 lays a solid foundation for building high-performance embedded communication systems. It is recommended to further study advanced features such as SPI TI mode timing configuration and automatic CRC verification, and to practice ultra-high-speed storage solutions with Quad-SPI interfaces in the STM32H7 series. By flexibly utilizing various operating modes of SPI, developers can build reliable communication systems that meet the needs of different scenarios.

    Leave a Comment