STM32 串口UART DMA Idel 接收调试记录

STM32 串口UART DMA Idol 接收调试记录

背景

在使用STM32CubeMX配置串口DMA+IDLE中断接收不定长度数据时,发现只有在main函数调用HAL_UARTEx_ReceiveToIdle_DMA()时执行一次,在中断回调函数中再次开启DMA时,发现huart- rxstate = 0x22 (HAL_UART_STATE_BUSY_RX),RX一直处于Busy状态,无法再次开启DMA接收。

最开始代码如下:

  1. 在main函数中启动DMA接收
c 复制代码
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  printf("Motor ready.\r\n");

  HAL_UARTEx_ReceiveToIdle_DMA(&huart2, (uint8_t *)rcv_buff, sizeof(rcv_buff));


  delay_ms(500);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
      HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
//      HAL_UART_Transmit_DMA(&huart2, s_buff, sizeof (s_buff));
//      HAL_Delay(500);

      delay_ms(500);
      commander_run();
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
  1. 接收到IDEL信号后,在中断回调函数中重新启动DMA接收
c 复制代码
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if(DEBUG_UART == 2)
	{
		HAL_UARTEx_ReceiveToIdle_DMA(huart, (uint8_t *)rcv_buff, sizeof(rcv_buff));
		rcv_flag = 1;
	}
}

解决

代码单步调试发现,中断回调函数中调用HAL_UARTEx_ReceiveToIdle_DMA()再次启动DMA时,

串口接收寄存器状态huart- rxstate = 0x22 (HAL_UART_STATE_BUSY_RX) ,一直处于busy状态。

必须先调用HAL_UART_DMAStop()关闭DMA后,huart- rxstate = 0x20(HAL_UART_STATE_READY),才能调用HAL_UARTEx_ReceiveToIdle_DMA()再次启动DMA

代码如下:

c 复制代码
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
		// 必须关闭DMA,否则huart- rxstate = 0x22 (HAL_UART_STATE_BUSY_RX),
		// 调用HAL_UARTEx_ReceiveToIdle_DMA()时,无法正常开启,还是继续上次开启的Idle DMA
		HAL_UART_DMAStop(huart);
		HAL_UARTEx_ReceiveToIdle_DMA(huart, (uint8_t *)rcv_buff, sizeof(rcv_buff));
}

参考:

  1. STM32-HAL库串口DMA空闲中断的正确使用方式+解析SBUS信号
  2. STM32CubeMX HAL库串口+DMA+IDLE空闲中断不定长度数据接收和发送
相关推荐
Jason_zhao_MR1 小时前
如何板端编译OpenCV并搭建应用--基于瑞芯微米尔RK3576开发板
人工智能·嵌入式硬件·mcu·opencv·物联网·计算机视觉·嵌入式
Shang131130487912 小时前
ISL9V3040D3ST-F085C一款安森美 ON生产的汽车点火IGBT模块,绝缘栅双极型晶体管ISL9V3040D3ST汽车点火电路中的线圈驱动器
单片机·嵌入式硬件·安森美 on生产·汽车点火igbt模块·isl9v3040d3st
亿道电子Emdoor2 小时前
【ARM】MDK Debug模式下Disassembly窗口介绍
stm32·单片机·嵌入式硬件
点灯小铭2 小时前
基于STM32单片机的无线鼠标设计
stm32·单片机·计算机外设·毕业设计·课程设计
嵌入式×边缘AI:打怪升级日志5 小时前
【无标题】
单片机·嵌入式硬件
嵌入式小李7 小时前
stm32项目(24)——基于STM32的汽车CAN通信系统
stm32·嵌入式硬件·汽车
程序员JerrySUN8 小时前
四级页表通俗讲解与实践(以 64 位 ARM Cortex-A 为例)
java·arm开发·数据库·redis·嵌入式硬件·缓存
优信电子8 小时前
基于STM32F103驱动SI5351 3通道时钟信号发生器输出不同频率信号
单片机·嵌入式
DIY机器人工房8 小时前
开发板RK3568和stm32的异同:
嵌入式硬件·嵌入式·diy机器人工房
酷飞飞19 小时前
库函数版独立按键用位运算方式实现(STC8)
单片机·嵌入式硬件