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

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;
}
...全文
371 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个,其他的都没有.
内容概要:本文针对无刷直流电机驱动的电子机械制动(EMB)执行器,建立了考虑Stribeck摩擦特性的非线性耦合动力学模型,并在Simulink环境中完成了系统级仿真分析。研究综合集成了电机动力学、齿轮传动机构与制动执行机构的动力学特性,构建了高保真的机电一体化系统模型。重点引入Stribeck摩擦模型以精确描述低速工况下执行器内部存在的静摩擦、粘滞摩擦与库仑摩擦之间的过渡行为,有效提升了系统在启停、反向运动等瞬态过程中的动态响应仿真精度。通过多工况仿真验证了模型的有效性,能够准确反映摩擦引起的爬行、滞后与定位误差等非线性现象,为EMB系统的高性能控制算法设计(如摩擦补偿、滑模控制)与结构优化提供了高可信度的仿真平台。; 适合人群:从事汽车电子制动系统、电机驱动控制、机电系统建模与仿真研究的研究生、科研人员及工程技术人员,需具备扎实的机械动力学、自动控制理论基础和MATLAB/Simulink仿真能力。; 使用场景及目标:①用于高精度电子机械制动系统的设计验证与性能预测;②为消除摩擦非线性影响的先进控制策略(如自适应控制、智能控制)提供精确的被控对象模型;③深入探究Stribeck摩擦等非线性因素对系统动态性能(如响应延迟、稳态误差)的作用机理; 阅读建议:读者应结合提供的Simulink模型文件,深入剖析Stribeck摩擦模块的数学实现与参数辨识方法,建议通过改变输入指令(如阶跃、正弦)和负载条件进行对比仿真,以直观理解非线性摩擦对系统动态特性的影响。

15,465

社区成员

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

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