usart 学习笔记

void USART1_IRQHandler(void)                //串口1中断服务程序
{
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

#endif



解读:

怎么写接收函数?

只要收到一个字节 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


本次实验的一个数据处理技巧:USART_RX_STA 

这个变量可以标志两个状态,还可以记录数据长度,很好的节省了空间

正常情况下有两个变量标志状态,还有一个变量记录数据;








猜你喜欢

转载自blog.csdn.net/shenlong1356/article/details/79940280