⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialport.cpp

📁 一个封装好的串口通信类
💻 CPP
📖 第 1 页 / 共 2 页
字号:
bool CSerialPort::GetOverlappedResult(OVERLAPPED& overlapped, 
									  DWORD& dwBytesTransferred, BOOL bWait)
{
	ASSERT(IsOpen());
	ASSERT(m_bOverlapped);
	bool bSuccess = 
		::GetOverlappedResult(m_hComm, &overlapped, &dwBytesTransferred, bWait);
	if (!bSuccess)
	{
		if (GetLastError() != ERROR_IO_PENDING)
		{
			TRACE(_T("Failed in call to GetOverlappedResult\n"));
			AfxThrowSerialException();
		}
	}
	return bSuccess;
}

void CSerialPort::_OnCompletion(DWORD dwErrorCode, DWORD dwCount, LPOVERLAPPED lpOverlapped)
{
	//Validate our parameters
	ASSERT(lpOverlapped);
	
	//Convert back to the C++ world
	CSerialPort* pSerialPort = (CSerialPort*) lpOverlapped->hEvent;
	ASSERT(pSerialPort);
	ASSERT(pSerialPort->IsKindOf(RUNTIME_CLASS(CSerialPort)));
	
	//Call the C++ function
	pSerialPort->OnCompletion(dwErrorCode, dwCount, lpOverlapped);
}

void CSerialPort::OnCompletion(DWORD /*dwErrorCode*/, DWORD /*dwCount*/, LPOVERLAPPED lpOverlapped)
{
	//Just free up the memory which was previously allocated for the OVERLAPPED structure
	delete lpOverlapped;
	
	//Your derived classes can do something useful in OnCompletion, but don't forget to
	//call CSerialPort::OnCompletion to ensure the memory is freed up
}

void CSerialPort::CancelIo()
{
	ASSERT(IsOpen());
	
	if (_SerialPortData.m_lpfnCancelIo == NULL)
	{
		TRACE(_T("CancelIo function is not supported on this OS. You need to be running at least NT 4 or Win 98 to use this function\n"));
		AfxThrowSerialException(ERROR_CALL_NOT_IMPLEMENTED);  
	}
	
	if (!::_SerialPortData.m_lpfnCancelIo(m_hComm))
	{
		TRACE(_T("Failed in call to CancelIO\n"));
		AfxThrowSerialException();
	}
}

DWORD CSerialPort::BytesWaiting()
{
	ASSERT(IsOpen());
	
	//Check to see how many characters are unread
	COMSTAT stat;
	GetStatus(stat);
	return stat.cbInQue;
}

BOOL CSerialPort::DataWaiting(DWORD dwTimeout)
{
	ASSERT(IsOpen());
	ASSERT(m_hEvent);
	//Setup to wait for incoming data
	DWORD dwOldMask;
	GetMask(dwOldMask);
	SetMask(EV_RXCHAR);
	
	//Setup the overlapped structure
	OVERLAPPED o;
	o.hEvent = m_hEvent;
	
	//Assume the worst;
	BOOL bSuccess = FALSE;
	
	DWORD dwEvent;
	bSuccess = WaitEvent(dwEvent, o);
	if (!bSuccess)
	{
		if (WaitForSingleObject(o.hEvent, dwTimeout) == WAIT_OBJECT_0)
		{
			DWORD dwBytesTransferred;
			GetOverlappedResult(o, dwBytesTransferred, FALSE);
			bSuccess = TRUE;
		}
	}
	
	//Reset the event mask
	SetMask(dwOldMask);
	
	return bSuccess;
}

void CSerialPort::WriteEx(const void* lpBuf, DWORD dwCount)
{
	ASSERT(IsOpen());
	
	OVERLAPPED* pOverlapped = new OVERLAPPED;
	ZeroMemory(pOverlapped, sizeof(OVERLAPPED));
	pOverlapped->hEvent = (HANDLE) this;
	if (!WriteFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
	{
		delete pOverlapped;
		TRACE(_T("Failed in call to WriteFileEx\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::ReadEx(void* lpBuf, DWORD dwCount)
{
	ASSERT(IsOpen());
	
	OVERLAPPED* pOverlapped = new OVERLAPPED;
	ZeroMemory(pOverlapped, sizeof(OVERLAPPED));
	pOverlapped->hEvent = (HANDLE) this;
	if (!ReadFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
	{
		delete pOverlapped;
		TRACE(_T("Failed in call to ReadFileEx\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::TransmitChar(char cChar)
{
	ASSERT(IsOpen());
	
	if (!TransmitCommChar(m_hComm, cChar))
	{
		TRACE(_T("Failed in call to TransmitCommChar\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::GetConfig(COMMCONFIG& config)
{
	ASSERT(IsOpen());
	
	DWORD dwSize = sizeof(COMMCONFIG);
	if (!GetCommConfig(m_hComm, &config, &dwSize))
	{
		TRACE(_T("Failed in call to GetCommConfig\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::SetConfig(COMMCONFIG& config)
{
	ASSERT(IsOpen());
	
	DWORD dwSize = sizeof(COMMCONFIG);
	if (!SetCommConfig(m_hComm, &config, dwSize))
	{
		TRACE(_T("Failed in call to SetCommConfig\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::SetBreak()
{
	ASSERT(IsOpen());
	
	if (!SetCommBreak(m_hComm))
	{
		TRACE(_T("Failed in call to SetCommBreak\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::ClearBreak()
{
	ASSERT(IsOpen());
	
	if (!ClearCommBreak(m_hComm))
	{
		TRACE(_T("Failed in call to SetCommBreak\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::ClearError(DWORD& dwErrors)
{
	ASSERT(IsOpen());
	
	if (!ClearCommError(m_hComm, &dwErrors, NULL))
	{
		TRACE(_T("Failed in call to ClearCommError\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::GetDefaultConfig(int nPort, COMMCONFIG& config)
{
	//Validate our parameters
	ASSERT(nPort>0 && nPort<=255);
	
	//Create the device name as a string
	CString sPort;
	sPort.Format(_T("COM%d"), nPort);
	
	DWORD dwSize = sizeof(COMMCONFIG);
	if (!GetDefaultCommConfig(sPort, &config, &dwSize))
	{
		TRACE(_T("Failed in call to GetDefaultCommConfig\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::SetDefaultConfig(int nPort, COMMCONFIG& config)
{
	//Validate our parameters
	ASSERT(nPort>0 && nPort<=255);
	
	//Create the device name as a string
	CString sPort;
	sPort.Format(_T("COM%d"), nPort);
	
	DWORD dwSize = sizeof(COMMCONFIG);
	if (!SetDefaultCommConfig(sPort, &config, dwSize))
	{
		TRACE(_T("Failed in call to GetDefaultCommConfig\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::GetStatus(COMSTAT& stat)
{
	ASSERT(IsOpen());
	
	DWORD dwErrors;
	if (!ClearCommError(m_hComm, &dwErrors, &stat))
	{
		TRACE(_T("Failed in call to ClearCommError\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::GetState(DCB& dcb)
{
	ASSERT(IsOpen());
	
	if (!GetCommState(m_hComm, &dcb))
	{
		TRACE(_T("Failed in call to GetCommState\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::SetState(DCB& dcb)
{
	ASSERT(IsOpen());
	
	if (!SetCommState(m_hComm, &dcb))
	{
		TRACE(_T("Failed in call to SetCommState\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::Escape(DWORD dwFunc)
{
	ASSERT(IsOpen());
	
	if (!EscapeCommFunction(m_hComm, dwFunc))
	{
		TRACE(_T("Failed in call to EscapeCommFunction\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::ClearDTR()
{
	Escape(CLRDTR);
}

void CSerialPort::ClearRTS()
{
	Escape(CLRRTS);
}

void CSerialPort::SetDTR()
{
	Escape(SETDTR);
}

void CSerialPort::SetRTS()
{
	Escape(SETRTS);
}

void CSerialPort::SetXOFF()
{
	Escape(SETXOFF);
}

void CSerialPort::SetXON()
{
	Escape(SETXON);
}

void CSerialPort::GetProperties(COMMPROP& properties)
{
	ASSERT(IsOpen());
	
	if (!GetCommProperties(m_hComm, &properties))
	{
		TRACE(_T("Failed in call to GetCommProperties\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::GetModemStatus(DWORD& dwModemStatus)
{
	ASSERT(IsOpen());
	
	if (!GetCommModemStatus(m_hComm, &dwModemStatus))
	{
		TRACE(_T("Failed in call to GetCommModemStatus\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::SetMask(DWORD dwMask)
{
	ASSERT(IsOpen());
	
	if (!SetCommMask(m_hComm, dwMask))
	{
		TRACE(_T("Failed in call to SetCommMask\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::GetMask(DWORD& dwMask)
{
	ASSERT(IsOpen());
	
	if (!GetCommMask(m_hComm, &dwMask))
	{
		TRACE(_T("Failed in call to GetCommMask\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::Flush()
{
	ASSERT(IsOpen());
	
	if (!FlushFileBuffers(m_hComm))
	{
		TRACE(_T("Failed in call to FlushFileBuffers\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::Purge(DWORD dwFlags)
{
	ASSERT(IsOpen());
	
	if (!PurgeComm(m_hComm, dwFlags))
	{
		TRACE(_T("Failed in call to PurgeComm\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::TerminateOutstandingWrites()
{
	Purge(PURGE_TXABORT);
}

void CSerialPort::TerminateOutstandingReads()
{
	Purge(PURGE_RXABORT);
}

void CSerialPort::ClearWriteBuffer()
{
	Purge(PURGE_TXCLEAR);
}

void CSerialPort::ClearReadBuffer()
{
	Purge(PURGE_RXCLEAR);
}

void CSerialPort::Setup(DWORD dwInQueue, DWORD dwOutQueue)
{
	ASSERT(IsOpen());
	
	if (!SetupComm(m_hComm, dwInQueue, dwOutQueue))
	{
		TRACE(_T("Failed in call to SetupComm\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::SetTimeouts(COMMTIMEOUTS& timeouts)
{
	ASSERT(IsOpen());
	
	if (!SetCommTimeouts(m_hComm, &timeouts))
	{
		TRACE(_T("Failed in call to SetCommTimeouts\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::GetTimeouts(COMMTIMEOUTS& timeouts)
{
	ASSERT(IsOpen());
	
	if (!GetCommTimeouts(m_hComm, &timeouts))
	{
		TRACE(_T("Failed in call to GetCommTimeouts\n"));
		AfxThrowSerialException();
	}
}

void CSerialPort::Set0Timeout()
{
	COMMTIMEOUTS Timeouts;
	ZeroMemory(&Timeouts, sizeof(COMMTIMEOUTS));
	Timeouts.ReadIntervalTimeout = MAXDWORD;
	SetTimeouts(Timeouts);
}

void CSerialPort::Set0WriteTimeout()
{
	COMMTIMEOUTS Timeouts;
	GetTimeouts(Timeouts);
	Timeouts.WriteTotalTimeoutMultiplier = 0;
	Timeouts.WriteTotalTimeoutConstant = 0;
	SetTimeouts(Timeouts);
}

void CSerialPort::Set0ReadTimeout()
{
	COMMTIMEOUTS Timeouts;
	GetTimeouts(Timeouts);
	Timeouts.ReadIntervalTimeout = MAXDWORD;
	Timeouts.ReadTotalTimeoutMultiplier = 0;
	Timeouts.ReadTotalTimeoutConstant = 0;
	SetTimeouts(Timeouts);
}

bool CSerialPort::WaitEvent(DWORD& dwMask)
{
	ASSERT(IsOpen());
	ASSERT(!m_bOverlapped);
	
	if (!WaitCommEvent(m_hComm, &dwMask, NULL))
	{
		TRACE(_T("Failed in call to WaitCommEvent\n"));
		//AfxThrowSerialException();
		return false;
	}
	else
		return true;
	
}

BOOL CSerialPort::WaitEvent(DWORD& dwMask, OVERLAPPED& overlapped)
{
	ASSERT(IsOpen());
	ASSERT(m_bOverlapped);
	ASSERT(overlapped.hEvent);
	
	BOOL bSuccess = WaitCommEvent(m_hComm, &dwMask, &overlapped);
	if (!bSuccess)
	{
		if (GetLastError() != ERROR_IO_PENDING)
		{
			TRACE(_T("Failed in call to WaitCommEvent\n"));
			AfxThrowSerialException();
		}
	}
	
	return bSuccess;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -