最近在做485数据通讯,遇到一些通讯问题,特意去查找资料,一帧数据接收有三种方法,现分享如下:
第一种方法:根据帧头和帧尾进行校验,
串口发送2字节例如(AA ,BB),然后程序对每2个字节进行判断,例如设定一个起始位例如AA,当程序收到AA,起始条件成立,开始接收数据,在设定一个终止位BB,当程序收到BB,终止条件成立,程序停止接受数据,然后把收到的数据放到一个数组里面,对收到的数据进行CRC校验,校验成立,则对收到的数据进行处理
程序如下:
if(USART_GetITStatus(RS485_USART_SOURCE, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(RS485_USART_SOURCE, USART_IT_RXNE);
if(USART_GetFlagStatus(RS485_USART_SOURCE, USART_FLAG_ORE) != RESET) //Òç³ö´íÎó±ê־λ
{
USART_ClearFlag(RS485_USART_SOURCE, USART_FLAG_ORE);
}
temp_rec = USART_ReceiveData (RS485_USART_SOURCE);
switch(temp_rec)
{
case __Start://ÊÕµ½Æðʼ룬½ÓÊÕÊý¾Ý¿ªÊ¼
if(!CommuSta.bRecOn)
{
CommuSta.bRecOn = SET;// ±íʾÕýÔÚ½ÓÊÕÊý¾Ý
len = 0;
aRxBuf[len++] = temp_rec;
}
break;
case __Stop://ÕÒµ½ÖÕֹ룬½ÓÊÕÊý¾Ý½áÊø
if(CommuSta.bRecOn)
{
CommuSta.bRecOn = RESET; // ½ÓÊÕÊý¾Ý½áÊø
CommuSta.bRecEnd = SET; // Ò»Ö¡Êý¾ÝÊÕÍê
aRxBuf[len] = temp_rec;
gRecBufLen = ++len;
len = 0;
}
break;
但是程序出问题了,原因是发送过来的指令起始位与终止位之间有字节与起始位或终止位相同,l例如7E(起始位) 01 B4 03 +CRC校验(CD 7E)+7F(终止位),CRC校验的7E与起始位相同,程序接收数据又重新开始,所以出错,因为是一个字节一个字节的接收数据,所以对帧头和帧尾进行判定有时会出错。
第二种方法:使用串口帧空闲中断
使能串口帧空闲中断,当接收一帧数据后,串口会产生一次中断,根据是否产生中断来判断是否接收一串完整的数据,这种方法不存在方法1的问题,推荐使用
第三种方法:根据接收到的字符之间的间隔进行判断
串口数传输都是使用标准波特率,因此串口传输一帧数据时,字符与字符之间的时间间隔是一个固定值,我们可以根据串口的波特率去计算串口每个字符的间隔时间,在数据接收的过程中判断接收的两个字节之间间隔大于3.5个字符间隔时间,则认为当前数据帧传输完毕