在UART DMA中发送完整的回叫未被调用

时间:2019-04-26 07:22:22

标签: uart dma stm32f4discovery cubemx

我想做的事情很简单。通过DMA传输并等待其传输。然后接收并等待它被接收。

当我注释掉接收部分(包括回叫)时,它将进入发送完成回叫功能。但是,当我取消注释接收部分时,它不会进入tx cplt回调,而是直接进入接收cplt回调。当我检查接收缓冲区时,我没有得到预期的结果(显然)。可能出了什么问题?

我正在使用Atollic True Studio V 9.0,CubeMx v5.1.0,STM32F407VG-DISC1开发板并为UART2启用了DMA。

我尝试过通过UART DMA发送char缓冲区并接收它。似乎它根本没有传输,因为它没有进入txCplt回调。它直接进入Rxcplt回调。

uint8_t tx_arr[10], rx_arr[10];
__IO ITStatus UartReady = RESET;

int main(void)
{
  int i = 0;
  for(i = 0; i<10; i++)
      rx_arr[i] = 0;

  for(i = 0; i<10; i++)
tx_arr[i] = i*2;

 HAL_Init();
 SystemClock_Config();
 MX_GPIO_Init();
 MX_DMA_Init();
 MX_USART6_UART_Init();
 MX_USART2_UART_Init();

  while (1)
  {

  if( HAL_UART_Transmit_DMA(&huart2, (uint8_t*)tx_arr, 10)!= HAL_OK )
  {
      Error_Handler();
  }
      while(UartReady != SET)
      {

  }
  UartReady  = RESET;
      if( HAL_UART_Receive_DMA(&huart2, (uint8_t*)rx_arr, 10)!= HAL_OK )
 {
    Error_Handler();
 }
     while(UartReady != SET)
 {

 }
 UartReady  = RESET;


}

}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    UartReady = SET;
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    UartReady = SET;
}

我希望rx_arr会被0、2、4、6,... 18填充,但是它会被垃圾填充

1 个答案:

答案 0 :(得分:0)

在我看来,原因是您正在两个ISR中使用相同的标志变量,两次都在主循环中忙于等待。

如果取消对这两个处理程序动作的注释,则您或早或晚都会遇到争用情况,在这种情况下,两个处理程序都将一个“ SET”值迅速地一个接一个地放置-在主循环等待它之前。然后,主循环通过将变量设置回“ RESET”来“使用”该标志。几行之后,另一个等待循环到来且不再被服务(因为两个ISR都运行得更早,并且只留下了一个“ SET”值,一个覆盖了另一个)。然后,您的主循环卡住了。

为了验证我的假设,您可以在进入主循环之前激活一个单向看门狗,并在每个主循环周期中触发它。如果主循环像我想象的那样卡住了,您将检测到复位原因随后指向看门狗。