STM32串口中断服务函数详解(含包头,包尾教程)

     引言

      串口通信我相信很多小伙伴已经或多或少有所了解,但我相信大多数小伙伴仍然停留在只做C/V工程师。在这里我想说,在串口通信中除了串口中断服务函数外你都可以不去深究,但一定要会写会分析串口中断服务函数!!!!

串口中断服务函数是在串口通信中处理接收数据的重要部分。

注意:当你不了解  中断标志位,FIFO,串口协议等

中断服务函数

  1. 定义与功能

    • 串口中断服务函数是当串口接收缓冲区中有数据到来时,针对接收中断标志位做出相应的动作的函数。
    • 它负责将数据读入串口接收缓冲区中,并通过FIFO等数据结构进行处理。
    • 在接收数据过程中,接收中断服务函数还需要进行数据的校验、解码以及数据的存储等操作。
  2. 运行逻辑

    • 当串口接收到数据时,会触发接收中断。
    • 串口中断服务函数会检查接收中断标志位的状态,如果标志位被设置(表示有数据到来),则执行中断服务函数。
    • 在中断服务函数中,首先读取接收到的数据,并根据预设的协议或规则对数据进行处理。
    • 数据处理可能包括校验、解码、存储到缓冲区等操作。
    • 处理完成后,通常会清除接收中断标志位,以便接收下一个数据。
  3. 状态标记与数据处理

    • 串口中断服务函数通常会使用状态标记(如USART_RX_STATE)来跟踪接收状态,如接收是否完成、是否接收到特定字符等。
    • 状态标记可能是一个多位寄存器,其中每一位代表不同的状态信息。
    • 根据状态标记的值,中断服务函数会执行不同的操作,如开始接收数据、继续接收数据、结束接收数据等。

代码讲解与展示 

参考文章中的代码示例(如USART1_IRQHandler函数)展示了串口中断服务函数的基本结构和运行逻辑。在实际应用中,开发人员可以根据具体需求对中断服务函数进行定制和优化,这也证明了串口中断服务函数的定制性!接下来我们从代码开始学习。

// RXState 用于变量标志位  
// pRxPacket 指示接收到的数据包的位数  
void USART1_IRQHandler(void)    
{  
	static uint8_t RxState = 0;     
	static uint8_t pRxPacket = 0;   
	if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)     
	{  
		uint8_t RxData = USART_ReceiveData(USART1);     
		if (RxState == 0)   
		{   
			if (RxData == 'A' && Serial_RxFlag == 0)     
			{  
				RxState = 1;      
				pRxPacket = 0;     
			}  
		}  
		else if (RxState == 1)   
		{  
			if (RxData == 'D')  
			{    
				RxState = 2;  
			}  
			else        
			{  
				Serial_RxPacket[pRxPacket] = RxData;    
				pRxPacket ++;    
			}  
		}  
		else if (RxState == 2)   
		{   
			if (RxData == '\n')  
			{  
				RxState = 0;  
				Serial_RxPacket[pRxPacket] = '\0';     
				Serial_RxFlag = 1;  
			}  
		}  
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);     
	}  
}

重要参数: 

首先你需要记住并学会使用的便是RxState(用于变量标志位)pRxPacket(指示接收到数据位的包数)RxData(记录串口接收的数据)。在日后或今天你凡是在写串口中断服务函数便会用到!

USART_GetITStatus函数

if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET) 

if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)     
	{  
		// 从USART1的接收数据寄存器中读取数据  
		uint8_t RxData = USART_ReceiveData(USART1);  
    }

首先解释 USART_GetITStatus(USART1, USART_IT_RXNE)。当我们串口1接收到信息后,检查接收缓冲区非空中断被触发------>接收到的信息被存入接收缓冲区------->再通过data将缓冲区的数据读取出来。这样它即实现了检验串口是否接收到信息,还可以实现将数据读出来储存起来。

RxState的状态

接下来我们将学习通过RxState的状态来处理接收到的数据。

if (RxState == 0)    // 如果当前状态为0  
        {  
            // 检查接收到的数据是否为'A',并且Serial_RxFlag是否为0(避免重复处理)  

这样我们就成功将包头设置为A。
            if (RxData == 'A' && Serial_RxFlag == 0)     
            {  
                // 如果条件满足,将RxState设置为1,表示开始接收数据包  
                RxState = 1;      
                // 重置接收数据包的索引为0  

               //这样子表示我们接收到的数据重新计算,开始接收数据。
                pRxPacket = 0;     
            }  
        }  

if (RxState == 1)   // 如果当前状态为1  
        {  
            // 检查接收到的数据是否为'D'  
            if (RxData == 'D')  
            {  
                // 如果条件满足,将RxState设置为2,开始进入数据整合过程。

                //并出现包尾D  
                RxState = 2;  
            } 

else        
            {  
                // 但如果不是'D',则将接收到的数据存储在Serial_RxPacket数组中  
                Serial_RxPacket[pRxPacket] = RxData;    
                // 增加接收数据包的索引,以便存储下一个字节  

                //这样子便实现了记录我们发送数据的内容。一直循环直到出现包尾D
                pRxPacket ++;    
            }  

else if (RxState == 2)    // 如果当前状态为2  

//但是在很多时候我们所发送的数据中包含D,这样子会导致我们的串口发送提前结束,所以我们引入二次确认,即再加一个包尾的包格式。
        {  

            //在满足检测到D后
            // 检查接收到的数据是否为换行符'\n'  
            if (RxData == '\n')  
            {  
                // 如果条件满足,将RxState重置为0,表示数据包接收完成  
                RxState = 0;  
                // 在数据包末尾添加空字符'\0',以便后续处理  
                Serial_RxPacket[pRxPacket] = '\0';     
                // 设置Serial_RxFlag为1,表示数据包已准备好供其他函数处理  
                Serial_RxFlag = 1;  
            }  
        }  

中断服务结束

USART_ClearITPendingBit(USART1, USART_IT_RXNE);  一定要记得加这一句

最用非常的大:清除USART1的接收数据寄存器非空中断标志位  
                         在读取数据寄存器后完成,以确保不会立即触发另一个中断 

这就是全部过程了,你是否已经掌握,快上手试试吧!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值