chinaye1 发表于 2010-11-23 17:04:03

请求拍砖,看我写的串口接收程序的可靠性及容错性

/*
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;
        }       
}

chinaye1 发表于 2010-11-23 17:06:43

数据域长度后有个 数据域 DATA

coyool 发表于 2011-6-24 14:04:07

你试试发一串68H 试试就知道了

coyool 发表于 2011-6-24 14:24:38

我可以很清楚的告诉楼主,你的程序问题很大。如果你接收到的缓冲里面有很多68H和16H,而且数据缓冲不是从帧的第一个字节开始(可能发送过程中有中断)的话很多问题。你自己好好看一下吧。你取到第一个68H如果失败后,全部的数据都丢弃了。因此我说,你的通讯一旦失败必定很难恢复到正常状态。要看你接收程序是怎么写的还有一些超时的时序问题!你可以试试通讯过程中你用镊子短接一下发送和接收的两个脚,如果还正常就说明程序是基本问题不大的。

coyool 发表于 2011-6-24 14:27:57

还是和地线短接吧

chinaye1 发表于 2011-6-25 09:56:51

回复【2楼】coyool
你试试发一串68h 试试就知道了
-----------------------------------------------------------------------

没有问题

你取到第一个68H如果失败后,全部的数据都丢弃了---我这里没有丢全部数据的代码

所有的都是一个字节一个字节丢的


68H 68H 68H + 正常帧这样的 都是把68H一个字节一个字节丢掉的

Uart_RxHead++;//丢掉一字节

coyool 发表于 2011-6-27 20:25:45

while(Pos != Uart_RxTail)//看缓冲区中已接收的未读数据长度
{
Length++;
Pos++;
}
if(Length < 5) return 0;//长度不到最小长度,目的是保证已收到帧长度L字段

这里有问题啊,很明显啊,你是全部都丢了,比如68H,00H,00H,16H,68H,00H,00H,16H,68H,00H,00H,16H

coyool 发表于 2011-6-27 20:28:27

你检到第一个数据尾就结束了,不信你自己再试试,虽然机率不大,但68H后面5个里面有一个16H你就挂掉了,明白吗

chinaye1 发表于 2011-7-10 16:50:20

回复【6楼】coyool
while(pos != uart_rxtail)//看缓冲区中已接收的未读数据长度
{
length++;
pos++;
}
if(length &lt; 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 &lt; 5) return 0;

只是还在缓冲区里先不读而已,等接受超过5了再读的意思,Uart_RxHead并没有变,读的时候还是Uart_RxBuf,怎么会全部都丢了呢?我这里是没有全部丢的,全部是一字节一字节丢错误的的

rayaohb 发表于 2012-2-28 19:54:03

mark
页: [1]
查看完整版本: 请求拍砖,看我写的串口接收程序的可靠性及容错性