读书人

定时握手的有关问题

发布时间: 2011-12-31 23:50:30 作者: rapoo

定时握手的问题
程序在和下位机通信,插入两个COM口,我现在想实现在通信的过程当中如果将某一个COM拔出,然后再插回去,怎么让它马上继续获取数据,现在我写了个方法,如果一个COM被拔出,然后给所有COM定时发送数据,如果你再将它插入回去,则重新开启该串口进行数据的获取,但是现在出问题了,这个方法可以实现,但是一旦我拔下一个后,另一个获取数据就好卡好卡了,我将代码贴出来,大家帮我分析一下,谢谢了。

C/C++ code
int GetCommNum()    {            int _u_connectmode=0;                DWORD dwactlen;            DWORD dwLength=0;        int len=1;        unsigned char *psendbuf=new unsigned char[len];        unsigned char *recvBuf=new unsigned char[1024];        psendbuf[0]=0xff;                    HAND temphand;        BOOL temp;                Lhand.connect=false;        Rhand.connect=false;                for(int i=1;i<13;i++)        {            (temphand.Port).Format(_T("COM%d"),i);            temp=OpenPort(57600,8,ONESTOPBIT,NOPARITY,&temphand);            if (temp == false)            {                continue;            }            else            {                            PurgeComm(temphand.hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);        //清除收/发缓冲区                WriteFile(temphand.hComm,psendbuf,len,&dwactlen,NULL);                ReadFile(temphand.hComm,recvBuf,1024,&dwLength,NULL);        //其实我们接收到的命令应答只是一个字节                                if(recvBuf[1]=='L') //                {                    Lhand.connect=true;                    Lhand.Port=temphand.Port;                }                else if(recvBuf[1]=='R')    //                {                    Rhand.connect=true;                    Rhand.Port=temphand.Port;                    }                if(Lhand.connect==true && Rhand.connect==true)    //左右手同时插入                {                    delete psendbuf;                    delete recvBuf;                    ClosePort(&temphand);                    return 3;                }                ClosePort(&temphand);                            }                            }

这个是获取串口的,遍历一遍所有的串口。
C/C++ code
void CInitData::OnTimer(UINT nIDEvent) {    CConnectPort CP;    CString Finger1,Finger2,Finger3,Finger4,Finger5,Finger6,Finger7,Finger8,Finger9,Finger10,Finger11,Finger12,Finger13,Finger14,Finger15,Finger16,Finger17,Finger18,Finger19,Finger20,Finger21,Finger22,Finger23,Finger24,Finger25,Finger26,Finger27,Finger28,Finger29,Finger30,Finger31,Finger32,Finger33,Finger34,Finger35,Finger36,Finger37,Finger38,Finger39,Finger40,Finger41,Finger42,Finger43;    UpdateData(FALSE);    Util util;    switch(nIDEvent)    {    case 1:                                   //左手连接,开始接收数据        BOOL flag;        flag= CP.GetData(0xff,16,3,&Lhand);        Finger1.Format("%d",Lhand.ADCData[0]);        Finger2.Format("%d",Lhand.ADCData[1]);        Finger3.Format("%d",Lhand.ADCData[2]);        Finger4.Format("%d",Lhand.ADCData[3]);        Finger5.Format("%d",Lhand.ADCData[4]);        Finger6.Format("%d",Lhand.ADCData[5]);        Finger7 = "0";        SetDlgItemText(IDC_EDIT1,Finger1);        //给InitData初始化窗体的左手拇指初始化文本框赋值        SetDlgItemText(IDC_EDIT2,Finger2);        //给InitData初始化窗体的左食指指初始化文本框赋值        SetDlgItemText(IDC_EDIT3,Finger3);        //给InitData初始化窗体的左中指指初始化文本框赋值        SetDlgItemText(IDC_EDIT4,Finger4);        //给InitData初始化窗体的左无名指指初始化文本框赋值        SetDlgItemText(IDC_EDIT5,Finger5);        //给InitData初始化窗体的左手小指初始化文本框赋值        SetDlgItemText(IDC_EDIT6,Finger6);          //给InitData初始化窗体的左手手腕前初始化文本框赋值            if(!flag)        {            CP.ClosePort(&Lhand);            CP.GetCommNum();            CP.OpenPort(57600,8,ONESTOPBIT,NOPARITY,&Lhand);        }        break;    case 2:        BOOL flag2;        flag2 = CP.GetData(0xff,16,3,&Rhand);        Finger22.Format("%d",Rhand.ADCData[0]);        Finger23.Format("%d",Rhand.ADCData[1]);        Finger24.Format("%d",Rhand.ADCData[2]);        Finger25.Format("%d",Rhand.ADCData[3]);        Finger26.Format("%d",Rhand.ADCData[4]);        Finger27.Format("%d",Rhand.ADCData[5]);        Finger28 = "0";        SetDlgItemText(IDC_EDIT22,Finger22);        SetDlgItemText(IDC_EDIT23,Finger23);        SetDlgItemText(IDC_EDIT24,Finger24);        SetDlgItemText(IDC_EDIT25,Finger25);        SetDlgItemText(IDC_EDIT26,Finger26);        SetDlgItemText(IDC_EDIT27,Finger27);        SetDlgItemText(IDC_EDIT28,Finger28);        if(!flag2)        {            CP.ClosePort(&Rhand);            CP.GetCommNum();                        CP.OpenPort(57600,8,ONESTOPBIT,NOPARITY,&Rhand);        }        break;    }    CDialog::OnTimer(nIDEvent);} 


这个时间方法里我分别对两个串口接收数据,定时为
SetTimer(1,10,NULL);
SetTimer(2,10,NULL);
CP.GetData(0xff,16,3,&Lhand);这个方法是给下位机发送协议0xff的,接收的数据存放在HAND Lhand,Rhand这两个结构体的ADCData里。GetData这个方法返回一个BOOL型,如果为false,说明没有接收到数据,那么就调用GetCommNum()方法进行串口的重新遍历,直到重新插入串口进行获取数据,现在问题来了,我开始将两个串口同时插上,很正常,接收数据很流畅,但是我一旦拔出一个,那么另一个接收就好卡好卡了,后来我找到了原因,把CP.GetCommNum();这个遍历方法一屏蔽掉,拔出一个另一个就很流畅,没有问题,但是这个一屏蔽掉你把拔出来的串口再插回去就没用了,大家伙帮帮忙吧。只剩下这点分了,都拿出来了

[解决办法]
我没有仔细看代码,我的理解是:
不管有多少个com,基本上一个线程对应一个com的通讯,这样容易处理一些。
每个线程在和com通讯的过程中,其实就是读和写两个操作,不管是读还是写,如果失败了,则持续地重试,直到成功。当然如果有对应的错误号码返回,比如是windows异常导致无法通讯就需要重新打开这个com后再重新通讯,如果只是外面的设备拔掉了,我猜应该是读写的一般失败,只是重试就可以了。如果外面的设备拔掉了,如果再插上还需要重新开始协议的通讯,则程序也需要做相应的协议初始化工作,而不能只是简单地重试
[解决办法]
3楼++

多线程能解决这个问题,你在定时器里做耗时遍历,这样就造成接数据卡住了!

读书人网 >VC/MFC

热点推荐