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);
}
相关推荐
AOI小白新手上路7 小时前
江科协51单片机 17-2 红外遥控电机调速实验调试总结
单片机·嵌入式硬件·51单片机
oshan20129 小时前
零基础STM32入门教程--10-PWM 呼吸灯
stm32·单片机·嵌入式硬件
记帖10 小时前
STM32C5A3R开发(7)----ADC电压采集
嵌入式硬件·adc·dac·stm32cubeide·stm32c5·stm32cubemx2·stm32c5a3rgt6
自小吃多12 小时前
器件移动、旋转、镜像、对齐、等间距操作笔记
笔记·嵌入式硬件
jianqiang.xue13 小时前
智能体整体架构设计:四大模块与目录组织
单片机·嵌入式硬件·物联网·架构·esp32
Messy create15 小时前
【BMS-AFE-温度检测】
stm32·单片机·能源
东莞市永盛电气15 小时前
三相208V变380V变压器,出海工业设备供电适配方案
python·单片机·嵌入式硬件
桃蹊、16 小时前
串口/网络透传实战:FreeRTOS 多任务架构与连接池设计
stm32·物联网·wifi·freertos
Learn-Share_HY16 小时前
[IT Network]如何配置反向路徑過濾器(rp_filter),以解決路由不對稱問題?
linux·嵌入式硬件·物联网·网络协议·tcp/ip·http·iot
深圳市宝华视联17 小时前
医院内网部署手术示教系统注意事项
嵌入式硬件·实时互动·音视频·实时音视频·视频编解码·嵌入式实时数据库