**
**
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntEnter();
#endif
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;//接收数据错误,重新开始接收
}
}
}
}
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntExit();
#endif
}
其中 0D 0A这是自行定义的一种数据帧结束标志,不定义这个不没法判断你这一帧数据什么时候结束了, 0D 0A是什么东西咧,它就是我们的回车键的ASCII码, 0D回车,0A换行 像在windows超级终端里一条数据输入完按回车正好来了个0D 0A,表示数据发完了
0x0D(asc码是13) 指的是“回车” \r是把光标置于本行行首
0x0A(asc码是10) 指的是“换行” \n是把光标置于下一行的同一列
0x0D + 0x0A 回车换行 \r\n把光标置于下一行行首
\n是换行,英文是linefeed,ASCII码是0xA。
\r是回车,英文是carriage return ,ASCII码是0xD。
USART_RX_STA是16位的数据,原子定义了最高位15是接收完成标志位,USART_RX_STA[15]=1时表示接收完成。所以0x8000好理解吧,就是最高位为1其他都为0,跟USART_RX_STA相与,低15位都被置0了只留下最高位即接收完成标志位,所以就可以通过USART_RX_STA&0x8000这样的方式来判断是否接收完成。
USART_RX_STA与0X3FFF进行与运算是用来确定接收到的数据长度的,USART_RX_STA的每个bit的含义教程里面有详细的讲解。
下面转自一个解读:
解读:
怎么写接收函数?
只要收到一个字节 stm32会产生中断
进入中断编写
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
u16 USART_RX_STA=0; //接收状态标记
第一步判断标志位是否正的接收到
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
第二步 接收下数据
Res =USART_ReceiveData(USART1); //读取接收到的数据
第三步判断标志位USART_RX_STA 上次是否接收完成(上次接收完成了会把标志位置1)
if((USART_RX_STA&0x8000)==0)//接收未完成
其中USART_RX_STA 是自己定义的16位变量用于标志接收完成或者接收到0x0d 类似于自己定义了一个寄存器
第四步 判断标志位USART_RX_STA 上次是否接收到了0xod
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始 如果上次接收到了/r(0x0d)这次应该是/n (0x0a)
else USART_RX_STA|=0x8000; //接收完成了
否则上次没有接收到0x0d
if(Res==0x0d)USART_RX_STA|=0x4000; //判断本次是否接收到了0x0d
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ; //把接收到的数据存入buf缓存区
USART_RX_STA++; //记录接收的数据字节数量
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收 接收的数据不能无限制的大
}
总结
这样的编程方式其实利用了状态机思想,增强稳定性,减少错误
本次实验有两个状态bit15接收状态,bit14接收到/r状态
编程时应该观察两个状态,注意到临界态 切换状态
首先判断当前接收处于什么状态,而不是盲目的接收
1、首先观察bit15状态 如果处于接收态应该注意 观察下一个状态bit14 在满足条件时切换bit15
2、观察bit14状态 如果处于接收到了/r态 再应该判断接收值是否满足 切换bit15态的条件
如果处于没有接收到\r态,应该判断接收值是否满足切换bit14的条件
if(USART_RX_STA&0x4000)//上次接收到了0x0d /r
else USART_RX_STA|=0x8000; 改变接收状态bit15
if(Res==0x0d) 接收到了/r
USART_RX_STA|=0x4000; 切换状态bit14
https://blog.csdn.net/shenlong1356/article/details/79940280
版权声明:本文为博主原创文章,转载请附上博文链接!