问题背景
u16 USART_RX_STA=0; //接收状态标记
USART_RX_STA的作用就是在全部函数之间实现一个消息传递,自己设置,自己管理,自己识别。
USART_RX_STA
bit15 | bit14 | bit13~0 |
---|---|---|
接收完成标志0x0a | 接收到0X0d标志 | 接收到的有效数据个数 |
问题
在串口中断函数里的一个全局变量USART_RX_STA,阅读串口中断函数里的程序时在想:USART_RX_STA里的数据是如何存入里面的,bit15接收完成标志位是从寄存器里取出来的?
解决
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
if( USART_GetFlagStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)(0x0D是回车的ASCLL码,0x0A是换行的ASCLL码)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成 1000 0000 0000 0000
{
if(USART_RX_STA&0x4000)//接收到了0x0d 0100 0000 0000 0000
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始--接收到了0X0D但是没有接受到0x0A
else USART_RX_STA|=0x8000; //接收完成了--0x0d后面是0x0a
}
else //还没收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000; //再次判断这次接收到的是不是0x0d
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ; // 0011 1111 1111 1111
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
我们来彻底的理一下上面程序的逻辑:假设我们第一次接收数据。接收的数据为abcd。
①在第一次进入串口中断处理函数,我们先判断是否接是因为USART1接受到了数据产生的中断
【if(USART_GetFlagStatus(USART1, USART_IT_RXNE) != RESET)】
如果是,则将USART1接受到的一位数据(a)存入变量Res里(Res = “a”)
②然后我们来判断接收的一系列数据是否没接收完。(当然没有啦,我们还有b、c、d三个数据没有接收)
【if((USART_RX_STA&0x8000)==0) //接收未完成 】
这个时候呢,USART_RX_STA——这个在全部函数之间实现消息传递的变量的值仍然为0,和0x8000相与以后为0,那么执行该if语句的内层函数。
要坚持继续向下看呀↓看到后面就会理解的。
③进入该if语句的内层语句后又是一个判断语句
【if(USART_RX_STA&0x4000)//接收到了0x0d】知识点:0x0d是回车的ASCLL码,0x0a是换行的ASCLL码
这里判断USART_RX_STA的第14位是否为1,如果我们接收到了回车,即0x0d那么USART_RX_STA的第14位会置1。在我们接收第一个数据a时USART_RX_STA当然还为0,(我们后面的的b、c、d、3个数据还都没接收了,当然不会收到0x0d)USART_RX_STA和0x400相与为0,该判断语句就为假,执行下面的else语句。
④该else语句的内层语句是一个if-else语句
【if(Res==0x0d)USART_RX_STA|=0x4000; 】
这里我就不再赘述,我们接收的是数据a,还没有接收到0x0d,执行else语句。
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ; // 0x3ff = 0011 1111 1111 1111
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
如果忘记USART_RX_STA里十六位数据分别是什么意思的话可以翻到最上面回顾一下
USART_RX_STA的bit0~bit13代表的是接收到的有效数据个数,这里USART_RX_STA值仍为0,USART_RX_STA & 0X3FFF = 0 ,然后USART_RX_BUF[USART_RX_STA&0X3FFF]=Res,意思就是将Res里的数据存放到USART_RX_BUF[0]里了,并且USART_RX_STA自增1。
此时USART_RX_STA = 1这样在接收到下一个数据b后USART_RX_STA&0X3FFF = 1,将b存入到了USART_RX_BUF[1]里,一直循环下去,直到我们接收到了0x0d(Res = 0x0d)。
我们可以从上面程序里找到如下代码:
else //还没收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000; //再次判断这次接收到的是不是0x0d
当接收到0x0d并且程序执行到这一步一时USART_RX_STA = 4,此时该if语句成立,执行USART_RX_STA|=0x4000,即0000 0000 0000 0100 | 0100 0000 0000 0000 = 0100 0000 0000 0100 ,我们可以清晰的看到bit13~0位是4,代表接收到了4个数据(a,b,c,d),第14位为1,是因为接收到了数据0x0d,也和最上面给的表对上了,然后程序向下执行,接收到了0x0d(回车),那下一个就是接收0x0a(换行)了,Res = 0x0a(跑呀跑,执行到这里了):
if(USART_RX_STA&0x4000)//接收到了0x0d 0100 0000 0000 0000
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始--接收到了0X0d但是没有接受到0x0a
else USART_RX_STA|=0x8000; //接收完成了--0x0d后面是0x0a
}
这里第一个判断语句if(USART_RX_STA&0x4000),当然为真,因为Res = 0x0a,那么执行else语句USART_RX_STA|=0x8000,即0100 0000 0000 0100 | 1000 0000 0000 0000 = 1100 0000 0000 0100。到了这一步,就说明这一串数据已经完完全全的接收完了USART_RX_STA = 1100 0000 0000 0100,最高位为1:代表接收到了0x0a,第十四位为1:代表接收到了0x0d,第0位到第13位为4,代表接收到了4位有效数据(a、b、c、d),再次把那个表格放出来我们对比一下:
USART_RX_STA
bit15 | bit14 | bit13~0 |
---|---|---|
接收完成标志0x0a | 接收到0X0d标志 | 接收到的有效数据个数 |
这样我们这个串口1中断服务程序函数已经完完全全的理解了!!!
结尾
emmm…没有什么可说的了,有强迫症,必须要格式好看(╥╯^╰╥)。
版权声明:本文为CSDN博主「森 屿 麋 鹿」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/milu_yu/article/details/108523888
暂无评论