STM32基于HAL库的串口接受中断和空闲中断

本文介绍了在STM32中处理串口接收的三种方法,包括基于结束符、定时器中断和串口空闲中断。针对没有固定结束符的16进制数据格式,作者推荐使用串口空闲中断,它在接收到一帧数据后,若串口在设定时间内保持空闲则触发中断,避免了定时器中断的不确定性。通过清除IDLE标志位,可以有效地控制数据包的接收。这种方法提供了一种硬件级别的优化,适用于连续且大小不固定的串口数据接收。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

在通信方面。UART由于全双工通信,可以同时接受数据和发送数据而被广泛使用。

而接受数据则又有很多种方法

比如:

<1>根据结束符判断,数据是字符串形式,所以一般串口接受的接受符就是"\r\n"  换成16进制ascil码显示就是 0X0D   0X0A (对应\r\n)

 <2>定时器中断,设计"喂狗信号量"也就是串口空闲的时间,在串口接受后的定时器里不断递减,减到零则判断接受完毕,接受数据则喂狗刷新递减时间。(这也是单片机常见的串口接受思路)

参考我51的工程:

单片机串口中断以及消息收发处理——对接受信息进行判断实现控制_昊月光华的博客-优快云博客_单片机串口中断怎么触发

 <3>STM32有很多种方式,前两种在某些情况都很可以用。

但是第一种只适用于判断结束符。在我最近做射频模块(RF)串口发送的数据(一种16进制的格式,没有\r\n的结束符)就受限了,另外第二种需要搭配定时器。而本次写作介绍的串口接受中断和空闲中断则让我感到满意  YYDS!!!

理解

串口接受中断 :

使能串口接受中断RXEN后,串口接受一个数据包 ,一帧 (通常 8位数据位,一位结束位)则进入中断。

以定时器2为例

使能

__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);

 实际处理函数

USART2_IRQHandler(void)

 在HAL库里这个函数是不能被重定义,在stm32f1xx_it.c里 加__weak 表示弱定义可被重写

__weak void USART2_IRQHandler(void)

串口空闲中断:

  在使能IDLE  ,在串口接受完一帧数据后,在一个字节的时间内串口保持空闲则触发串口空闲中断  

再次进入  USART2_IRQHandler(void)   

使能 

 __HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);

和串口接受数据的中断处理函数一样。 像是上面第二种方法的改进,因为第二种方法不知道定时多长时间,因为数据发送间隔大小不知道,只能估摸着一个值来通过衰减的“喂狗信号量”来判断。同样,如果数据太大且不停的发送则也不会空闲。

值得注意的是,串口接受完后空闲必须清除空闲标志位。通过读串口DR寄存器里的值来清除IDLE标志位,否则程序一直触发空闲中断。

比如串口中断处理代码(以串口三为例) 注意(用__weak修饰hal库stm32f1x_it.c里的以此重写)

void USART3_IRQHandler(void){
      uint8_t temp;
    if(huart3.Instance->SR & UART_FLAG_RXNE){
         Rx_uart3_signal=2;
         temp=huart3.Instance->DR;
        Rx_uart3_buf[Rx_uart3_cnt++]=temp; 
    }
    
    else if(huart3.Instance->SR & UART_FLAG_IDLE){
         temp=huart3.Instance->DR;
        Rx_uart3_signal=0;
		
		 
		
    }

}

通过Rx_uart3_signal=0判断一次接受完毕,在while中打印数据。给我的效果个感觉都非常不错,是第二种方法以硬件的方式(stm32自带的空闲中断)而不是定时器实现了数据包的接受。

参考

STM32串口之空闲中断_csdn_dx的博客-优快云博客_串口空闲中断

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值