搜索
bottom↓
回复: 9

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

[复制链接]

出0入0汤圆

发表于 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[Uart_RxHead] != 0x68))//有新的数据进入缓冲区且开头不是以68开始
        {
                Uart_RxHead++;//丢掉该字节不读
        }
        Pos = Uart_RxHead;//保证开头是0x68
        while(Pos != Uart_RxTail)//看缓冲区中已接收的未读数据长度
        {
                Length++;
                Pos++;
        }
        if(Length < 5)        return 0;//长度不到最小长度,目的是保证已收到帧长度L字段
        if(Uart_RxBuf[Uart_RxHead+2] < 7)//判断帧长度字段Uart_RxBuf[Uart_RxHead+2]是否在0到6之间
        {
                if(Length < (5+Uart_RxBuf[Uart_RxHead+2]))        return 0;//是否接收到一帧的长度5+Uart_RxBuf[Uart_RxHead+2] 否则不读 等待下次再读
                else//有长度字段所指的完整一帧长度
                {
                        Length = Uart_RxBuf[Uart_RxHead+2];
                        if(Uart_RxBuf[Uart_RxHead+4+Length] == 0x16)//判断某一确定位置是否是帧尾
                        {
                                for(i = 0; i < (Length+5); i++)//接收到了一帧 保存返回
                                {
                                        *Buffer++ = Uart_RxBuf[Uart_RxHead++];//DATA字段可以有0x68 0x16
                                }
                                return (Length+5);//返回一帧数据处理 数据字段减33H 查CS校验码等
                        }
                        else//不是丢掉一字节
                        {
                                Uart_RxHead++;
                                return 0;
                        }
                }
        }
        else//帧长度字段不在0到6之间
        {
                Uart_RxHead++;//丢掉一字节
                return 0;
        }       
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2010-11-23 17:06:43 | 显示全部楼层
数据域长度后有个 数据域 DATA

出0入0汤圆

发表于 2011-6-24 14:04:07 | 显示全部楼层
你试试发一串68H 试试就知道了

出0入0汤圆

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

出0入0汤圆

发表于 2011-6-24 14:27:57 | 显示全部楼层
还是和地线短接吧

出0入0汤圆

 楼主| 发表于 2011-6-25 09:56:51 | 显示全部楼层
回复【2楼】coyool  
你试试发一串68h 试试就知道了
-----------------------------------------------------------------------

没有问题

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

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


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

Uart_RxHead++;//丢掉一字节

出0入0汤圆

发表于 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

出0入0汤圆

发表于 2011-6-27 20:28:27 | 显示全部楼层
你检到第一个数据尾就结束了,不信你自己再试试,虽然机率不大,但68H后面5个里面有一个16H你就挂掉了,明白吗

出0入0汤圆

 楼主| 发表于 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[Uart_RxHead],怎么会全部都丢了呢?我这里是没有全部丢的,全部是一字节一字节丢错误的的

出0入0汤圆

发表于 2012-2-28 19:54:03 | 显示全部楼层
mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 17:29

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表