搜索
bottom↓
回复: 12

请教win32 API串口编程检测数据丢失的办法

[复制链接]

出0入0汤圆

发表于 2013-2-22 14:28:16 | 显示全部楼层 |阅读模式
单片机通过串口要往PC传送大量数据,把数据分成定长的包往上发,有包头和包尾,上位机接收以后发现没问题就让下位机继续发,有问题就让下位机重发。现在的问题就是定长的数据偶尔会丢失,在win32 API的串口程序中有没有什么办法检测数据丢失了。是不是通过超时设置函数SetCommTimeouts来处理的?如果是的话,具体是怎么处理的。如果不是,那用什么办法来检测下位机有数据没发上来呢。

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

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2013-2-22 14:33:56 | 显示全部楼层
本帖最后由 mingqiang 于 2013-2-22 14:35 编辑

因为数据包是定长的,如果发上来的数据长度不够,就一直等着下位机发数据上来,接收够了上位机才会做出相应的处理。如果数据已经发完,但是发送的过程中丢失了数据,那么上位机就一直在傻等下位机的数据,而下位机也一直傻等上位机的指令。我现在就是想检测出数据丢失,然后上位机让下位机重发。

出0入0汤圆

发表于 2013-2-22 14:35:21 | 显示全部楼层
楼主能不能给个例子,我串口接收老是出问题

出0入0汤圆

发表于 2013-2-22 14:44:53 | 显示全部楼层
PC编程有个超时的概念,应用一下吧,楼主!

出0入0汤圆

 楼主| 发表于 2013-2-22 14:46:34 | 显示全部楼层
我也是参考的lishaoan的例子,网上一搜一大把。

出0入264汤圆

发表于 2013-2-22 14:48:08 | 显示全部楼层
收到一个字节后就启动定时器计时呗,超时了就重发,和单片机下的串口收发思路一致。

出130入129汤圆

发表于 2013-2-22 14:48:13 来自手机 | 显示全部楼层
真实串口还是转的?数据长度一帧多少

出0入0汤圆

 楼主| 发表于 2013-2-22 14:53:20 | 显示全部楼层
mcu_lover 发表于 2013-2-22 14:48
收到一个字节后就启动定时器计时呗,超时了就重发,和单片机下的串口收发思路一致。 ...

用time.h中的clock函数定时,超过指定时间就重发?

出0入0汤圆

 楼主| 发表于 2013-2-22 14:56:21 | 显示全部楼层
68336016 发表于 2013-2-22 14:48
真实串口还是转的?数据长度一帧多少

真实串口,数据长度一帧642字节。下位机的晶振是16M,波特率是115200,所以觉得有数据丢失很正常。

出0入264汤圆

发表于 2013-2-22 15:24:57 | 显示全部楼层
mingqiang 发表于 2013-2-22 14:53
用time.h中的clock函数定时,超过指定时间就重发?

settimer
killtimer 啊,处理WM_TIMER消息。
收到一帧数据的第一个字节时候就setttimer,当帧数据接收完成时候就killtimer,否则在WM_TIMER消息中killtimer并要求下位机重发数据帧。

出0入0汤圆

发表于 2013-2-22 17:12:01 | 显示全部楼层
timeout   

出0入0汤圆

 楼主| 发表于 2013-2-25 16:29:22 | 显示全部楼层
本帖最后由 mingqiang 于 2013-2-25 16:40 编辑

已经解决,用clock函数就可以了。相关的部分程序如下。
if(comstat.cbInQue == 0)//COMSTAT结构返回串口状态信息,cbInQue成员变量的值代表输入缓冲区的字节数       
        {
                 if(flagtime==0)
                    {
                       flagtime=1;       //标志,区别是否连续进入if(comstat.cbInQue == 0)
                       start=clock();
                       //printf("a\n");
                     }
                 else
            {                               
                end=clock();
                if((end-start)/CLOCKS_PER_SEC>0.01)     //单位是秒,可以精确到毫秒 ,这里定的是超过10ms没收到串口数据就执行如下操作
                    {
                        start=clock();        //重置起始时间
                WriteChar("b",1);  //下发“b”,告诉下位机重发
                    }                  
             }                       
               continue;
            }
flagtime=0;

出0入0汤圆

发表于 2015-8-8 08:56:49 | 显示全部楼层
mingqiang 发表于 2013-2-22 14:46
我也是参考的lishaoan的例子,网上一搜一大把。

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

本版积分规则

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

GMT+8, 2024-8-25 20:10

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

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