请教一个关于串口通讯的问题

wjiwji 2016-01-12 02:37:44
本人在程序中要用到串口,在处理串口的过程中碰到一个令我感到极为疑惑的现象,希望有知道的大侠指点一下!
下面我将问题详细描述一下:处理串口的方式我参考了CSerialPort类,因为感觉CSerialPort类在接收方面效率较低,又不好怎么处理modbus rtu类的协议,所以我将接收方面做了修改,另外写串口没有在线程函数内。具体思路是:初始化串口后,建立读监视线程,调用WaitCommEvent函数,如果函数返回FALSE,调用GetLastError,如果为IO_PENDING,转入WaitForSingleObject后续处理,如果是其他,报错处理。如果WaitCommEvent返回TRUE,调用ClearCommError看cbInQue,如果为0,continue(和CSerialPort同)。接下来WaitForSingleObject阻塞线程等待,如果为OBJECT_0,调用接收函数RecvChar处理,RecvChar处理和CSerialPort有点不同,具体是在for(;;)中每次读1个字符,一直读缓冲区,直到cbInQue为0,再用Sleep等待5ms,如果确实无后续字符到达,结束接收并发送消息。(由于断定调用RecvChar时cbInQue肯定不为0,因为为0时监视线程continue掉了,同时后续的处理用到了即使为0仍等待5ms才判断结束,所以一开始没有cbInQue== 0的判断)。
我的问题是,当我在一收一发的应用中,发现当我发送一帧查询命令,程序收到了两次通知接收的消息。第一条消息后,数据全部被接收,是完整的,第二次接收长度为0。按照程序的设想,在RecvChar处理过程中,后续字符可能到达,并置位EV_RXCHAR,和WaitForSingleObject中的事件,当从RecvChar返回监视线程,WaitCommEvent应该返回TRUE,并continue掉,根本不会发出第二条通知接收的消息。但是情况是第二条消息确实发出了。我猜测除非是这样一种情况:在调用RecvChar处理接收时,每调用一次ReadFile系统都清除一次EV_RXCHAR,由于在WINDOWS中EV_RXCHAR产生的次数总是等于或比接收到的字符数少(这点和单片机不同),这样在RecvChar返回时已经没有EV_RXCHAR了,只有WaitForSingleObject中的事件了(ReadFile并不复位这一事件)。再返回监视线程时,调用WaitCommEvent结果是FALSE,转入WaitForSingleObject处理,触发了第二次读,因为缓冲区没有字符,所以仅触发了一次接收消息。由于没有找到EV_RXCHAR触发,复位的相关信息,所以不知道自己的猜测对不对,还望知道的回复一下!
...全文
1131 4 点赞 打赏 收藏 举报
写回复
4 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
串口收发,俺习惯 发送---主动调用 接收---线程接收 在主程序中不停的判断某一帧是否接收完成。 使用多级大缓冲,一级只管接收,循环缓冲区,大小为2^n字节,一般为64K字节,用一个unsigned short的变量当成写入下标。 for( 本次接收的数量 ) buffer_level_1[ io_read++ ] = 本次接收的字符[ i ]; 1级存放完整的数据 根据业务要求,再设置2级,或3级缓冲,有时发送一条,会收到多条响应,那么2级中就会存放分成帧的数据,一般还是在线程中进行分帧,只要io_read与io_recv不一致,则在线程中不停的等待。
  • 打赏
  • 举报
回复
阿先森 2016-04-29
  • 打赏
  • 举报
回复
wjiwji 2016-01-12
我说的跟流控没多大关系吧,我没有用到这个
  • 打赏
  • 举报
回复
赵4老师 2016-01-12
搜“Xon Xoff”
  • 打赏
  • 举报
回复
相关推荐
发帖
硬件/系统
创建于2007-09-28

2598

社区成员

VC/MFC 硬件/系统
申请成为版主
帖子事件
创建了帖子
2016-01-12 02:37
社区公告
暂无公告