www.pudn.com > EvsCommun.rar > SerialPort.cpp
#include "StdAfx.h" #include ".\serialport.h" #includeCSerialPort::CSerialPort(void) : m_bOpen(false) { ::ZeroMemory(&m_Dcb,sizeof(m_Dcb)); m_Dcb.DCBlength = sizeof(m_Dcb); m_hCommu = INVALID_HANDLE_VALUE; m_nBufferIn = m_nBufferOut = 512; ::ZeroMemory(&m_nTimeOut,sizeof(m_nTimeOut)); m_nTimeOut.ReadIntervalTimeout = 100; m_nTimeOut.ReadTotalTimeoutMultiplier = 150; m_nTimeOut.WriteTotalTimeoutConstant = 1000; m_nTimeOut.WriteTotalTimeoutMultiplier = 1000; m_nTimeOut.WriteTotalTimeoutConstant = 1000; ::ZeroMemory(&m_OvlpWrite,sizeof(m_OvlpWrite)); m_OvlpWrite.hEvent = CreateEvent(NULL, true, false, NULL); assert(m_OvlpWrite.hEvent != INVALID_HANDLE_VALUE); ::ZeroMemory(&m_OvlpRead,sizeof(m_OvlpRead)); m_OvlpRead.hEvent = CreateEvent(NULL,true,false,NULL); } CSerialPort::~CSerialPort(void) { if(m_bOpen) Close(); } void CSerialPort::Init(void) { } void CSerialPort::Close(void) { if(m_bOpen) ::CloseHandle(m_hCommu); m_bOpen = false; m_hCommu = INVALID_HANDLE_VALUE; ::ResetEvent(m_OvlpWrite.hEvent); ::CloseHandle(m_OvlpWrite.hEvent); ::ResetEvent(m_OvlpRead.hEvent); ::CloseHandle(m_OvlpRead.hEvent); } bool CSerialPort::Open(UINT nPort,DWORD BaudRate, BYTE ByteSize,BYTE Parity, BYTE StopBits) { m_nPort = nPort; if(m_bOpen) Close(); char com_str[10]; strcpy(com_str, "COM"); ltoa(m_nPort, com_str + 3, 10); m_hCommu = CreateFile( com_str, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, //重叠I/O NULL ); if(m_hCommu == INVALID_HANDLE_VALUE) return false; BOOL tempBit; //---------------------------------------------------------------------- //设置缓冲区 tempBit = SetupComm(m_hCommu,m_nBufferIn,m_nBufferOut); if(!tempBit) return false; //----------------------------------------------------------------------- //设置串口参数:波特率,数据位......等等 tempBit = GetCommState(m_hCommu,&m_Dcb); if(!tempBit) return false; m_Dcb.BaudRate = BaudRate; m_Dcb.ByteSize = ByteSize; m_Dcb.Parity = NOPARITY;//MODBUS的特殊需要 m_Dcb.StopBits = StopBits; tempBit = SetCommState(m_hCommu,&m_Dcb); if(!tempBit) return false; //------------------------------------------------------------------------------ //设置超时时间 tempBit = SetCommTimeouts(m_hCommu, &m_nTimeOut); if(!tempBit) return false; //-------------------------------------------------------------------------------- //清空串口缓冲区 tempBit = PurgeComm(m_hCommu,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); if(!tempBit) return false; //----------------------------------------------------------------------------------- m_bOpen = true; return true; } //用于多机通信 bool CSerialPort::SetParityBit(BYTE nParity) { m_Dcb.Parity = nParity; if(SetCommState(m_hCommu,&m_Dcb)) return true; return false; } //在开串口之前调用有效 void CSerialPort::InitBufferSize(UINT nBufferIn, UINT nBufferOut) { m_nBufferIn = nBufferIn; m_nBufferOut = nBufferOut; } //异步写数据 bool CSerialPort::WriteData(BYTE* pWriteBuff, WORD nWrite) { if(!m_bOpen) return false; assert(pWriteBuff); m_OvlpWrite.Offset = 0; m_OvlpWrite.OffsetHigh = 0; DWORD dwError; COMSTAT state; ::ClearCommError(m_hCommu,&dwError,&state);//清除错误标志 PurgeComm(m_hCommu, PURGE_TXABORT | PURGE_TXCLEAR |PURGE_TXCLEAR | PURGE_RXCLEAR);//清空缓冲区和终止发送与接收 DWORD nRealWrite = 0; BOOL bResult; bool bWrite = true; bResult = WriteFile(m_hCommu,pWriteBuff,nWrite,&nRealWrite,&m_OvlpWrite);//异步写 if(!bResult) { dwError = ::GetLastError(); switch(dwError) { case ERROR_IO_PENDING: { bWrite = false; break; } default:return false; } } if(!bWrite) { bResult = ::GetOverlappedResult(m_hCommu,&m_OvlpWrite,&nRealWrite,true); if(!bResult) return false; bWrite = true; } return true; } //异步读数据 DWORD CSerialPort::ReadData(BYTE* pReadBuff, WORD nRead) { COMSTAT state; BOOL bResult; DWORD dwError = 0; DWORD nRealRead = 0; bool bRead = true; ::ClearCommError(m_hCommu,&dwError,&state); bResult = ::ReadFile(m_hCommu,pReadBuff,nRead,&nRealRead,&m_OvlpRead); if(!bResult) { dwError = ::GetLastError(); switch(dwError) { case ERROR_IO_PENDING: { bRead = false; break; } default:return false; } } if(!bRead) { bResult = ::GetOverlappedResult(m_hCommu,&m_OvlpRead,&nRealRead,true); if(!bResult) return false; bRead = true; } return nRealRead; }