#include "StdAfx.h" #include "CommRS232.h" CCommRS232::CCommRS232(void) { m_hComm = NULL; m_bOpened = FALSE; m_byCommPort = 1; m_dwBaudRate = BAUD_9600; m_bySize = 8; m_byParity = 0; m_byStopBits = 1; m_byStartAddr = 1; m_nInterval = 1000; } CCommRS232::~CCommRS232(void) { if ( m_hComm != NULL && m_hComm != INVALID_HANDLE_VALUE ) CloseHandle(m_hComm); m_hComm = NULL; m_bOpened = FALSE; } BOOL CCommRS232::InitComm( 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); m_byCommPort = byCommPort; m_dwBaudRate = dwBaudRate; m_bySize = bySize; m_byParity = byParity; m_byStopBits = byStopBits; m_byStartAddr = byStartAddr; m_nInterval = nInterval; // 关闭串口句柄; m_bOpened = FALSE; if ( m_hComm != NULL && m_hComm != INVALID_HANDLE_VALUE ) { CloseHandle(m_hComm); } m_hComm = NULL; DCB dcb; COMMTIMEOUTS timeout; BOOL bResult = FALSE; TCHAR szTmp[MAX_PATH] = _T("\\\\.\\com"); TCHAR szPort[5] = {0}; _ltot_s(byCommPort, szPort, 10); _tcscat_s(szTmp, szPort); // 以独占方式打开串口; m_hComm = CreateFile(szTmp, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, NULL , NULL); if( m_hComm == INVALID_HANDLE_VALUE) { LOG4C_NO_FILENUM((LOG_NOTICE,"打开串口失败:%s",szTmp)); return FALSE; } // SetupComm设置缓冲区大小; bResult = SetupComm(m_hComm, 1024, 1024); ASSERT(bResult); if( !bResult ) return FALSE; // 在串口读写之前,清除缓冲区; bResult = PurgeComm(m_hComm, PURGE_TXCLEAR|PURGE_RXCLEAR); ASSERT(bResult); if(!bResult) return FALSE; ////////////////////////////////////////////////////////////////////////// // GetCommState获取设备控制块状态; bResult = GetCommState(m_hComm, &dcb); ASSERT(bResult); if(!bResult) return FALSE; dcb.Parity = byParity; if(dcb.Parity == NOPARITY) dcb.fParity = FALSE; else dcb.fParity = TRUE; dcb.BaudRate = dwBaudRate; dcb.ByteSize = bySize; dcb.StopBits = byStopBits; if(dcb.ByteSize == 8) dcb.StopBits = ONESTOPBIT; // SetCommState设置设备的控制块状态; bResult = SetCommState(m_hComm, &dcb); ASSERT(bResult); if(!bResult) return FALSE; ////////////////////////////////////////////////////////////////////////// // 获取设备的超时值; bResult = GetCommTimeouts(m_hComm, &timeout); ASSERT(bResult); if(!bResult) return FALSE; timeout.ReadIntervalTimeout = MAXDWORD; timeout.ReadTotalTimeoutMultiplier = 0; timeout.ReadTotalTimeoutConstant = 0; timeout.WriteTotalTimeoutMultiplier = 0; timeout.WriteTotalTimeoutConstant = 0; // 设置设备的超时值; bResult = SetCommTimeouts(m_hComm,&timeout); ASSERT(bResult); if(!bResult) return FALSE; m_bOpened = TRUE; return TRUE; } BOOL CCommRS232::CloseComm() { BOOL bRet = FALSE; if ( m_hComm != NULL && m_hComm != INVALID_HANDLE_VALUE ) bRet = CloseHandle(m_hComm); if ( bRet == FALSE ) return FALSE; m_hComm = NULL; m_bOpened = FALSE; return TRUE; } INT CCommRS232::Write(IN BYTE *pWirteBuf, IN CONST INT& nWriteSize) { if ( !m_bOpened ) return 0; if ( m_hComm == NULL || m_hComm == INVALID_HANDLE_VALUE ) return 0; DWORD dwBytesWritten = 0; // 实际写入的字节数; if ( WriteFile( m_hComm, pWirteBuf, nWriteSize, &dwBytesWritten, NULL) ) { return dwBytesWritten; } return 0; } INT CCommRS232::Read(IN BYTE *pReadBuf, IN CONST INT& nReadSize) { if ( m_hComm == NULL || m_hComm == INVALID_HANDLE_VALUE ) { LOG4C_NO_FILENUM((LOG_NOTICE,"串口句柄空")); return 0; } if ( pReadBuf == NULL || !::AfxIsValidAddress(pReadBuf, nReadSize, FALSE) ) { LOG4C_NO_FILENUM((LOG_NOTICE,"缓冲区指针无效")); return 0; } if ( !m_bOpened ) { LOG4C_NO_FILENUM((LOG_NOTICE,"串口状态无效")); return 0; } BOOL bResult = FALSE; DWORD dwBytesRead = 0; DWORD dwErrorFlags = 0; // ReadFile前,使用ClearCommError清除错误; COMSTAT ComStat; ClearCommError(m_hComm, &dwErrorFlags, &ComStat); DWORD dwTick = GetTickCount(); while ( ComStat.cbInQue <= 0 ) {// cbInQue表示输入缓冲区的字节数; if ( GetTickCount() - dwTick > 3000) break; ClearCommError(m_hComm, &dwErrorFlags, &ComStat); Sleep(100); } if ( ComStat.cbInQue <= 0 ) { LOG4C_NO_FILENUM((LOG_NOTICE,"串口无返回")); return 0; } dwBytesRead = (DWORD) ComStat.cbInQue; if ( nReadSize < (INT)dwBytesRead ) { dwBytesRead = (DWORD)nReadSize; } if ( ReadFile(m_hComm, pReadBuf, dwBytesRead, &dwBytesRead, NULL) ) { LOG4C_NO_FILENUM((LOG_NOTICE,"读:%s,%d", pReadBuf, dwBytesRead)); return (INT)dwBytesRead; } DWORD dwError; dwError = GetLastError(); CString strMsg; strMsg.Format("ReadFile Error! ErrorCode = %d", dwError); LOG4C_NO_FILENUM((LOG_NOTICE,"串口读失败:%s",strMsg)); return 0; }