123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500 |
- #include "StdAfx.h"
- #include "SynSerial.h"
- int CSynSerial::s_nCurPos = 0;
- byte CSynSerial::s_byBuffer[BUFFER_LEN];
- ThreadSection CSynSerial::s_csClearBuffer;
- CSynSerial::CSynSerial(void) :m_hSerialPort(NULL)
- , m_dwInQueue(1024)
- , m_dwOutQueue(1024)
- {
- memset(&m_dcb, 0, sizeof(DCB));
- memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
- memset(&m_szSerialPort, 0, sizeof(TCHAR)*MAX_PORT_LEN);
- m_hEvent = NULL;
- m_hThread = NULL;
- // 初始化重叠对象;
- ZeroMemory(&m_writeOverlapped,sizeof(m_writeOverlapped));
- if (m_writeOverlapped.hEvent != NULL) {
- ResetEvent(m_writeOverlapped.hEvent);
- m_writeOverlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
- }
- ZeroMemory(&m_readOverlapped,sizeof(m_readOverlapped));
- if (m_readOverlapped.hEvent != NULL) {
- ResetEvent(m_readOverlapped.hEvent);
- m_readOverlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
- }
- }
- CSynSerial::~CSynSerial(void)
- {
- EndofThread();
- CloseSerialPort();
- }
- BOOL CSynSerial::OpenSerialPort(IN CONST BYTE & byCommPort, IN CONST DWORD & dwBaudRate, IN CONST BYTE & bySize, IN CONST BYTE & byParity, IN CONST BYTE & byStopBits, IN CONST BYTE & byStartAddr, IN CONST INT & nInterval)
- {
- ASSERT(byCommPort);
- CloseSerialPort();
- _stprintf_s(m_szSerialPort, _T("\\\\.\\com%d"), (int)byCommPort);
- m_hSerialPort = CreateFile(m_szSerialPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- if (m_hSerialPort == INVALID_HANDLE_VALUE)
- {
- // 打开串口失败;
- DWORD dwError = GetLastError();
- return FALSE;
- }
- BOOL bResult = FALSE;
- // SetupComm设置缓冲区大小;
- bResult = SetupComm(m_hSerialPort, m_dwInQueue, m_dwOutQueue);
- if (!bResult)
- {
- CloseHandle(m_hSerialPort);
- m_hSerialPort = INVALID_HANDLE_VALUE;
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // 在串口读写之前,清除缓冲区;
- bResult = PurgeComm(m_hSerialPort, PURGE_TXCLEAR | PURGE_RXCLEAR);
- if (!bResult)
- {
- CloseHandle(m_hSerialPort);
- m_hSerialPort = INVALID_HANDLE_VALUE;
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // GetCommState获取设备控制块状态;
- memset(&m_dcb, 0, sizeof(DCB));
- bResult = GetCommState(m_hSerialPort, &m_dcb);
- if (!bResult) {
- CloseHandle(m_hSerialPort);
- m_hSerialPort = INVALID_HANDLE_VALUE;
- DWORD dwError = GetLastError();
- return FALSE;
- }
- m_dcb.Parity = byParity;
- if (m_dcb.Parity == NOPARITY)
- m_dcb.fParity = FALSE;
- else
- m_dcb.fParity = TRUE;
- m_dcb.BaudRate = dwBaudRate;
- m_dcb.ByteSize = bySize;
- m_dcb.StopBits = byStopBits;
- if (m_dcb.ByteSize == 8)
- m_dcb.StopBits = ONESTOPBIT;
- // SetCommState设置设备的控制块状态;
- memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
- bResult = SetCommState(m_hSerialPort, &m_dcb);
- if (!bResult) {
- CloseHandle(m_hSerialPort);
- m_hSerialPort = INVALID_HANDLE_VALUE;
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // 获取设备的超时值;
- bResult = GetCommTimeouts(m_hSerialPort, &m_cts);
- if (!bResult) {
- CloseHandle(m_hSerialPort);
- m_hSerialPort = INVALID_HANDLE_VALUE;
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // 两字符之间最大的延时,设置0表示参数不起作用;
- m_cts.ReadIntervalTimeout = 50;
- m_cts.ReadTotalTimeoutMultiplier = 100;
- m_cts.ReadTotalTimeoutConstant = 8000;
- m_cts.WriteTotalTimeoutMultiplier = 100;
- m_cts.WriteTotalTimeoutConstant = 5000;
- // 设置设备的超时值;
- bResult = SetCommTimeouts(m_hSerialPort, &m_cts);
- if (!bResult) {
- CloseHandle(m_hSerialPort);
- m_hSerialPort = INVALID_HANDLE_VALUE;
- DWORD dwError = GetLastError();
- return FALSE;
- }
- return TRUE;
- }
- BOOL CSynSerial::ReOpenSerialPort()
- {
- ASSERT(_tcslen(m_szSerialPort));
- CloseSerialPort();
- m_hSerialPort = CreateFile(m_szSerialPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- if (m_hSerialPort == INVALID_HANDLE_VALUE)
- {
- // 打开串口失败;
- DWORD dwError = GetLastError();
- return FALSE;
- }
- BOOL bResult = FALSE;
- // SetupComm设置缓冲区大小;
- bResult = SetupComm(m_hSerialPort, m_dwInQueue, m_dwOutQueue);
- if (!bResult)
- {
- CloseHandle(m_hSerialPort);
- m_hSerialPort = INVALID_HANDLE_VALUE;
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // 在串口读写之前,清除缓冲区;
- bResult = PurgeComm(m_hSerialPort, PURGE_TXCLEAR | PURGE_RXCLEAR);
- if (!bResult)
- {
- CloseHandle(m_hSerialPort);
- m_hSerialPort = INVALID_HANDLE_VALUE;
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // SetCommState设置设备的控制块状态;
- memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
- bResult = SetCommState(m_hSerialPort, &m_dcb);
- if (!bResult)
- {
- CloseHandle(m_hSerialPort);
- m_hSerialPort = INVALID_HANDLE_VALUE;
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // 设置设备的超时值;
- bResult = SetCommTimeouts(m_hSerialPort, &m_cts);
- if (!bResult)
- {
- CloseHandle(m_hSerialPort);
- m_hSerialPort = INVALID_HANDLE_VALUE;
- DWORD dwError = GetLastError();
- return FALSE;
- }
- return TRUE;
- }
- void CSynSerial::CloseSerialPort()
- {
- if (m_hSerialPort != NULL && m_hSerialPort != INVALID_HANDLE_VALUE)
- CloseHandle(m_hSerialPort);
- m_hSerialPort = INVALID_HANDLE_VALUE;
- }
- BOOL CSynSerial::SetSerialPort(IN CONST DWORD & dwBaudRate, IN CONST BYTE & byByteSize, IN CONST BYTE & byParity, IN CONST BYTE & byStopBits, IN CONST BYTE & byStartAddr, IN CONST DWORD & dwInQueue, IN CONST DWORD & dwOutQueue)
- {
- if (!IsOpen())
- return FALSE;
- BOOL bResult = FALSE;
- // GetCommState获取设备控制块状态;
- memset(&m_dcb, 0, sizeof(DCB));
- bResult = GetCommState(m_hSerialPort, &m_dcb);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- m_dcb.Parity = byParity;
- if (m_dcb.Parity == NOPARITY)
- m_dcb.fParity = FALSE;
- else
- m_dcb.fParity = TRUE;
- m_dcb.BaudRate = dwBaudRate;
- m_dcb.ByteSize = byByteSize;
- m_dcb.StopBits = byStopBits;
- if (m_dcb.ByteSize == 8)
- m_dcb.StopBits = ONESTOPBIT;
- // SetCommState设置设备的控制块状态;
- memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
- bResult = SetCommState(m_hSerialPort, &m_dcb);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // 获取设备的超时值;
- bResult = GetCommTimeouts(m_hSerialPort, &m_cts);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // 两字符之间最大的延时,设置0表示参数不起作用;
- m_cts.ReadIntervalTimeout = 50;
- m_cts.ReadTotalTimeoutMultiplier = 100;
- m_cts.ReadTotalTimeoutConstant = 8000;
- m_cts.WriteTotalTimeoutMultiplier = 100;
- m_cts.WriteTotalTimeoutConstant = 3000;
- // 设置设备的超时值;
- bResult = SetCommTimeouts(m_hSerialPort, &m_cts);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- return TRUE;
- }
- void CSynSerial::SetSerialDCB(IN CONST DCB & dcb)
- {
- }
- void CSynSerial::SetSerialCommTimeouts(IN CONST COMMTIMEOUTS & commTimeouts)
- {
- }
- bool CSynSerial::WriteComm(IN BYTE * pWirteBuf, IN CONST INT32 nWriteSize)
- {
- if (!IsOpen())
- return false;
- if (pWirteBuf == NULL || !::AfxIsValidAddress(pWirteBuf, nWriteSize, FALSE))
- {
- return false;
- }
-
- DWORD dwErrorFlags;
- DWORD dwBytesWritten = 0; // 实际写入的字节数;
- // 写前, 清除错误;
- COMSTAT ComStat;
- ClearCommError(m_hSerialPort, &dwErrorFlags, &ComStat);
- // 写前,清空缓存区;
- PurgeComm(m_hSerialPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
- if ( !WriteFile(m_hSerialPort, pWirteBuf, nWriteSize, &dwBytesWritten, &m_writeOverlapped) ) {
- DWORD dwError = GetLastError();
- if ( ERROR_IO_PENDING == GetLastError() ) {
- while(!GetOverlappedResult(m_hSerialPort, &m_writeOverlapped, &dwBytesWritten, FALSE)){
- #if 0
- printf("\t\t写串口出错: %d,%d,%d,%d,%d,%d\n",
- GetLastError(), m_writeOverlapped.Internal, m_writeOverlapped.InternalHigh,
- m_writeOverlapped.Offset, m_writeOverlapped.OffsetHigh,dwBytesWritten);
- #endif
- }
- }
- }
- #ifdef _DEBUG
- if (dwBytesWritten == nWriteSize)
- printf("\t写串口成功:%s\n", pWirteBuf);
- else
- printf("\t写串口失败:%s\n",pWirteBuf);
- #endif
- // 返回写入字节数;
- return (dwBytesWritten == nWriteSize);
- }
- DWORD CSynSerial::ReadComm(IN BYTE *pReadBuf, IN CONST DWORD& dwReadSize, WORD timeout /* = 300 */)
- {
- if (!IsOpen())
- return 0;
- if (pReadBuf == NULL || !::AfxIsValidAddress(pReadBuf, dwReadSize, FALSE))
- {
- return 0;
- }
- DWORD dwError = 0;
- DWORD dwRealRead = 0;
- if ( !ClearCommError(m_hSerialPort, &dwError, NULL) ) {
- PurgeComm(m_hSerialPort, PURGE_TXABORT|PURGE_TXCLEAR);
- }
-
- if ( !ReadFile(m_hSerialPort, pReadBuf, dwReadSize, &dwRealRead, &m_readOverlapped) ) {
- if ( STATUS_PENDING == m_readOverlapped.Internal ) {
- while(!GetOverlappedResult(m_hSerialPort, &m_readOverlapped, &dwRealRead, FALSE)){
- #if 0
- static int i = 0;
- static TCHAR szLog[MAX_PATH] ;
- Sleep(20);
- _stprintf_s(szLog,"\t\t读串口出错: %d = %d,%d,%d,%d,%d,%d\n", ++i,
- GetLastError(), m_readOverlapped.Internal, m_readOverlapped.InternalHigh,
- m_readOverlapped.Offset, m_readOverlapped.OffsetHigh, dwRealRead);
- OutputDebugString(szLog);
- #endif
- // 是否仍在等待;
- if ( STATUS_PENDING != m_readOverlapped.Internal ) {
- break;
- }
-
- // 线程是否结束;
- if ( m_hThread && WaitForSingleObject(m_hEvent, 0) == WAIT_OBJECT_0 )
- break;
- }
- }
- }
-
- return m_readOverlapped.InternalHigh;
- }
- void CSynSerial::StartThread()
- {
- if ( m_hEvent || m_hThread )
- return;
- m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- if ( m_hEvent == NULL )
- return;
- m_hThread = CreateThread(NULL, 0, ThreadWatch, this, 0, NULL);
- if ( m_hThread == NULL ) {
- SetEvent(m_hEvent);
- CloseHandle(m_hEvent);
- m_hEvent = NULL;
- }
- }
- void CSynSerial::EndofThread()
- {
- // 设置有信号;
- if ( m_hEvent ) {
- SetEvent(m_hEvent);
- }
- // 等待线程结束;
- if ( m_hThread ) {
- WaitForSingleObject(m_hThread, INFINITE);
- CloseHandle(m_hThread);
- m_hThread = NULL;
- }
- if ( m_hEvent )
- CloseHandle(m_hEvent);
- m_hEvent = NULL;
- }
- void CSynSerial::SwapBuffers(TCHAR *szValue, DWORD dwRealRead)
- {
- #if 0 // 过于复杂的逻辑处理
- int nLeft = 0;
- bool bFist = true; // 是否填充完整过;
- int nIndex = 0;
- if ( s_nCurPos + dwRealRead <= BUFFER_LEN ) {
- memcpy_s(&s_byBuffer[s_nCurPos], BUFFER_LEN-s_nCurPos, szValue, dwRealRead);
- s_nCurPos += dwRealRead;
- } else {
- nLeft = dwRealRead - (nIndex = BUFFER_LEN - s_nCurPos);
-
- // 先将尾部填充;
- memcpy_s(&s_byBuffer[s_nCurPos], BUFFER_LEN-s_nCurPos, szValue, BUFFER_LEN-s_nCurPos);
- // 剩余是否大于缓冲区;
- while ( nLeft > BUFFER_LEN ) {
- // 先复制尾部;
- nIndex += BUFFER_LEN;
- memcpy_s(s_byBuffer, BUFFER_LEN, &szValue[nIndex], BUFFER_LEN);
- nLeft -= BUFFER_LEN;
- }
- s_nCurPos = nLeft;
- // 处理最后剩余的数据;
- if ( nLeft != 0 ) {
- memcpy_s(s_byBuffer, nLeft, &szValue[nIndex], nLeft);
- }
- }
- m_strbuffer.append(szValue, dwRealRead);
- // 超过10倍才清空;
- if ( m_strbuffer.size() > BUFFER_LEN*3) {
- m_strbuffer.resize(0);
- m_strbuffer.clear();
- // 如果遇到\0开头,显示空字符,但实现有内容;
- m_strbuffer.append((char*)&s_byBuffer[s_nCurPos], BUFFER_LEN - s_nCurPos);
- m_strbuffer.append((char*)s_byBuffer, s_nCurPos);
- }
- #else
- if ( m_strbuffer.length() > BUFFER_LEN * 10 ) {
- int nIndex = 0;
- m_strbuffer = m_strbuffer.substr(BUFFER_LEN * 9);
- if ( (nIndex = m_strbuffer.find_first_of('\r')) != std::string::npos )
- m_strbuffer = m_strbuffer.substr(nIndex+1);
- }
-
- m_strbuffer.append(szValue, dwRealRead);
- #endif
- printf("内容:%s\n", m_strbuffer.c_str());
- }
- DWORD CSynSerial::ThreadWatch(LPVOID lpVoid)
- {
- int nLeft = 0;
- bool bFist = true; // 是否填充完整过;
- int nIndex = 0;
- DWORD dwRealRead;
- TCHAR szValue[1024] = {0};
- CSynSerial *pthat = (CSynSerial*)lpVoid;
-
- do
- {
- memset(szValue, 0, 1024);
- if ( (dwRealRead = pthat->ReadComm((BYTE*)szValue, 1024)) > 0) {
- AutoThreadSection aSection(&s_csClearBuffer);
- #ifdef _DEBUG
- OutputDebugString(_T("内容:"));
- OutputDebugString(szValue);
- OutputDebugString(_T("\n"));
- #endif
- #if 1
- if ( pthat->m_strbuffer.length() > BUFFER_LEN * 10 ) {
- int nIndex = 0;
- pthat->m_strbuffer = pthat->m_strbuffer.substr(BUFFER_LEN * 9);
- if ( (nIndex = pthat->m_strbuffer.find_first_of('\r')) != std::string::npos )
- pthat->m_strbuffer = pthat->m_strbuffer.substr(nIndex+1);
- }
- pthat->m_strbuffer.append(szValue, dwRealRead);
- #else // 这里如果不及时清除,内存越来越大;
- pthat->m_strbuffer.append(szValue, dwRealRead);
- #endif
- }
- } while ( WaitForSingleObject(pthat->m_hEvent, 30) == WAIT_TIMEOUT );
- #ifdef _DEBUG
- printf("线程结束\n");
- #endif
- return 0;
- }
- bool CSynSerial::FindWord(std::string strWord, int nWatchTime )
- {
- bool found = false;
- int nSize = nWatchTime/30;
- for ( int i = 0; i < nSize; i++ ) {
- if ( m_strbuffer.find(strWord) != std::string::npos ) {
- found = true;
- break;
- }
- Sleep(30);
- }
- return found;
- }
|