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空闲中断不定长度数据接收和发送
相关推荐
gmmi16 分钟前
ARM 基础(3)
嵌入式硬件
蜀黍@猿2 小时前
【GD32】存储器架构介绍
单片机·mcu
Aczone284 小时前
硬件(六)arm指令
开发语言·汇编·arm开发·嵌入式硬件·算法
EkihzniY11 小时前
OCR 证件识别:驱动澳门酒店自助入住智能化
嵌入式硬件·ocr
好家伙VCC11 小时前
数学建模模型 全网最全 数学建模常见算法汇总 含代码分析讲解
大数据·嵌入式硬件·算法·数学建模
伴杯猫11 小时前
【ESP32-IDF】基础外设开发2:系统中断矩阵
c语言·单片机·嵌入式硬件·mcu·物联网·github
搬砖的小码农_Sky11 小时前
常见的显示器接口技术
嵌入式硬件·计算机外设·显示器
茯苓gao11 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
点灯小铭13 小时前
基于STM32单片机的智能粮仓温湿度检测蓝牙手机APP设计
stm32·单片机·智能手机·毕业设计·课程设计
沐欣工作室_lvyiyi13 小时前
基于单片机的智能路灯(论文+源码)
单片机·嵌入式硬件·毕业设计