2025-03-24 7:19 AM - edited 2025-03-25 12:32 AM
Hello ST Community,
I am trying to set up SPI communication between two STM32 microcontrollers (two NUCLEO-F401RE boards); one as an SPI master and the other as an SPI slave. For now, I am only trying to transmit only one byte (0x61). For this I am using STM32’s HAL Library, and its functions HAL_SPI_Transmit_IT() and HAL_SPI_Receive_IT.
On the slave, the HAL_SPI_RxCpltCallback() and the code inside it (setting a flag) are being executed, meaning that the slave is attempting to receive data sent by the master. However, the data in the SPI receive buffer is always 0x00 (serial terminal shown below; displaying "0" for every SPI receive interrupt occurrence).
Termite serial terminal outputting "0" upon every occurance of SPI receive interrupt
I need to have the master and the slave operating in Full-Duplex Master and Full-Duplex Slave modes respectively (both with interrupts), however, when setting them in Transmit Only Master and Receive Only Slave, and disabling interrupts, for debugging purposes, the same issue persisted.
Below are the hardware connections (short wires from one NUCLEO board to another):
Connection diagram of the two NUCLEO-F401RE boards
Other information related to hardware:
Code snippets below. I am only showing the user-inputted code, not the auto-generated code.
Attached are the Master and Slave configuration settings in STM32CubeIDE Code Configurator.
NUCLEO-F401RE Board 1 (MASTER) Code:
/* USER CODE BEGIN PV */
/* Private variables */
uint8_t spi_tx_buf[] = "a"; // Data to send... 0x61 or Decimal 97
/* USER CODE END PV */
In main():
/* USER CODE BEGIN 2 */
// Start with green LED OFF
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
// Slave NSS (PA10) normally high
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
HAL_Delay(2000); // Give slave time to prepare...
/* USER CODE END 2 */
In while(1):
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET); // Pull slave NSS (PA10) low
// HAL_Delay(100); // No effect
HAL_Delay(500); // No effect
HAL_SPI_Transmit_IT(&hspi2, spi_tx_buf, 1); //Sending in Interrupt mode
HAL_Delay(100); // No effect
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET); // Slave NSS (PA10) back high
// Blink green LED
// LED ON
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
HAL_Delay(100);
// LED OFF
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_Delay(5000); // 5s delay before next transmit
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
(In the above code snippet, adding delays right after setting the NSS line low and before setting it bac high, had not effect on the data received by the slave.)
NUCLEO-F401RE Board 2 (SLAVE) Code:
/* USER CODE BEGIN PV */
/* Private variables */
volatile uint8_t spi_rx_buf[1]; // Data to receive
volatile uint8_t spi_rx_flag = 0;
uint8_t uart_tx_buf[20];
/* USER CODE END PV */
In main():
/* USER CODE BEGIN 2 */
// Start with green LED off
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_SPI_Receive_IT(&hspi2, spi_rx_buf, 1); //Receive in Interrupt mode
/* USER CODE END 2 */
In while(1):
/* USER CODE BEGIN WHILE */
while (1)
{
if (spi_rx_flag==1){
spi_rx_flag=0; // Reset flag immediately
sprintf((char*)uart_tx_buf, "%u\r\n", spi_rx_buf[0]);
HAL_UART_Transmit(&huart2, uart_tx_buf, strlen((char*)uart_tx_buf), 50);
// Blink the green LED
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_SPI_Receive_IT(&hspi2, spi_rx_buf, 1); // Receive again in interrupt mode
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
SPI ISR:
/* USER CODE BEGIN 4 */
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef * hspi)
{
// RX Done
spi_rx_flag = 1;
}
/* USER CODE END 4 */
I checked the SCK, MOSI and NSS signals using an oscilloscope, and nothing looks wrong there, so I believe the problem lies within the slave's receiving data code... MOSI and SCK signals shown below and are in synch, with MOSI showing bits for 0x61 one-byte message transmitted by the Master (apologies for the bad image quality, I'll try to update the picture ASAP)... NSS signal has also been verified.
Photo of scope showing SCK signal (blue) and MOSI signal (yellow) during transmission of 0x61 single-byte message
I really appreciate your help in getting this very basic code to work. I have been trying various code examples, including from ST WIKI (https://wiki.st.com/stm32mcu/wiki/Getting_started_with_SPI) and still cannot get this board-to-board SPI communication working. I have also tried changing the NUCLEO boards to exclude hardware malfunctions, and switching from SPI2 to SPI3 peripherals.
Thanks!
Brian
Solved! Go to Solution.
2025-04-01 12:22 AM
Hello All,
An update on the above issue, which has been solved.
The following was done, which did not lead to any positive results:
After reverting to the original code / SPI configuration (as shown in my original post), I restarted by Windows PC, and right after that, the Slave started receiving the byte sent by the Master. Following this, multi-byte and multi-slave (with software control of NSS pins) transmission was tested and worked fine.
There were no updates available at the time of PC restart, and I had restarted the IDE and PC previously. I cannot recall changing anything else to software or hardware, apart from restarting my machine, so I cannot really say what was causing the problem.
Thanks all for your help!
Brian
2025-04-01 12:27 AM
Hi @TDK ,
I appreciate your help and offer to investigate this issue, and I apologise for the delayed reply.
This issue had been solved and I have just posted an update.
Brian