2026-02-09 2:49 AM - last edited on 2026-02-09 9:40 AM by Andrew Neil
Title edited to note that this relates to a Blue Pill board.
Hello everyone,
I'm starting a learning journey into the STM32 world, specifically studying the HAL library (my past programming experiences didn't rely on ready-made libraries).
Right now (after tinkering with GPIOs, LCD management, etc.) I'm working on the SPI dialogue. I have two STM32F103CBT6A development boards, one configured for "Full Duplex Master" and one for "Full Duplex Slave."
When trying to send 10 static bytes (10, 20, 30, 100) from both the master and slave sides using the "HAL_SPI_TransmitReceive_IT(&hspi1, TX_Buffer, RX_Buffer, 10)" function, I expect the oscilloscope to see the MOSI line equal to the MISO line without any offsets. This happens for a few seconds after resetting the slave (image 1), but then the bytes on the MISO line shift (image 2). Furthermore (I'm viewing the data received from the slave on an LCD) when this problem occurs, the slave also doesn't receive correctly.
After adjusting the codes for 10-byte transmission, I wanted to expand it to 150 bytes.
Thanks in advance to anyone who can point out where I'm going wrong.
2026-02-09 6:21 AM
The slave has to be ready to send before the master starts clocking SCK. This is a code issue. How are you ensuring the slave is ready to send before the master starts?
2026-02-09 6:40 AM
I don't know the exact Cube/HAL example you talk about here.
But historically, the F103 is a very early model, and most examples published by ST utilized the SPL, a predecessor of the current library.
I'm still using SPL code for many of my examples, because it's much less complicated, less resource-intensive, and better readable - and the examples were usually tested well.
Anyway, most of the SPL firmware packages I reviewed (F0, F3, F4) contained a SPI/DMA example with two identical boards, one as slave and one as master. The example is usually named "SPI_TwoBoards" (or similiar).
Even if you stick with your Cube code, I would recommend to download such a package (usually the more generic one named "STM32xxxx_DSP_StdPeriph_Lib_Vx.x.x"), and compare the configuration process and setup sequence of your code with the example.
2026-02-09 8:03 AM
Dear TDK,
thanks a lot for your reply.
How can I load data into the slave's buffer before the master starts generating the clock?
Best Regards
2026-02-09 8:14 AM
Here is one way to properly handle SPI interrupt-based communications between master and slave:
2026-02-09 9:13 AM - last edited on 2026-02-09 9:18 AM by Andrew Neil
Dear TDK,
I'm sorry to bother you again, but I can't figure out what I'm doing wrong in your example. I've attached the code for my master and slave. Any help would be greatly appreciated.
MASTER CODE:
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
Lcd_cursor(&lcd, 0,0);
Lcd_int(&lcd, RX_Buffer[0]);
Lcd_cursor(&lcd, 0,4);
Lcd_int(&lcd, RX_Buffer[1]);
Lcd_cursor(&lcd, 0,8);
Lcd_int(&lcd, RX_Buffer[2]);
Lcd_cursor(&lcd, 0,12);
Lcd_int(&lcd, RX_Buffer[3]);
Lcd_cursor(&lcd, 0,16);
Lcd_int(&lcd, RX_Buffer[4]);
Lcd_cursor(&lcd, 1,0);
Lcd_int(&lcd, RX_Buffer[5]);
Lcd_cursor(&lcd, 1,4);
Lcd_int(&lcd, RX_Buffer[6]);
Lcd_cursor(&lcd, 1,8);
Lcd_int(&lcd, RX_Buffer[7]);
Lcd_cursor(&lcd, 1,12);
Lcd_int(&lcd, RX_Buffer[8]);
Lcd_cursor(&lcd, 1,16);
Lcd_int(&lcd, RX_Buffer[9]);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
HAL_SPI_TransmitReceive_IT(&hspi1, TX_Buffer, RX_Buffer, 10);
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
HAL_Delay(500);
}
/* USER CODE END 3 */
}SLAVE CODE:
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
Lcd_cursor(&lcd, 0,0);
Lcd_int(&lcd, RX_Buffer[0]);
Lcd_cursor(&lcd, 0,4);
Lcd_int(&lcd, RX_Buffer[1]);
Lcd_cursor(&lcd, 0,8);
Lcd_int(&lcd, RX_Buffer[2]);
Lcd_cursor(&lcd, 0,12);
Lcd_int(&lcd, RX_Buffer[3]);
Lcd_cursor(&lcd, 0,16);
Lcd_int(&lcd, RX_Buffer[4]);
Lcd_cursor(&lcd, 1,0);
Lcd_int(&lcd, RX_Buffer[5]);
Lcd_cursor(&lcd, 1,4);
Lcd_int(&lcd, RX_Buffer[6]);
Lcd_cursor(&lcd, 1,8);
Lcd_int(&lcd, RX_Buffer[7]);
Lcd_cursor(&lcd, 1,12);
Lcd_int(&lcd, RX_Buffer[8]);
Lcd_cursor(&lcd, 1,16);
Lcd_int(&lcd, RX_Buffer[9]);
HAL_SPI_TransmitReceive_IT(&hspi1, TX_Buffer, RX_Buffer, 10);
}
/* USER CODE END 3 */
}Best Regards
Edited to apply source code formatting - please see How to insert source code for future reference.
2026-02-09 9:13 AM
Welcome to the forum.
Please see How to write your question to maximize your chances to find a solution for best results.
@NicoNX650 wrote:I have two STM32F103CBT6A development boards, .
What boards are they, exactly ?
2026-02-09 9:18 AM
Dear Andrew,
thanks for your reply.
The boards are two STM32F103CBT6A.
Best Regards
2026-02-09 9:28 AM
@NicoNX650 wrote:The boards are two STM32F103CBT6A.
That's not a board - that's just the part number of the MCU chip.
You need to give details of the board on which the chip is mounted.
How to write your question to maximize your chances to find a solution
2026-02-09 9:36 AM
Dear Andrew,
you're right. If I remember well the board name is Blue Pill.
For be sure I attached the picture of them.
Thanks