关于串口数据接收的问题,外部发一次数据,会响应多次的问题

coldant 2007-12-27 08:19:56
我在另一台电脑发送数据的时候,在本机上用串口调试工具接收显示完全正确.
我在程序用接收的时候出现了些问题,外部发送来的数据,长度不一定,最长的22个字节,最短的也有10个字节.但是程序执行的时候,
消息响应出现问题,经常会响应多次消息,如果我发22个字节的话,那么程序可能会响应多次.不知道为什么呀,哪位大哥能帮忙告诉点经验,谢谢了.



virtual DWORD ThreadFunc()
{
if(!::SetCommMask(_hCommHandle, _dwMaskEvent))
{
char szBuffer[256];
_snprintf(szBuffer, 255, "%s(%d) : COM%d Call WINAPI SetCommMask(%x, %x) Fail, thread work invalid! GetLastError() = %d;",
__FILE__, __LINE__, _dwPort, _hCommHandle, _dwMaskEvent, GetLastError());
MessageBox(NULL, szBuffer, "Class cnComm", MB_OK);
return 1;
}

COMSTAT Stat;
DWORD dwError;

for(DWORD dwLength, dwMask = 0; _fRunFlag && IsOpen(); dwMask = 0)
{
if(!::WaitCommEvent(_hCommHandle, &dwMask, &_WaitOverlapped))
{
if(::GetLastError() == ERROR_IO_PENDING)////// asynchronous
::GetOverlappedResult(_hCommHandle, &_WaitOverlapped, &dwLength, TRUE);
else
continue;
}


if(dwMask == 0)
continue;

switch(dwMask)
{
case EV_RXCHAR :
::ClearCommError(_hCommHandle, &dwError, &Stat);
if(Stat.cbInQue > 0)//此处,如果外部发送22个字节,Stat.cbInQue第一次的值一 般为8,然后执行一次OnReceive()后在返回上层for循环.如果这里改成Stat.cbInQue >=22的话,问题基本解决,但是外面发的消息长度小于22的,就不准确了,经常接收不到,也不准确.下断点的时候,Stat.cbInQue的直,在第2次for循环后往往比外面发来的消息的直大很多.但是正常情况下, 比方说if(Stat.cbInQue >=22),Stat.cbInQue的值比22大很多,但是读出来的那22个字节却是很正确.
{
OnReceive();
break;
}
break;


}///case
}///for
return 0;
}
...全文
299 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
coldant 2008-01-14
  • 打赏
  • 举报
回复
大家一起学习
coldant 2008-01-14
  • 打赏
  • 举报
回复
回9楼的,
case EV_RXCHAR :
::ClearCommError(_hCommHandle, &dwError, &Stat);
if(Stat.cbInQue > 0)
{
Read( &(Data[Pos]),Stat.cbInQue);
Pos += Stat.cbInQue;

if ( (Data[4]!=0)&( Pos >= (Data[4]+4)))
{
Pos = 0;
OnReceive();
}

break;
}
break;

这些是修改过的,基本思路就是串口不能一次把数据全读完,要分多次读,然后把数据组装起来.
wqm_44944 2008-01-08
  • 打赏
  • 举报
回复
问题是怎么解决的?贴出来,大家一起学习一下
coldant 2008-01-03
  • 打赏
  • 举报
回复
呵呵,谢谢楼上各位,问题解决了^_^
wqm_44944 2008-01-03
  • 打赏
  • 举报
回复
应该是读取数据过快的原因,当事件触发后,你加一个延时!看看效果。大约sleep(30)就可以了!
gisgan2006 2007-12-29
  • 打赏
  • 举报
回复
zhoujianhei 说的很对. 读串口数据有的时候不能一次性读完.所以每笔数据必须加长度标志. 当读取的长度跟标志长度相等时,才能算得上读完一笔数据.接着就可以去分析这笔设局.
shulei521 2007-12-29
  • 打赏
  • 举报
回复
顶啊
Elysium 2007-12-29
  • 打赏
  • 举报
回复
建议另开一个线程处理接收到的数据
shulei521 2007-12-29
  • 打赏
  • 举报
回复
我再顶
zhoujianhei 2007-12-29
  • 打赏
  • 举报
回复
在发数据前先发数据长度,再根据长度读取数据(多次读取)。
coldant 2007-12-27
  • 打赏
  • 举报
回复
急急急,大哥们帮忙,^-^.说了这么多,其实就是想实现外面发来的数据,只响应一次就可以全部读出来.
if(Stat.cbInQue > 0)//此处,如果外部发送22个字节,Stat.cbInQue第一次的值一 般为8,读数据的时候只能读出前8个,其他的都没有.

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧