对于串口中断函数USART_RX_STA接收标记位解析,费话不多说了,直接上代码。
#define USART1_REC_LEN 200
u8 USART1_RX_BUF[USART1_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
u16 USART1_RX_STA=0; //接收状态标记
void USART1_IRQHandler(void)
{ u8 Res;
if((USART_GetITStatus(USART1,USART_IT_RXNE))!=RESET) //判断串口是否接收到数据
{
Res = USART_ReceiveData(USART1);
printf("%c",Res); //接收到则打印回电脑端
}
if((USART1_RX_STA &0X8000)==0) //接收未完成
{
if(USART1_RX_STA & 0X4000) //接收到回车0x0d ,执行
{
if(Res!=0x0a) USART1_RX_STA=0;
else USART1_RX_STA |=0X8000;//完成数据接收,把USART1_RX_STA高bit[15]置1
}
else //没有接收到回车
{
if(Res==0x0d) //接收到回车(0x0d)
USART1_RX_STA |=0X4000; //则把USART1_RX_STA高bit[14]置1
else { //
USART1_RX_BUF[USART1_RX_STA&0X3FFF]=Res;
USART1_RX_STA++;
if(USART1_RX_STA>(USART1_REC_LEN-1))
USART1_RX_STA = 0; //加到200,会把标记清0
}
}
}
}
串口中断函数中USART_RX_STA关键点解析:
(1)USART_RX_STA这个在0~13位是用来存数据个数的,可以看到每次结束判断会有USART_RX_STA++;
而14、15位则是通过与运算来将高位置1
(2)Res这个是接收到的数据,可以看到有此函数
Res=USART_ReceiveData(USART1)
(3)USART_RX_BUF这个是用来保存接收到的数据的可以看到每次结束判断会有
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
这个也是精髓之处,故此通过上面分析,不难理解
①if(Res==0x0d)USART_RX_STA|=0x4000;
意为一旦接收到回车(这个是系统自动生成的0x0d数据),那么USART_RX_STA第14位会被置为1(也就是我们所谓的标记)
②if(USART_RX_STA&0x4000)//接收到了 0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else
USART_RX_STA|=0x8000; //接收完成了
}
这个就意味着第一个if条件满足了(前面分析了,第14位置为1标记好了),接下来就是所谓的“等待0x0a的到来(这个也是系统自动生成的而且是紧接着0x0d,没有紧接着收到的话那么就意味着接受错误)”那么一旦接受完了0x0d和0x0a那么就将第15位置1(也是我们所谓的标记)那么到这里数据就已经接受完毕。如果一直没按回车,一直在输入数字,也可以看到函数最后有这样一行if(USART1_RX_STA>(USART1_REC_LEN-1))//大于200,清0
USART1_RX_STA = 0;
把标记位清0,重新接收。