Skip to main content
Visitor II
March 13, 2025
Solved

2 STM32F407 sending data to each other using DMA

  • March 13, 2025
  • 3 replies
  • 833 views

I have 2 STM32F407 Discovery boards sending data back and forth to each other using usart2. Usart3 on one is just a monitor so I can see the output on a USB comm port. I'm using DMA on the receive for both and the HAL_UART_RxCpltCallback for both just sends the data back for both boards. I have to have a transmit in one of the tasks before it will work. I have a counter that advances in each callback that spins the 4 LED's so I can see if it's working because it goes too fast to spit it out to the comm port. Is there any way to slow it down? I tried putting a vTaskDelay in one of the callbacks but I don't think you can do that. I'm using STM32CubeIDE and FreeRTOS.I have attached both freertos.c files from the Core/Src/ directory. The lights spin incredibly fast and then slow down and pause once in a while.

    This topic has been closed for replies.
    Best answer by Karl Yamashita

    Set a flag in HAL_UART_RxCpltCallback and check the flag in a task. In the task you can use a delay instead of using the delay in the interrupt. In the same task you can transmit instead of transmitting in the interrupt with blocking transmit.

     

    volatile bool dataRdy = false;
    
    void StartTask03(void const * argument)
    {
     /* USER CODE BEGIN StartTask03 */
     /* Infinite loop */
     // 57FF70064983574811332087	id of ST-Link for test_uart3
     // 066EFF565257867767140832	id of ST-Link for test_uart2
    	vTaskDelay(10);
    	HAL_UART_Receive_DMA (&huart2, &data[0], DATA_SIZE);
    
    	for(;;)
    	{
    		vTaskDelay(2000);
     if(dataRdy)
     {
     dataRdy = 0;
     HAL_UART_Transmit(&huart2, &data[0], DATA_SIZE, 10);
     }
    	}
     /* USER CODE END StartTask03 */
    }
    
    /* Private application code --------------------------------------------------*/
    /* USER CODE BEGIN Application */
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
     //HAL_UART_Transmit(&huart3, data, 10, 200);
    	HAL_UART_Receive_DMA(&huart2, &data[0], DATA_SIZE);
     dataRdy = true
    	
    	//HAL_UART_Transmit(&huart3, &data[0], DATA_SIZE, 1000);
    	//HAL_UART_Transmit(&huart3, &crlf[0], 2, 10);
    	//vTaskDelay(1000);
    	if(++menu_ptr > 3)
    		menu_ptr = 0;
    }

    3 replies

    Visitor II
    March 13, 2025

    looking through stm32f4xx_hal_uart.h I found HAL_UART_DMAPause() and HAL_UART_DMAResume(). I guess I'll try that.

    Graduate II
    March 13, 2025

    Set a flag in HAL_UART_RxCpltCallback and check the flag in a task. In the task you can use a delay instead of using the delay in the interrupt. In the same task you can transmit instead of transmitting in the interrupt with blocking transmit.

     

    volatile bool dataRdy = false;
    
    void StartTask03(void const * argument)
    {
     /* USER CODE BEGIN StartTask03 */
     /* Infinite loop */
     // 57FF70064983574811332087	id of ST-Link for test_uart3
     // 066EFF565257867767140832	id of ST-Link for test_uart2
    	vTaskDelay(10);
    	HAL_UART_Receive_DMA (&huart2, &data[0], DATA_SIZE);
    
    	for(;;)
    	{
    		vTaskDelay(2000);
     if(dataRdy)
     {
     dataRdy = 0;
     HAL_UART_Transmit(&huart2, &data[0], DATA_SIZE, 10);
     }
    	}
     /* USER CODE END StartTask03 */
    }
    
    /* Private application code --------------------------------------------------*/
    /* USER CODE BEGIN Application */
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
     //HAL_UART_Transmit(&huart3, data, 10, 200);
    	HAL_UART_Receive_DMA(&huart2, &data[0], DATA_SIZE);
     dataRdy = true
    	
    	//HAL_UART_Transmit(&huart3, &data[0], DATA_SIZE, 1000);
    	//HAL_UART_Transmit(&huart3, &crlf[0], 2, 10);
    	//vTaskDelay(1000);
    	if(++menu_ptr > 3)
    		menu_ptr = 0;
    }
    Graduate II
    March 13, 2025

    Have you tried lowering the BAUD rate?