串口接受到数据之后,线程里如何处理?才能保证接受到一个有效的控制码?

NextMoon 2007-04-17 03:16:04
我的串口程序里,读串口数据,开了个线程,代码如下:
简略的:
void __fastcall TRead::DisplayIt()
{
Form1->Memo1->SetSelTextBuf(inBuff);
}
inBuff是个char类型的一维数组,上面这个DisplayIt调用,只要我外接开关按着某个键,这个键的编码就一直显示出来,先肯定是存到inBuff这个数组里。
我要根据得到的这个键的编码值来执行相应的功能,只要知道有键按下就可以了,但是假如按着时间有点长,会一直有编码出来,怎么样处理,在线程里只接受到一个有效编码,就忽略后面接受到的编码了。谢谢
...全文
299 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
NextMoon 2007-04-20
  • 打赏
  • 举报
回复
我写在定时器里,运行起来之后就会停止
Waiting4you 2007-04-20
  • 打赏
  • 举报
回复
好像代码没什么问题,只是映象里Win2k以后对同步串口读写方式不再提供支持, 你改成overlap方式试一下

还有你为什么要一个个地发? 直接WriteFile(hComm,WriteToCommArray,sizeof(WriteToCommArray),&lrc,&ov);不好吗?
NextMoon 2007-04-20
  • 打赏
  • 举报
回复
在CB里,关于WriteFile()这个函数,几个参数能不能给我介绍一下?我开的线程实时的检测串口,
void __fastcall TForm1::Timer12Timer(TObject *Sender)
{
if(GetTickCount()- ReadThread->LastTime>500)
{
Timer12->Enabled=false;
if(ReadThread->LastInBuf[0]==':')
{
ShowMessage("开");

SetOpenStatusLed();
}
}
}
还有一个函数:
//-----------------------打开“开”指示灯------------------
void TForm1::SetOpenStatusLed()
{
byte ch;
DWORD lrc, SendNum;
int ChkSum = 0;
WriteToCommArray[0]='\xff';
// WriteToCommArray[1]='0';
// WriteToCommArray[2]='0';
// WriteToCommArray[3]='1';
// WriteToCommArray[4]='0';
// WriteToCommArray[5]='\x';
// WriteToCommArray[6]='\x';
WriteToCommArray[7]='\x7E';

for(int i=0;i<8;i++)
{
ChkSum = ChkSum+WriteToCommArray[i];
}
if(hComm == 0)
{
MessageBox(NULL, "COM Port is not opened!", "Send Error", MB_OK);
return;
}
//开始发送数据
for(int i=0;i<8;i++)
{
ch = WriteToCommArray[i];
WriteFile(hComm,&ch,1,&lrc,NULL);//调用到这句出错!
}
}
NextMoon 2007-04-19
  • 打赏
  • 举报
回复
这样我担心会出现一些衔接的问题。毕竟是通过这样的办法来实现的。您有什么好办法,给我讲讲。
Waiting4you 2007-04-19
  • 打赏
  • 举报
回复
Time1->Enabled=false;放在if(...) { ShowMessage("开")...;之前,

>300 这个再调大点

目的是有':'来的时候激活timer,
当timer发现前一次来的':'到当前时间已经超过300ms时认为已经松开按键, 这时才确认一次按下操作.
NextMoon 2007-04-19
  • 打赏
  • 举报
回复
楼上的,也许我表述的有点不对,按照您的做法,我也试了,这样程序是没出错。但是当一直按着键的时候,还会出现消息框跳出来多个。举个例子,比如,我一直按着面板上的”开“键,它这个消息框一直会跳出来,按了对应的字符码":"有五个的话,就会跳出五个对应的消息框,我达到的目的就是,按下,只要响应一次就可以了。也就是说,多个相同的按键,只执行一次消息框就可以了。
Waiting4you 2007-04-19
  • 打赏
  • 举报
回复
后来想想好像不用Timer也行.

DWORD TRead::ClickTime=0; //在TRead()里初始化成0

void __fastcall TRead::DisplayIt()
{
Form1->Memo1->SetSelTextBuf(inBuff);
if(inBuff[0]==':' && IfSameChar())
{
DWORD CurTime=GetTickCount();
if(CurTime-ClickTime>500)
{
//ShowMessage("开");
把这个改成PostMessage(MainForm->Handle,WM_USER,0,1);之类的东东,因为ShowMessage的时候在等待你点击,而这时串口缓冲里已经有不少':'了,so点击完后又来几个':'因为时间记录的问题必然会再次跳出"开" :-(
}
ClickTime=CurTime; {
}
else if(inBuff[0]=='[' && IfSameChar())
{
ShowMessage("上");//同上
}


}
Waiting4you 2007-04-18
  • 打赏
  • 举报
回复
你是意思是说一直按着键就会不断地调用DisplayIt()?

那么可以试验一下从按下到松开InBuff里的数据是否有变化, 如果有那么只要等到松开键再执行就行了.

如果没有KeyUp码,可以用一个时钟控件, 间隔定小一点(比如100ms).
有数据来时置一变量为当前时间(比如LastCome=GetTickCount();Time1->Enabled=true;);
时钟里的代码是判断if(GetTickCount()-LastCome>300) { DisplayIt(); Time1->Enabled=false;}
Waiting4you 2007-04-18
  • 打赏
  • 举报
回复
DisplayIt里写
{
LastCome=GetTickCount();
strncpy(LastInBuf,InBuff,50);
Form1->Timer1->Enabled=true;
}
Form1的确Timer1Time里
if(GetTickCount()-Read->LastCome>300){
Form1->Memo1->SetSelTextBuf(Read->LastInBuf);
if(Read->LastInBuf[0]==':' && IfSameChar())
{
ShowMessage("开");
}
else if(Read->LastInBuf[0]=='[' && IfSameChar())
{
ShowMessage("上");
}
Time1->Enabled=false;
}
NextMoon 2007-04-18
  • 打赏
  • 举报
回复
楼上您能给我说明白点吗?我有点听不太明白您说的。
我把我的代码贴出来。
void __fastcall TRead::DisplayIt()
{
Form1->Memo1->SetSelTextBuf(inBuff);
if(inBuff[0]==':' && IfSameChar())
{
ShowMessage("开");
}
else if(inBuff[0]=='[' && IfSameChar())
{
ShowMessage("上");
}


}
void __fastcall TRead::Execute()
{
DWORD dwBytesRead;
FreeOnTerminate = true;
while(1)
{
ReadFile(hComm,inBuff,50,&dwBytesRead,NULL);
if(dwBytesRead)
{
inBuff[dwBytesRead] = 0;
Synchronize(DisplayIt);
}
}
}
如何分解出一个字符,或者有相同一样的,忽略掉,谢谢大侠了
Waiting4you 2007-04-18
  • 打赏
  • 举报
回复
从你的代码上看,如果你的DisplayIt写在线程里的话应该用Synchronize与主线程消息队列同步.

LastCome=GetTickCount();Time1->Enabled=true;这行当然也可以用Synchronize. 它应该在收到InBuff之后调用.
NextMoon 2007-04-18
  • 打赏
  • 举报
回复
我想问楼上的,我写在线程里,怎么样来触发用Timer控件呢。
希望可以和你单独交流一下。我的代码你也可以看一下。我没有调用TimerTime。
NextMoon 2007-04-17
  • 打赏
  • 举报
回复
请楼上的赐教啊!最好给我点实例代码!
Waiting4you 2007-04-17
  • 打赏
  • 举报
回复
如果松开键有对应的编码的话还好处理一点.

如果没有的话只好读入inBuff时先不执行你的相应功能, 在超过一个时间段(比如300ms)后再执行了.
内容概要:本文系统研究了基于豪猪优化算法(CPO)的多无人机协同集群在三维空间中的避障路径规划问题,聚焦于实现以最低成本为目标的航迹优化,综合考虑路径长度、飞行高度、威胁规避及转弯角度等多个关键因素。通过构建精细化的三维环境模型与多无人机协同机制,采用Matlab平台实现CPO算法的仿真与验证,充分展示了该算法在复杂动态障碍环境下的高效搜索能力与全局优化性能。研究不仅涵盖了路径规划的数学建模与目标函数设计,还深入探讨了算法的收敛特性与鲁棒性,为智能群体系统在实际场景中的应用提供了理论依据与技术支撑。; 适合人群:具备一定编程基础和优化算法背景,从事无人机系统控制、智能路径规划、群体协同、人工智能与自动化等相关领域的科研人员、高校研究生及工程技术人员。; 使用场景及目标:①应用于多无人机协同执行侦察、灾害监测、应急救援、区域巡检等复杂任务中的自主路径规划;②为智能优化算法在三维动态环境下的路径决策问题提供可复现的技术范例;③支持研究人员对CPO算法与其他主流群智能算法(如PSO、GWO、WOA等)进行性能对比与改进研究,推动路径规划技术的发展。; 阅读建议:建议结合提供的Matlab代进行实践操作,重点理解目标函数的多维度建模方式与CPO算法的迭代优化流程,可通过调整环境参数与约束条件进行仿真实验,对比不同算法在相同场景下的路径质量与收敛速度,从而深入掌握其优势与适用边界。

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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