请求拍砖,看我写的串口接收程序的可靠性及容错性
/*1、Uart_RxBuf为接收缓冲区(来中断之后数据就放进去,本函数作为一个任务隔一段时间去缓冲区中读);
2、Uart_RxHead和Uart_RxTail分别是读开头和接收结尾
3、数据帧格式:帧起始符 控制码 数据域长度 校验码 结束符
68H C L(0到6之间) CS 16H
*/
int Uart_Read(char *Buffer)
{
int Length = 0,i;
INT8U Pos;
while((Uart_RxHead != Uart_RxTail)&&(Uart_RxBuf != 0x68))//有新的数据进入缓冲区且开头不是以68开始
{
Uart_RxHead++;//丢掉该字节不读
}
Pos = Uart_RxHead;//保证开头是0x68
while(Pos != Uart_RxTail)//看缓冲区中已接收的未读数据长度
{
Length++;
Pos++;
}
if(Length < 5) return 0;//长度不到最小长度,目的是保证已收到帧长度L字段
if(Uart_RxBuf < 7)//判断帧长度字段Uart_RxBuf是否在0到6之间
{
if(Length < (5+Uart_RxBuf)) return 0;//是否接收到一帧的长度5+Uart_RxBuf 否则不读 等待下次再读
else//有长度字段所指的完整一帧长度
{
Length = Uart_RxBuf;
if(Uart_RxBuf == 0x16)//判断某一确定位置是否是帧尾
{
for(i = 0; i < (Length+5); i++)//接收到了一帧 保存返回
{
*Buffer++ = Uart_RxBuf;//DATA字段可以有0x68 0x16
}
return (Length+5);//返回一帧数据处理 数据字段减33H 查CS校验码等
}
else//不是丢掉一字节
{
Uart_RxHead++;
return 0;
}
}
}
else//帧长度字段不在0到6之间
{
Uart_RxHead++;//丢掉一字节
return 0;
}
} 数据域长度后有个 数据域 DATA 你试试发一串68H 试试就知道了 我可以很清楚的告诉楼主,你的程序问题很大。如果你接收到的缓冲里面有很多68H和16H,而且数据缓冲不是从帧的第一个字节开始(可能发送过程中有中断)的话很多问题。你自己好好看一下吧。你取到第一个68H如果失败后,全部的数据都丢弃了。因此我说,你的通讯一旦失败必定很难恢复到正常状态。要看你接收程序是怎么写的还有一些超时的时序问题!你可以试试通讯过程中你用镊子短接一下发送和接收的两个脚,如果还正常就说明程序是基本问题不大的。 还是和地线短接吧 回复【2楼】coyool
你试试发一串68h 试试就知道了
-----------------------------------------------------------------------
没有问题
你取到第一个68H如果失败后,全部的数据都丢弃了---我这里没有丢全部数据的代码
所有的都是一个字节一个字节丢的
68H 68H 68H + 正常帧这样的 都是把68H一个字节一个字节丢掉的
Uart_RxHead++;//丢掉一字节 while(Pos != Uart_RxTail)//看缓冲区中已接收的未读数据长度
{
Length++;
Pos++;
}
if(Length < 5) return 0;//长度不到最小长度,目的是保证已收到帧长度L字段
这里有问题啊,很明显啊,你是全部都丢了,比如68H,00H,00H,16H,68H,00H,00H,16H,68H,00H,00H,16H 你检到第一个数据尾就结束了,不信你自己再试试,虽然机率不大,但68H后面5个里面有一个16H你就挂掉了,明白吗 回复【6楼】coyool
while(pos != uart_rxtail)//看缓冲区中已接收的未读数据长度
{
length++;
pos++;
}
if(length < 5) return 0;//长度不到最小长度,目的是保证已收到帧长度l字段
这里有问题啊,很明显啊,你是全部都丢了,比如68h,00h,00h,16h,68h,00h,00h,16h,68h,00h,00h,16h
-----------------------------------------------------------------------
我这里Uart_RxHead++;是丢的意思
while(pos != uart_rxtail)//看缓冲区中已接收的未读数据长度
{
length++;
pos++;
}
if(length < 5) return 0;
只是还在缓冲区里先不读而已,等接受超过5了再读的意思,Uart_RxHead并没有变,读的时候还是Uart_RxBuf,怎么会全部都丢了呢?我这里是没有全部丢的,全部是一字节一字节丢错误的的 mark
页:
[1]