系统城装机大师 - 固镇县祥瑞电脑科技销售部宣传站!

当前位置:首页 > 系统教程 > 其它教程 > 详细页面

STM32基于HAL库串口空闲中断接收不定长数据

时间:2020-08-19来源:www.pcxitongcheng.com作者:电脑系统城

一、前言

  • 最近在使用STM32的HAL库的时候,发现竟然没有集成IDLE中断处理,本身写的HAL库处理逻辑就挺繁琐,效率又不高,还缺胳膊少腿的。平时项目中的串口接收数据都是不定长的,而IDLE中断在这一块作用是非常大的,可以大大简化数据接收过程的判断。本文将介绍基于HAL库IDLE中断接收不定长数据。

二、代码实现

  • 首先串口的初始化工作,在初始化过程中,我们需要开启两个中断,一个是UART_IT_RXNE接收中断,此中断是没接收到一个字节的数据接收产生一次中断,另一个是UART_IT_IDLE空闲中断,也就是我们今天的主角。每帧数据发送完成就会有空闲时期,一帧数据接收完成就会产生空闲中断。这里我们不使用 HAL_UART_Receive_IT()函数来初始化了,因为我们不用HAL库的那一套,直接进行中断开启。
void USART1_Init(uint32_t Bound)
{
	UART1_HandleStructure.Instance = USART1;
	UART1_HandleStructure.Init.BaudRate = Bound;
	UART1_HandleStructure.Init.WordLength = UART_WORDLENGTH_8B;
	UART1_HandleStructure.Init.StopBits = UART_STOPBITS_1;
	UART1_HandleStructure.Init.Parity = UART_PARITY_NONE;
	UART1_HandleStructure.Init.Mode = UART_MODE_TX_RX;
	UART1_HandleStructure.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	HAL_UART_Init(&UART1_HandleStructure);
	
	HAL_NVIC_EnableIRQ(USART1_IRQn);
	HAL_NVIC_SetPriority(USART1_IRQn,3,3);
	
	__HAL_UART_ENABLE_IT(&UART1_HandleStructure,UART_IT_RXNE);//接收中断
	__HAL_UART_ENABLE_IT(&UART1_HandleStructure,UART_IT_IDLE);//空闲中断
}
  • 下来是写我们的中断服务函数,我们直接在USART1_IRQHandler()里写我们的处理逻辑,不需要再调用HAL_UART_IRQHandler()函数。如果进入的是接收中断,我们把接收到的字节放入到缓冲区,如果接收长度超过了缓冲区字节就不再处理直接丢弃。如果进入的是空闲中断,则表示一帧数据接收完成,这时候调用我们的回调函数进行数据处理即可,一般是放到中断外进行处理,我这里为了简化所以直接写到中断里面了。注意清除IDLE的中断标志要使用__HAL_UART_CLEAR_IDLEFLAG()进行,不然会一直进入中断。
void USART1_IRQHandler(void)
{
	uint8_t res = 0;
	
	//接收中断
	if(__HAL_UART_GET_FLAG(&UART1_HandleStructure,UART_FLAG_RXNE) != RESET)
	{
		HAL_UART_Receive(&UART1_HandleStructure,&res,1,1000);
		//将数据放入缓冲区
		if(rxConut < RX_BUFFER_SIZE)
		{
			aRxBuffer[rxConut] = res;
			rxConut++;
		}
		
		__HAL_UART_CLEAR_FLAG(&UART1_HandleStructure,UART_FLAG_RXNE);
	}
	//空闲中断
	if(__HAL_UART_GET_FLAG(&UART1_HandleStructure,UART_FLAG_IDLE) != RESET)
	{
		//一帧数据接收完成
		USART1_IdleCallback(aRxBuffer,rxConut);
		rxConut = 0;
		
		__HAL_UART_CLEAR_IDLEFLAG(&UART1_HandleStructure);
	}
}
//回调函数
void USART1_IdleCallback(uint8_t *pData,uint16_t len)
{
	while(__HAL_UART_GET_FLAG(&UART1_HandleStructure,UART_FLAG_TC) != SET);
	
	HAL_UART_Transmit(&UART1_HandleStructure,pData,len,1000);
}

三、测试结果

  • 我设置的波特率为115200,数据发送间隔10ms,附上测试图。


心之所向,素履以往
分享到:

相关信息

  • ThinkPad蓝牙鼠标如何配对

    ThinkPad蓝牙鼠标如何配对解答步骤41U5008鼠标驱动官网地址: https://support.lenovo.com/en_US/downloads/detail.page?&LegacyDocID=MIGR-67201 第一种方式是比较传统的:使...

    2024-04-11

  • USB接口无法识别设备的解决方法

    故障现象: USB设备U盘、移动硬盘等插入后提示无法识别的设备,确认设备本身正常,设备可加电,或插入设备后加电但无任何反应,无法使用。新型号机器多表现为黄色USB接口存在此问题,...

    2024-04-11

系统教程栏目

栏目热门教程

人气教程排行

站长推荐

热门系统下载