// 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;
另外在这在体格问题,上面说的问题其实主要是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;
}