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; //接收完成了
}
{
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
这个变量可以标志两个状态,还可以记录数据长度,很好的节省了空间
正常情况下有两个变量标志状态,还有一个变量记录数据;