正点原子STM32 USART1_IRQHandle函数理解

看了正点原子STM32串口通信这节视频,看到了中断服务函数这里,死活理解不了,它定义的这个小协议,我还是一直懵逼的,找了点资料,研究了下,终于理解了,记录一下,以便之后有时间的时候再次复习。函数如下:

void USART1_IRQHandler(void) //串口 1 中断服务程序
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
//接收中断(接收到的数据必须是 0x0d 0x0a 结尾)
{
Res =USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据
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;//接收数据错误,重新开始接收
      }
      }
     }
  }
}
假设我们发送的数据是“abcd”经过串口调试助手加上0X0D+0X0A后发送给单片机,即单片机要接受的数据是“abcd”+“0X0D+0X0A

接收到“a”时读寄存器非空,RXNE为1,第一次进入串口中断处理函数,我们先判断是否接是因为USART1接受到了数据产生的中断,如果是,则将USART1接受到的一位数据“a”存入变量Res里(Res = “a”)。

u16 USART_RX_STA=0;  我们在前面定义了,然后USART_RX_STA与上0x8000等于0,进入if(USART_RX_STA&0x4000),0与上0x4000还是等于0,我们在C语言里面规定0是假,非0是真。这里不成立,然后进入下面的else,先是if(Res==0x0d),也就是判断是否收到了0x0d,收到了就执行后面的USART_RX_STA|=0x400,这句话的意思是把第14标记为1,之前就是突然搞忘了这句话可以这样写USART_RX_STA=USART_RX_STA|0x4000,导致卡了一下,USART_RX_STA与上0100 0000 0000 0000  (与的意思就是有1则1),然后我们的第14位就被置为1了。这里是先解释。因为我们还没有收到0x0d,继续执行后面的else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
   }

我们这里是根据数据的大小来自定义数组的大小,一开始USART_RX_STA等于0,0与上0X3FFF还是0,我们就定义了一个USART_RX_BU[0]大小的数组,然后USART_RX_STA++;为1,回到了上面去了,if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;这里需要理解一下,USART_REC_LEN-1,因为我们的数组是从0开始的,如果我们定义了USART_RX_BU[9],我们就是有10个元素,所以要USART_REC_LEN-1。继续发送b.c.d。发完了,到0x0d了,然后执行这句USART_RX_STA&0x8000)==0,USART_RX_STA此时等于4,因为USART_RX_STA++了四次,与上0x8000还是等于0,继续执行if(USART_RX_STA&0x4000),4与上0x4000为假,因为与了之后为0,不执行,执行后面的else

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;//接收数据错误,重新开始接收
      }
      }
     }
  }
}

因为收到了0x0d,执行if(Res==0x0d)USART_RX_STA|=0x4000;这一句就是把USART_RX_STA14位置为1,我们上面已经说了。然后USART_RX_STA14位为1了,不执行下面的了。跳回到上面去了,与上if((USART_RX_STA&0x8000)==0)还是为0,因为我们是14位为1,这里是15位1,与上还是0,然后到了这句if(USART_RX_STA&0x4000),这句终于要被执行了,USART_RX_STA14位为1了,与上0x4000不为0,就是真,执行改句if(USART_RX_STA&0x4000),然后下面就是把15置为1,我们接收就完成了。

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值