📄 serialport.cpp
字号:
case DsrDtrFlowControl:
{
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = TRUE;
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
break;
}
case XonXoffFlowControl:
{
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fOutX = TRUE;
dcb.fInX = TRUE;
dcb.XonChar = 0x11;
dcb.XoffChar = 0x13;
dcb.XoffLim = 100;
dcb.XonLim = 100;
break;
}
default:
{
ASSERT(FALSE);
break;
}
}
//Now that we have all the settings in place, make the changes
SetState(dcb);
}
void CSerialPort::Close()
{
if (IsOpen())
{
//Close down the comms port
BOOL bSuccess = CloseHandle(m_hComm);
m_hComm = INVALID_HANDLE_VALUE;
if (!bSuccess)
TRACE(_T("CSerialPort::Close, Failed to close up the comms port, Error:%d\n"), GetLastError());
//Free the event object we are using
if (m_hEvent)
{
CloseHandle(m_hEvent);
m_hEvent = NULL;
}
}
}
void CSerialPort::Attach(HANDLE hComm)
{
Close();
//Validate our parameters, now that the port has been closed
ASSERT(m_hComm == INVALID_HANDLE_VALUE);
ASSERT(m_hEvent == NULL);
m_hComm = hComm;
//Create the event we need for later synchronisation use
m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (m_hEvent == NULL)
{
DWORD dwLastError = GetLastError();
Close();
TRACE(_T("CSerialPort::Attach, Failed in call to CreateEvent in Attach, Error:%d\n"), dwLastError);
ThrowSerialException(dwLastError);
}
}
HANDLE CSerialPort::Detach()
{
//What will be the return value from this function
HANDLE hrVal = m_hComm;
m_hComm = INVALID_HANDLE_VALUE;
if (m_hEvent)
{
CloseHandle(m_hEvent);
m_hEvent = NULL;
}
return hrVal;
}
DWORD CSerialPort::Read(void* lpBuf, DWORD dwCount)
{
//Validate our parameters
ASSERT(IsOpen());
DWORD dwBytesRead = 0;
if (!ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, NULL))
{
DWORD dwLastError = GetLastError();
TRACE(_T("CSerialPort::Read, Failed in call to ReadFile, Error:%d\n"), dwLastError);
ThrowSerialException(dwLastError);
}
return dwBytesRead;
}
BOOL CSerialPort::Read(void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped, DWORD* pBytesRead)
{
//Validate our parameters
ASSERT(IsOpen());
DWORD dwBytesRead = 0;
BOOL bSuccess = ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, &overlapped);
if (!bSuccess)
{
DWORD dwLastError = GetLastError();
if (dwLastError != ERROR_IO_PENDING)
{
TRACE(_T("CSerialPort::Read, Failed in call to ReadFile, Error:%d\n"), dwLastError);
ThrowSerialException(dwLastError);
}
}
else
{
if (pBytesRead)
*pBytesRead = dwBytesRead;
}
return bSuccess;
}
DWORD CSerialPort::Write(const void* lpBuf, DWORD dwCount)
{
//Validate our parameters
ASSERT(IsOpen());
DWORD dwBytesWritten = 0;
if (!WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, NULL))
{
DWORD dwLastError = GetLastError();
TRACE(_T("CSerialPort::Write, Failed in call to WriteFile, Error:%d\n"), dwLastError);
ThrowSerialException(dwLastError);
}
return dwBytesWritten;
}
BOOL CSerialPort::Write(const void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped, DWORD* pBytesWritten)
{
//Validate our parameters
ASSERT(IsOpen());
DWORD dwBytesWritten = 0;
BOOL bSuccess = WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, &overlapped);
if (!bSuccess)
{
DWORD dwLastError = GetLastError();
if (dwLastError != ERROR_IO_PENDING)
{
TRACE(_T("CSerialPort::Write, Failed in call to WriteFile, Error:%d\n"), dwLastError);
ThrowSerialException(dwLastError);
}
}
else
{
if (pBytesWritten)
*pBytesWritten = dwBytesWritten;
}
return bSuccess;
}
void CSerialPort::GetOverlappedResult(OVERLAPPED& overlapped, DWORD& dwBytesTransferred, BOOL bWait)
{
//Validate our parameters
ASSERT(IsOpen());
if (!::GetOverlappedResult(m_hComm, &overlapped, &dwBytesTransferred, bWait))
{
DWORD dwLastError = GetLastError();
if (dwLastError != ERROR_IO_INCOMPLETE)
{
TRACE(_T("CSerialPort::GetOverlappedResult, Failed in call to GetOverlappedResult, Error:%d\n"), dwLastError);
ThrowSerialException(dwLastError);
}
}
}
void CSerialPort::_OnCompletion(DWORD dwErrorCode, DWORD dwCount, LPOVERLAPPED lpOverlapped)
{
//Validate our parameters
ASSERT(lpOverlapped);
//Convert back to the C++ world
CSerialPort* pSerialPort = static_cast<CSerialPort*>(lpOverlapped->hEvent);
ASSERT(pSerialPort);
//Call the C++ function
pSerialPort->OnCompletion(dwErrorCode, dwCount, lpOverlapped);
}
void CSerialPort::OnCompletion(DWORD /*dwErrorCode*/, DWORD /*dwCount*/, LPOVERLAPPED lpOverlapped)
{
//Just free 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
}
void CSerialPort::CancelIo()
{
//Validate our parameters
ASSERT(IsOpen());
if (m_lpfnCancelIo == NULL)
{
TRACE(_T("CSerialPort::CancelIo, 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"));
ThrowSerialException(ERROR_CALL_NOT_IMPLEMENTED);
}
if (!m_lpfnCancelIo(m_hComm))
{
DWORD dwLastError = GetLastError();
TRACE(_T("Failed in call to CancelIO, Error:%d\n"), dwLastError);
ThrowSerialException(dwLastError);
}
}
DWORD CSerialPort::BytesWaiting()
{
//Validate our parameters
ASSERT(IsOpen());
//Check to see how many characters are unread
COMSTAT stat;
GetStatus(stat);
return stat.cbInQue;
}
BOOL CSerialPort::DataWaiting(DWORD dwTimeout)
{
//Validate our parameters
ASSERT(IsOpen());
//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)
{
//Validate our parameters
ASSERT(IsOpen());
OVERLAPPED* pOverlapped = new OVERLAPPED;
memset(pOverlapped, 0, sizeof(OVERLAPPED));
pOverlapped->hEvent = static_cast<HANDLE>(this);
if (!WriteFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
{
DWORD dwLastError = GetLastError();
delete pOverlapped;
TRACE(_T("CSerialPort::WriteEx, Failed in call to WriteFileEx, Error:%d\n"), dwLastError);
ThrowSerialException(dwLastError);
}
}
void CSerialPort::ReadEx(void* lpBuf, DWORD dwCount)
{
//Validate our parameters
ASSERT(IsOpen());
OVERLAPPED* pOverlapped = new OVERLAPPED;
memset(pOverlapped, 0, sizeof(OVERLAPPED));
pOverlapped->hEvent = static_cast<HANDLE>(this);
if (!ReadFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
{
DWORD dwLastError = GetLastError();
delete pOverlapped;
TRACE(_T("CSerialPort::ReadEx, Failed in call to ReadFileEx, Error:%d\n"), dwLastError);
ThrowSerialException(dwLastError);
}
}
void CSerialPort::TransmitChar(char cChar)
{
//Validate our parameters
ASSERT(IsOpen());
if (!TransmitCommChar(m_hComm, cChar))
{
DWORD dwLastError = GetLastError();
TRACE(_T("CSerialPort::TransmitChar, Failed in call to TransmitCommChar, Error:%d\n"), dwLastError);
ThrowSerialException(dwLastError);
}
}
void CSerialPort::GetConfig(COMMCONFIG& config)
{
//Validate our parameters
ASSERT(IsOpen());
DWORD dwSize = sizeof(COMMCONFIG);
if (!GetCommConfig(m_hComm, &config, &dwSize))
{
DWORD dwLastError = GetLastError();
TRACE(_T("CSerialPort::GetConfig, Failed in call to GetCommConfig, Error:%d\n"), dwLastError);
ThrowSerialException(dwLastError);
}
}
void CSerialPort::SetConfig(COMMCONFIG& config)
{
//Validate our parameters
ASSERT(IsOpen());
DWORD dwSize = sizeof(COMMCONFIG);
if (!SetCommConfig(m_hComm, &config, dwSize))
{
DWORD dwLastError = GetLastError();
TRACE(_T("CSerialPort::SetConfig, Failed in call to SetCommConfig, Error:%d\n"), dwLastError);
ThrowSerialException(dwLastError);
}
}
void CSerialPort::SetBreak()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -