我原来写串口程序的时候都采用强行等待Sleep,现在想做个循环等待的(其实也用了Sleep的),下面的代码在单步调试的时候可以能接收到设备返回的数据,但在直接执行的时候却收不到数据,请大家帮忙看看!代码如下:
if (m_bConnected)   //判断串口是否打开
    {
        BOOL Wait_time=TRUE;
        int Wait_time_NO=0;
        char *m_pInbuffer_temp=new char[100];
        char *m_pOutbuffer_temp=new char[100];
        char *m_temp=new char[100];
        BYTE *reply=new BYTE[2];
        PurgeComm(h_Com,PURGE_TXCLEAR|PURGE_RXCLEAR);
        memset(m_pInbuffer_temp,0,sizeof(m_pInbuffer_temp));
        memset(m_pOutbuffer_temp,0,sizeof(m_pOutbuffer_temp));
        memset(reply,0,sizeof(reply));
        memcpy(m_pInbuffer_temp,"\x7e\x00\x00\x041\x41\x01\x1a",7);
        crc_16(m_pInbuffer_temp,7,reply);
        m_pInbuffer_temp[7]=reply[0];
        m_pInbuffer_temp[8]=reply[1];
        WriteComm(m_pInbuffer_temp,9);
        
        //////////////////////////////////////////////////////////////////
        memset(m_pInbuffer_temp,0,sizeof(m_pInbuffer_temp));
        memset(m_pOutbuffer_temp,0,sizeof(m_pOutbuffer_temp));
        memset(reply,0,sizeof(reply));
        DWORD number=0;
        while (Wait_time)
        {
            number=ReadComm(m_pOutbuffer_temp,100);        //这里设断点
            if (number==11)
            {
                Wait_time=FALSE;
                unsigned char *m_pOutbuffer_format=new unsigned char[number];
                for(int i=0;i<(int)(number);i++)
                {
                    m_pOutbuffer_format[i]=unsigned char(m_pOutbuffer_temp[i]);
                }
                ///////////////////////////////////////////////////////////////////////
                
                memset(m_temp,0,sizeof(m_temp));    
                memcpy(m_temp,m_pOutbuffer_temp,9);
                crc_16(m_temp,9,reply);
                if (reply[0]==m_pOutbuffer_format[number-2]&&reply[1]==m_pOutbuffer_format[number-1]) 
                {
                    //全局变量保存编号及原设备地址
                    m_RTU_number[0]=m_pOutbuffer_format[0];
                    m_RTU_number[1]=m_pOutbuffer_format[1];
                    m_RTU_number[2]=m_pOutbuffer_format[2];
                    m_RTU_number[3]=m_pOutbuffer_format[3];
                    m_RTU_number[4]=m_pOutbuffer_format[4];
                    RTU_Initialize=TRUE;
                    delete[]m_pOutbuffer_format;
                    AfxMessageBox("初始化成功!");        
                }
                else
                {
                    AfxMessageBox("校验位错误,请重试!");
                }
            }
            if (Wait_time_NO>80) 
            {
                Wait_time=FALSE;
                AfxMessageBox("编号读取失败!");
            }
            else
            {
                Sleep(1);//这里把等待时间改长了一也样啊!
                Wait_time_NO++;
            }
        }
            delete[]m_pInbuffer_temp;
            delete[]m_pOutbuffer_temp;
            delete[]m_temp;
    }
    else
        AfxMessageBox("请确认串口是否已经打开!");

解决方案 »

  1.   

    WaitCommEvent(m_hFile, &dwEvtMask, &m_ReadOs);
    if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
    {
    ...
    }WaitCommEvent to replace Sleep.
      

  2.   

    楼上的估计不行吧,如果串口真的什么状态都不返回那程序这个进城岂不是死了.BOOL ZComm::WaitEventChar()
    {
       OVERLAPPED  os ; 
       DWORD       dwEvtMask,Errors;
       COMSTAT Stat;   memset( &os, 0, sizeof( OVERLAPPED ));
       os.hEvent = CreateEvent( NULL,    // no security
                                TRUE,    // explicit reset req
                               FALSE,   // initial event nonsignaled. 
                               NULL ) ; // no name
       dwEvtMask = 0 ;
       WaitCommEvent(idComDev,&dwEvtMask,&os);
       
       if (WaitForSingleObject(os.hEvent,MAXTIMEOUT)==WAIT_TIMEOUT)
       {
         CloseHandle(os.hEvent);
       return false;
       }
       else if ((dwEvtMask & EV_RXCHAR/*EV_RXFLAG*/) == /*EV_RXFLAG*/EV_RXCHAR)
       {
           CloseHandle(os.hEvent);
       
       ClearCommError(idComDev,&Errors, &Stat);
       return true;
    }else
    {
         CloseHandle(os.hEvent);
       return false;
       }
    }使用WaitForSingleObject可以保证超时退出WaitCommEvent
      

  3.   

    不用响应事件那么麻烦
    DWORD endtime;                            /////////jiesuo...
    if(!ReadFile(hComm,inbuff,nToRead,&nBytesRead,&ol))
        {    
            if((lrc=GetLastError())==ERROR_IO_PENDING)
            {
                ///////////////////
                endtime=GetTickCount()+ReadTime;//GetTickCount()取回系统开始至此所用的时间(毫秒)
                while(!GetOverlappedResult(hComm,&ol,&nBytesRead,FALSE))//该函数取回重叠操作的结果
                {
                    if(GetTickCount()>endtime)
                        break;
                }    
            }        
        }就行了!