解决方案 »

  1.   

    自己先顶个,再加一段COM初始化和设置的代码。
    另外在这在体格问题,上面说的问题其实主要是WaitCommEvent(),和WaitForMultipleObjects(),而这两个函数等待的事件和返回值就决定了,线程的执行方向。现在LZ最不明白的是WaitCommEvent()这个函数,有么有人用过这个,他等待的事件是否可以设置,根据自己查阅的资料SetCommMask可以设置,但是自己只设置EV_RXCHAR,但是WaitCommEvent()还会返回其他的值,不知道上面原因。
    设置的代码在下面。BOOL CSerialPort::InitPort(CWnd* pPortOwner, // the owner (CWnd) of the port (receives message)
       UINT  portnr, // portnumber (1..4)
       UINT  baud, // baudrate
       TCHAR parity, // parity 
       UINT  databits, // databits 
       UINT  stopbits, // stopbits 
       DWORD dwCommEvents, // EV_RXCHAR, EV_CTS etc
       UINT  writebuffersize) // size to the writebuffer
    {
    //assert(portnr > 0 && portnr < 5);
    assert(pPortOwner != NULL); // if the thread is alive: Kill
    //KillPortThread();
    if (m_bThreadAlive)
    {
    do
    {
    if (SetEvent(m_hShutdownEvent))
    {
    TRACE("%s:ShutdownEvent ComThread by InitPort!\n",_GetTime());
    }

    while (m_bThreadAlive);
    TRACE("%s:Thread ended int InitPort!\n",_GetTime());
    } // create events
    if (m_overlapped.hEvent != NULL)
    ResetEvent(m_overlapped.hEvent);
    m_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (m_hWriteEvent != NULL)
    ResetEvent(m_hWriteEvent);
    m_hWriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    if (m_hShutdownEvent != NULL)
    ResetEvent(m_hShutdownEvent);
    m_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // initialize the event objects
    m_hEventArray[0] = m_hShutdownEvent; // 串口关闭事件,自己控制触发
    m_hEventArray[1] = m_overlapped.hEvent; // 串口接收到数据事件,由串口驱动触发
    m_hEventArray[2] = m_hWriteEvent; // 串口写数据事件,自己控制触发 // initialize critical section
    InitializeCriticalSection(&m_csCommunicationSync);//临界区初始化

    // set buffersize for writing and save the owner
    //m_pOwner = dynamic_cast<CMainFrame*>(pPortOwner); 
    m_pOwner = pPortOwner; 
    m_nPortNr = portnr; m_nWriteBufferSize = writebuffersize;
    m_dwCommEvents = dwCommEvents; BOOL bResult = FALSE;
    TCHAR* szPort = new TCHAR[50];
    TCHAR* szBaud = new TCHAR[50]; // now it critical!
    EnterCriticalSection(&m_csCommunicationSync); // if the port is already opened: close it
    if (m_hComm != NULL)
    {
    CloseHandle(m_hComm);
    m_hComm = NULL;
    } // prepare port strings
    wsprintf(szPort, _T("COM%d"), portnr);
    //sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, stopbits);
    wsprintf(szBaud, _T("baud=%d parity=%c data=%d stop=%d"), baud, parity, databits, stopbits); // get a handle to the port
    m_hComm = CreateFile(szPort, // communication port string (COMX) //modify by leo
         GENERIC_READ|GENERIC_WRITE, // read/write types
         0, // comm devices must be opened with exclusive access
         NULL, // no security attributes
         OPEN_EXISTING, // comm devices must use OPEN_EXISTING
     FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,// Async I/O
         0); // template must be 0 for comm devices if (m_hComm == INVALID_HANDLE_VALUE)
    {
    //DWORD nErrer =  GetLastError();
    TRACE("%s:CreateFile Com%d Error ,%s~\n",_GetTime(),m_nPortNr,_GetErrorCodeCause(GetLastError()));
    // port not found
    delete [] szPort;
    delete [] szBaud;
    return FALSE;
    } // set the timeout values
    m_CommTimeouts.ReadIntervalTimeout = -1;
    m_CommTimeouts.ReadTotalTimeoutMultiplier = 0;
    m_CommTimeouts.ReadTotalTimeoutConstant = 1000;
    m_CommTimeouts.WriteTotalTimeoutMultiplier = 0;
    m_CommTimeouts.WriteTotalTimeoutConstant = 1000;

    SetupComm(m_hComm,4096,2048);
    // configure
    if (SetCommTimeouts(m_hComm, &m_CommTimeouts))
    {    
    //if (SetCommMask(m_hComm, dwCommEvents))EV_RXCHAR
    if (SetCommMask(m_hComm, EV_RXCHAR))
    {
    if (GetCommState(m_hComm, &m_dcb))
    {
    m_dcb.EofChar = 89;
    m_dcb.ErrorChar = 88;
    m_dcb.EvtChar = 89;
    //m_dcb.EvtChar = 30;
    m_dcb.XonChar = 89;
    m_dcb.XoffChar =89; m_dcb.fRtsControl = RTS_CONTROL_DISABLE;
    m_dcb.fDtrControl = DTR_CONTROL_DISABLE;
    m_dcb.fDsrSensitivity = FALSE;
    m_dcb.XonLim = 2048;
    m_dcb.XoffLim = 512; if (BuildCommDCB(szBaud, &m_dcb))           
    {
    if (SetCommState(m_hComm, &m_dcb))
    ; // normal operation... continue
    else
    ProcessErrorMessage(_T("SetCommState()"));
    }
    else
    ProcessErrorMessage(_T("BuildCommDCB()"));
    }
    else
    ProcessErrorMessage(_T("GetCommState()"));
    }
    else
    ProcessErrorMessage(_T("SetCommMask()"));
    }
    else
    ProcessErrorMessage(_T("SetCommTimeouts()")); delete [] szPort;
    delete [] szBaud;
    // flush the port
    //PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
    // release critical section
    LeaveCriticalSection(&m_csCommunicationSync);
    TRACE("%s:Initialisation for communicationport %d completed.\nUse Startmonitor to communicate.\n", _GetTime(),portnr);
    return TRUE;
    }