只要有数据串口的EV_RXCHAR消息就会到达,而我的ReadCom(void* buf,int length)想要在收到EV_RXCHAR时就读取指定长度的帧(包含我想要的完整的帧),如何做到?

解决方案 »

  1.   

    DWORD   dwErrorFlags;
    COMSTAT ComStat ;
    WaitCommEvent( hComDev, &dwEvtMask, &osWait);
    if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
      ClearCommError( hComDev, &dwErrorFlags, &ComStat ) ;
    //ComStat.cbInQue 指定长度的帧
      

  2.   

    DWORD   dwErrorFlags;
    COMSTAT ComStat ;
    WaitCommEvent( hComDev, &dwEvtMask, &osWait);
    if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
      ClearCommError( hComDev, &dwErrorFlags, &ComStat ) ;
    //ComStat.cbInQue 指定长度的帧ReadCom(buf,ComStat.cbInQue)
      

  3.   

    每当下位机发送一帧(n字节)时,只会触发一次EV_RXCHAR吗,还是会分多次触发,我怎么去组合一帧呢(我可能接到好多中格式的帧)
      

  4.   

    既然你通过EV_RXCHAR来得到数据到达的通知,你必然需要read了,read后放入缓冲区然后判断不就行了?
    这一小段程序就是读取串口的,每次数据到达向主窗口发送数据到达消息。DWORD CUpgraderDlg::ThreadProc(LPVOID lpParam)
    {
    CUpgraderDlg *pThis = (CUpgraderDlg *)lpParam; DWORD dwEvents, dwBytesRead, dwError; while(pThis->m_bCommOpen) {
    if(WaitCommEvent(pThis->m_hComm, &dwEvents, NULL)) {
    if(dwEvents == EV_RXCHAR) {
    dwBytesRead = pThis->ReadCommBlock(pThis->m_szRecvBuffer, 1024);
    if(dwBytesRead) {
    ResetEvent(pThis->m_hEvBufferEmpty);
    ::PostMessage(pThis->m_hWnd, UM_DATAARRIVAL, 0, dwBytesRead);
    WaitForSingleObject(pThis->m_hEvBufferEmpty, INFINITE);
    }
    }
    }
    else {
    dwError = GetLastError();
    if(dwError != 995)
    pThis->ShowError();
    return 0;
    }
    }
    return 1;
    }
    --------------------------------------------------------------------
    这是把新读入信息放到缓冲区(这里是文本框)中
    LRESULT CUpgraderDlg::OnDataArrival(WPARAM wParam, LPARAM lParam)
    {
    // UpdateData(); m_szRecvBuffer[lParam] = 0;
    m_strOutput.SetSel( 10000, 10000 );
    m_strOutput.ReplaceSel( m_szRecvBuffer ); SetEvent(m_hEvBufferEmpty); //if(m_strOutPut.Right(1) == "\n")
    //if(m_strOutPut.GetLength() > 1000)
    // UpdateData(FALSE);
    return 0;
    }
    ------------------------------------------------------------------
    这是分析缓冲区的,根据信息判断,我的程序每完成一项功能,返回的字符不一样
    DWORD CUpgraderDlg::UpgradeThread(LPVOID lpParam)
    {
    CUpgraderDlg *pThis = (CUpgraderDlg *)lpParam;
    CString msg; BYTE bb[2]; bb[0] = 0x8B;
    bb[1] = 'u'; //Start to upgrade
    pThis->WriteCommBlock(bb, 2);
    pThis->m_strOutput.GetWindowText( msg ); while( msg.Find("Programming") < 0) {
    pThis->m_strOutput.GetWindowText( msg );
    Sleep(10);
    } for(int i = 0; i < 512; i++) {
    if(!pThis->WriteCommBlock(pThis->m_byteBuffer + i * 128, 128)) {
    pThis->m_ctlProgress.SetPos(0);
    pThis->EnableButtons();
    pThis->CloseComm();
    pThis->m_bUpgrading = false;
    return -1;
    }
    pThis->m_ctlProgress.SetPos(i);
    } pThis->m_strOutput.GetWindowText( msg );
    while(msg.Find("Verifying") < 0){
    pThis->m_strOutput.GetWindowText( msg );
    Sleep(10);
    } UINT nChecksum = pThis->CheckSum();
    RevBO32((BYTE *)&nChecksum);
    pThis->WriteCommBlock(&nChecksum, 4); pThis->m_strOutput.GetWindowText( msg );
    while(msg.Find("Complete.") < 0){
    pThis->m_strOutput.GetWindowText( msg );
    Sleep(10);
    } pThis->EnableButtons();
    pThis->CloseComm();
    pThis->m_ctlProgress.SetPos(0);
    pThis->m_bUpgrading = false;
    return 0;
    }串口程序最重要的就是缓冲区,合理使用才能正确。
      

  5.   

    开始先读取一个字节,然后读到这个字节制定的长度的数据,下次再度取一个字节,再度取指定字节长度的数据; 或者:
    开一个缓冲区队列(FIFO),读取的数据都加入缓冲区。分析程序测试队列的长度,如果有一定的数据,且长度大于等于第一个字节的长度,从队列中取出第一个字节指定的长度的数据。