目录
前文的发送已经很好的实现了发送一个数据,但是接收端仅介绍了每次接收一个字符,如果是双方通信,例如发送端以串口发送如下:
1,125,238,475,359
其中1表示命令号;125表示传感器1的数据,238表示传感器2的数据,475表示传感器3的数据,359表示传感器4的数据。
2,19,45,37,28
其中2表示命令号;19表示设定模块1数据,45表示设定模块2数据,37表示设定模块3数据,28表示设定模块4数据。
可以看到两个命令是不等长的(但是每一个相同命令号的应是等长的)
不等长意味着不能接收到第一个字符进行计数,固定长度后停止。
一、标志位结束法
1、实现原理
在数据尾部加入特殊字符,一般在工业界采用'\r''\n'来作为帧尾,也就是说串口收到数据后进行数组的存储,当连续收到\r\n,则表示该帧结束。

2、代码
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
在主函数判断即可实现。
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
printf("\r\n您发送的消息为:\r\n\r\n");
for(t=0;t<len;t++)
{
USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
USART_RX_STA=0; //一定要清除接收标志
}
3、优缺点
优点:
-
易于解析:
- 固定的结束符:使用固定的字符如
\r\n作为帧结束符,可以让接收端程序简单地检测到数据
- 固定的结束符:使用固定的字符如

最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



