STM32: How to use SPI Full-Duplex Master + Slave with Interrupt & DMA

STM32 HAL Tutorial: SPI1 Master + SPI2 Slave Communication

Abstract

Learn how to configure STM32 SPI1 in full-duplex master mode and SPI2 as slave, using interrupt for reception and DMA for transmission. Step-by-step HAL example included.

1. Introduction

SPI is a high-speed synchronous serial interface widely used in embedded systems:

  • Full-duplex communication: Master and Slave can transmit/receive simultaneously
  • Master: generates clock (SCK)
  • Slave: synchronizes to master clock
  • DMA: enables fast, CPU-independent data transfer
  • Interrupts: notify MCU when data is received

Goal: Demonstrate SPI1 as master and SPI2 as slave:

  • Master sends a buffer via DMA
  • Slave receives via interrupt
  • Both operate full-duplex

2. Prerequisites

  • STM32 board with SPI
  • STM32CubeIDE or VS Code installed
  • Knowledge of HAL and SPI

3. SPI Configuration Overview

Mode

Master

Slave

Clock Polarity/Phase

CPOL=0, CPHA=0

CPOL=0, CPHA=0

Data Size

8-bit / 16-bit

8-bit / 16-bit

NSS Management

Software or Hardware

Hardware (NSS input)

Transmission

DMA

Interrupt on RX

 

 

How CPOL and CPHA works:

4. CubeMX Configuration

Master (SPI1)

  1. Set Mode = Master

  2. Configure Baud rate prescaler

  3. Enable Full-Duplex

  4. Enable DMA TX

Slave (SPI2)

  1. Set Mode = Slave

  2. Enable Full-Duplex

  3. Enable Interrupt on RX

Generate HAL code for initialization.

5. HAL Example: Master Transmit with DMA

				
					uint8_t masterTxBuffer[16] = "STM32 SPI Full-Duplex";

void SPI1_Master_Transmit(void)
{
    // Start DMA transmission
    HAL_SPI_Transmit_DMA(&hspi1, masterTxBuffer, sizeof(masterTxBuffer));
}

				
			

6. HAL Example: Slave Receive with Interrupt

				
					uint8_t slaveRxBuffer[16];

void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
    if(hspi->Instance == SPI2)
    {
        // Data received from master
        // Process slaveRxBuffer here
    }
}

// Start interrupt-based reception

				
			

HAL_SPI_Receive_IT(&hspi2, slaveRxBuffer, sizeof(slaveRxBuffer));

  • HAL_SPI_Receive_IT() enables RX interrupt

     

  • When master sends data, slave ISR triggers HAL callback

     

  • DMA on master transfers without CPU intervention

7. Hands-On Lab Example

1. Connect SPI1 pins (SCK, MOSI, MISO, NSS) to SPI2 pins

2. Initialize SPI1 master with DMA TX

3. Initialize SPI2 slave with interrupt RX

4. Send test buffer from SPI1 master

5. Observe SPI2 slave receives buffer via interrupt callback

6. Optionally, respond from slave using DMA TX for true full-duplex

7. Optionally, send data over the UART to transmit it over SPI

				
					/* USER CODE BEGIN PFP */
uint8_t u8UartBuff[2];
uint8_t u8FlagRxReceived = 0;
uint8_t u8SPIMasterTX[2];
uint8_t u8SPISlaveRX[2];
/* USER CODE END PFP */

				
			
				
					/* USER CODE BEGIN 2 */
 HAL_UART_Receive_IT(&huart2, u8UartBuff, 1);
 HAL_SPI_Receive_IT(&hspi2, u8SPISlaveRX, 1);
 /* USER CODE END 2 */

				
			
				
					 /* USER CODE BEGIN WHILE */
 while (1)
 {
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
	  if(u8FlagRxReceived)
	  {
		  HAL_SPI_Transmit_DMA(&hspi1, u8SPIMasterTX, 1);
		  u8FlagRxReceived = 0;
	  }
 }
 /* USER CODE END 3 */

				
			
				
					/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	HAL_UART_Receive_IT(&huart2, u8UartBuff, 1);
	u8FlagRxReceived = 1;
	u8SPIMasterTX[0] =  u8UartBuff[0];
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
	u8UartBuff[1] =  u8SPISlaveRX[0];
	HAL_UART_Transmit(&huart2, &u8UartBuff[1], 1, 10);
	HAL_SPI_Receive_IT(&hspi2, u8SPISlaveRX, 1);
}
/* USER CODE END 4 */

				
			

Tip: Use logic analyzer or oscilloscope to visualize full-duplex data exchange

8. Advantages

  • True full-duplex communication

  • DMA reduces CPU load on master

  • Interrupts provide immediate response on slave

  • Perfect for high-speed sensor or memory interfacing

  • Demonstrates advanced STM32 peripheral interaction

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top