void USART1_IRQHandler(void) 串口中断服务函数详解

本文主要分析正点原子stm32的void USART1_IRQHandler(void) 函数

一下为源代码

void USART1_IRQHandler(void)                	//串口一中断服务函数
	{
	u8 Res;
#if SYSTEM_SUPPORT_OS 		如果SYSTEM_SUPPORT_OS为真支持OS.
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断,接收到的数据必须以0x0d  0x0a结尾
		{
		Res =USART_ReceiveData(USART1);	//读取接收到的数据
		
		if((USART_RX_STA&0x8000)==0)//接收未完成
			{
			if(USART_RX_STA&0x4000)//接收到了0x0d
				{
				if(Res!=0x0a)USART_RX_STA=0;//接受错误重新开始
				else USART_RX_STA|=0x8000;	//接收完成了
				}
			else //没有收到0X0D
				{	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
					{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收错误重新开始接收  
					}		 
				}
			}   		 
     } 
#if SYSTEM_SUPPORT_OS 	//如果SYSTEM_SUPPORT_OS为真支持OS.
	OSIntExit();  											 
#endif
}
下面我们开始一步一步地对这个程序作解释
1、定义了一个Res用于在Res =USART_ReceiveData(USART1);中存储串口1发送的数据,注意这里的数据是按位进行发送的。
2、使用if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 经过USART_GetITStatus我也不知道判断了什么?
3、利用USART_ReceiveData(USART1)将通道1发送的数据存储到Res中
4、在这里先给大家讲解下USART_RX_STA的作用,USART_RX_STA一共有16位,前两位为标记位,后14位记录了串口发送的数的位数。第一位标记位标记了Res是否为0x0a,第二位标记位标记了Res是否为0x0d。具体为什么在接下来的讲解中会给大家讲。
以下为整篇文章的重点
		if((USART_RX_STA&0x8000)==0)//接收未完成        if1
			{
			if(USART_RX_STA&0x4000)//接收到了0x0d        if2
				{
				if(Res!=0x0a)USART_RX_STA=0;//接受错误重新开始      if3
				else USART_RX_STA|=0x8000;	//接收完成了         else1
				}
			else //没有收到0X0d   else2
				{	
				if(Res==0x0d)USART_RX_STA|=0x4000;                       if4
				else                               //else3
					{ 
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收错误重新开始接收  if5
					}		 
				}
			}  

首先让我们回到USART_RX_STA变量的起点u16 USART_RX_STA=0; //接收状态位标记

u16 USART_RX_STA=0;       //接收状态位标记 

if1使用USART_RX_STA&0x8000==0判断USART_RX_STA的第一位是否为0,这时因为USART_RX_STA的初始值为0,所以我们进入if2.
if2使用USART_RX_STA&0x4000判断USART_RX_STA的第二位是否为1,与if1类似所以我们进入else2.
else2中首先用if4判断了Res是否0x0d /0x0d 和0x0a 分别为回车和换行字符/ 即Res是否为回车,这里如果串口有输入数据的话明显是否的,所以我们进入else3.
else3为本篇代码的精髓所在,首先USART_RX_BUF[ ]是在前面定义的一个最大为USART_REC_LEN的数组,而USART_RX_STA&0X3FFF即得到USART_RX_STA变量的后14位记录串口已输入数据位数的大小。以USART_RX_STA作为USART_RX_BUF[ ]的下标,再配合上下一句的USART_RX_STA++;可以完美的把数据存储到USART_RX_BUF[ ]数组中。最后的if5则控制着输入数据的长度防止其超过USART_RX_STA的14位数据记录位的大小。
而后便是不断地从串口接收数据,不断去判断是否为串口发送数据的最后一位。如果是则在倒数第2次循环中使用USART_RX_STA|=0x4000;将第二位状态标志位置为1;在倒数第1次循环中使用USART_RX_STA|=0x8000;将第一位状态标志位也置为1,;而后串口数据接收结束,所有从串口接收的数据保存在USART_RX_BUF[ ]数组中,串口所发送的数据长度保存在USART_RX_STA的后14位中。
由于两个这两个变量都是宏定义,所以原子哥在main.c中就直接使用了它们,这里要注意的点就是USART_RX_STA只有后14位为记录串口所发数据长度的数据位,所以在使用时切记不要直接使用USART_RX_STA而是USART_RX_STA&0x3fff 得到USART_RX_STA后14位的数据位。

再次感谢原子哥开源的代码
以上

  • 18
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值