STM32 HAL库配置DMA加空闲中断接收串口数据

一、在cubemx生成的初始化代码中加入DMA

复制代码
void MX_USART1_UART_Init(void)
{
	huart1.Instance = USART1;
	huart1.Init.BaudRate = 115200;

	huart1.Init.WordLength = UART_WORDLENGTH_8B;
	huart1.Init.StopBits = UART_STOPBITS_1;
	huart1.Init.Parity = UART_PARITY_NONE;
	huart1.Init.Mode = UART_MODE_TX_RX;
	huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	// huart1.Init.OverSampling = UART_OVERSAMPLING_16;
	if (HAL_UART_Init(&huart1) != HAL_OK)
	{
		Error_Handler();
	}

	// 启动DMA接收
	HAL_UART_Receive_DMA(&huart1, USART1_DMA_Buffer, USART1_DMA_BUFFER_SIZE);

	// 使能IDLE中断
	__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
}

二、在HAL_UART_MspInit()中修改

复制代码
else if (uartHandle->Instance == USART1)
	{
		/* USER CODE BEGIN USART1_MspInit 0 */

		/* USER CODE END USART1_MspInit 0 */
		/* USART1 clock enable */
		__HAL_RCC_USART1_CLK_ENABLE();

		__HAL_RCC_GPIOA_CLK_ENABLE();
		/**USART1 GPIO Configuration
		PA9     ------> USART1_TX
		PA10     ------> USART1_RX
		*/
		GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
		GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
		GPIO_InitStruct.Pull = GPIO_NOPULL;
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
		GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
		HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

		__HAL_RCC_DMA2_CLK_ENABLE();

		// 閰嶇疆DMA
		hdma_usart1_rx.Instance = DMA2_Stream2;
		hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4;
		hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
		hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
		hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
		hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
		hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
		hdma_usart1_rx.Init.Mode = DMA_NORMAL;
		hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
		hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

		if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
		{
			Error_Handler();
		}

		__HAL_LINKDMA(uartHandle, hdmarx, hdma_usart1_rx);

		/* DMA2_Stream2_IRQn interrupt configuration */
		HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
		HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);

		HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
		HAL_NVIC_EnableIRQ(USART1_IRQn);
	}

三、增加对应的DMA中断,这里是DMA2_Stream2_IRQHandler()

复制代码
void DMA2_Stream2_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&hdma_usart1_rx);
}

四、完善串口中断USART1_IRQHandler()

复制代码
void USART1_IRQHandler(void)
{
	// 检查是否是IDLE中断标志
	if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
	{
		// 清除IDLE标志
		__HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_IDLE);

		// 停止当前DMA传输
		HAL_UART_DMAStop(&huart1);

		// 计算接收到的数据长度
		uint16_t received_len = USART1_DMA_BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);

		// 将接收到的数据保存到UART1BUF缓冲区
		if (received_len > 0 && received_len <= UARTLEN)
		{
			// 将数据从DMA缓冲区复制到UART1BUF
			memcpy(UART1BUF, USART1_DMA_Buffer, received_len);
			UART1_byte_count = received_len;
			UART1RcvFg = 1; // 设置接收完成标志
		}

		// 重新启动DMA接收
		HAL_UART_Receive_DMA(&huart1, USART1_DMA_Buffer, USART1_DMA_BUFFER_SIZE);
	}

	// 处理HAL库相关中断
	HAL_UART_IRQHandler(&huart1);
}
相关推荐
泡泡糖的中文规格书1 小时前
【硬件设计】LM358DR2G中文文档深度解读:高质量翻译与芯片特性全解析
嵌入式硬件·规格说明书·电路设计·运放·中文翻译·datasheet
czwxkn2 小时前
2STM32(stdl)GPIO输入
stm32·单片机·嵌入式硬件
码农三叔3 小时前
(9-1)电源管理与能源系统:电池选择与安全
人工智能·嵌入式硬件·安全·机器人·能源·人形机器人
qq_246646195 小时前
openclaw快速安装-windows版
windows·stm32·单片机
染予6 小时前
13.AD软件操作:原理图如何导入PCB及导入常见错误
嵌入式硬件
小莞尔7 小时前
【51单片机】【protues仿真】 基于51单片机波形发生器系统
c语言·单片机·嵌入式硬件·物联网·51单片机
码农三叔7 小时前
(9-2-01)电源管理与能源系统:能耗分析与功率管理(1)步行能耗估计
人工智能·嵌入式硬件·机器人·人机交互·能源·人形机器人
Polanda。8 小时前
ADC-定时器触发
单片机·嵌入式硬件
-Springer-8 小时前
STM32 学习 —— 个人学习笔记1(STM32简介)
笔记·stm32·学习