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空闲中断不定长度数据接收和发送
相关推荐
移远通信17 小时前
显示器-调试
单片机·嵌入式硬件·计算机外设
Szime1 天前
全球首创10位40GSPS超宽带ADC选型参考:国产超高速ADC深智微科技选型支持
科技·单片机·嵌入式硬件·fpga开发
(Morgan)1 天前
51单片机期末复习知识点总结
stm32·单片机·嵌入式硬件
榴莲llll1 天前
应用于计时器/微波炉等产品的高亮LED数显驱动VK16K33C 数码管屏显驱动芯片
单片机
华一精品Adreamer1 天前
T606 vs 骁龙662/RK3566:主流安卓+4G定制平板芯片横向测评指南
单片机
Zyed1 天前
[STM32]Day9-Part1USART+串口接收+串口收发
stm32·单片机·嵌入式硬件
小慧10241 天前
手动建立工程模板
stm32·单片机
嵌入式ZYXC1 天前
STM32烧录一次后无法再次烧录的两种原因
stm32·单片机·嵌入式硬件
踏着七彩祥云的小丑1 天前
嵌入式测试学习第33 天:压力测试、反复开关机、反复插拔接口测试
单片机·嵌入式硬件·学习
布子麟1 天前
NodeMcu(ESP8266)之更新固件
单片机·物联网·iot