|
@@ -0,0 +1,404 @@
|
|
|
+/************************************************************************/
|
|
|
+/* Copyright (C), 2016-2020, [Home], 保留所有权利;
|
|
|
+/* 模 块 名:异步串口模块;
|
|
|
+/* 描 述:;
|
|
|
+/*
|
|
|
+/* 版 本:[V];
|
|
|
+/* 作 者:[Home];
|
|
|
+/* 日 期:[12/20/2017];
|
|
|
+/*
|
|
|
+/*
|
|
|
+/* 注 意:;
|
|
|
+/*
|
|
|
+/* 修改记录:[Home];
|
|
|
+/* 修改日期:;
|
|
|
+/* 修改版本:;
|
|
|
+/* 修改内容:;
|
|
|
+/************************************************************************/
|
|
|
+
|
|
|
+#ifndef __BASE_SERIAL__
|
|
|
+#define __BASE_SERIAL__
|
|
|
+
|
|
|
+#pragma once
|
|
|
+
|
|
|
+class CBaseSerial
|
|
|
+{
|
|
|
+public:
|
|
|
+ //Enums
|
|
|
+ enum FlowControl
|
|
|
+ {
|
|
|
+ NoFlowControl,
|
|
|
+ CtsRtsFlowControl,
|
|
|
+ CtsDtrFlowControl,
|
|
|
+ DsrRtsFlowControl,
|
|
|
+ DsrDtrFlowControl,
|
|
|
+ XonXoffFlowControl
|
|
|
+ };
|
|
|
+
|
|
|
+ enum Parity
|
|
|
+ {
|
|
|
+ NoParity = 0,
|
|
|
+ OddParity = 1,
|
|
|
+ EvenParity = 2,
|
|
|
+ MarkParity = 3,
|
|
|
+ SpaceParity = 4
|
|
|
+ };
|
|
|
+
|
|
|
+ enum StopBits
|
|
|
+ {
|
|
|
+ OneStopBit,
|
|
|
+ OnePointFiveStopBits,
|
|
|
+ TwoStopBits
|
|
|
+ };
|
|
|
+protected:
|
|
|
+ HANDLE m_hComm;
|
|
|
+public:
|
|
|
+ CBaseSerial(void);
|
|
|
+ virtual ~CBaseSerial(void);
|
|
|
+
|
|
|
+ BOOL IsOpen() const throw() // noexcept
|
|
|
+ {
|
|
|
+ return m_hComm != INVALID_HANDLE_VALUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ void Close() throw() // noexcept
|
|
|
+ {
|
|
|
+ if (IsOpen())
|
|
|
+ {
|
|
|
+ CloseHandle(m_hComm);
|
|
|
+ m_hComm = INVALID_HANDLE_VALUE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL Open(LPCTSTR pszPort, BOOL bOverlapped = FALSE) throw(); // noexcept
|
|
|
+ BOOL Open(int nPort, DWORD dwBaud = 9600, int parity = NoParity, BYTE DataBits = 8, int stopBits = OneStopBit, int fc = NoFlowControl, BOOL bOverlapped = FALSE);
|
|
|
+ BOOL Open(LPCTSTR pszPort, DWORD dwBaud = 9600, int parity = NoParity, BYTE DataBits = 8, int stopBits = OneStopBit, int fc = NoFlowControl, BOOL bOverlapped = FALSE) throw(); // noexcept
|
|
|
+
|
|
|
+ //////////////////////////////////////////////////////////////////////////
|
|
|
+ //Reading / Writing Methods
|
|
|
+ BOOL Read(void* lpBuffer, DWORD dwNumberOfBytesToRead, DWORD& dwBytesRead) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ dwBytesRead = 0;
|
|
|
+ return ReadFile(m_hComm, lpBuffer, dwNumberOfBytesToRead, &dwBytesRead, NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL Read(void* lpBuffer, DWORD dwNumberOfBytesToRead, OVERLAPPED& overlapped, DWORD* lpNumberOfBytesRead = NULL) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return ReadFile(m_hComm, lpBuffer, dwNumberOfBytesToRead, lpNumberOfBytesRead, &overlapped);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL ReadEx(LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return ReadFileEx(m_hComm, lpBuffer, dwNumberOfBytesToRead, lpOverlapped, lpCompletionRoutine);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL Write(const void* lpBuffer, DWORD dwNumberOfBytesToWrite, DWORD& dwBytesWritten) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ dwBytesWritten = 0;
|
|
|
+ return WriteFile(m_hComm, lpBuffer, dwNumberOfBytesToWrite, &dwBytesWritten, NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL Write(const void* lpBuffer, DWORD dwNumberOfBytesToWrite, OVERLAPPED& overlapped, DWORD* lpNumberOfBytesWritten = NULL) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return WriteFile(m_hComm, lpBuffer, dwNumberOfBytesToWrite, lpNumberOfBytesWritten, &overlapped);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL WriteEx(LPCVOID lpBuffer, DWORD dwNumberOfBytesToWrite, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return WriteFileEx(m_hComm, lpBuffer, dwNumberOfBytesToWrite, lpOverlapped, lpCompletionRoutine);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL TransmitChar(char cChar) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return TransmitCommChar(m_hComm, cChar);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL GetOverlappedResult(OVERLAPPED& overlapped, DWORD& dwBytesTransferred, BOOL bWait) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return ::GetOverlappedResult(m_hComm, &overlapped, &dwBytesTransferred, bWait);
|
|
|
+ }
|
|
|
+
|
|
|
+ __if_exists(::GetOverlappedResultEx)
|
|
|
+ {
|
|
|
+ BOOL GetOverlappedResultEx(OVERLAPPED& overlapped, DWORD& dwBytesTransferred, DWORD dwMilliseconds, _In_ BOOL bAlertable) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return ::GetOverlappedResultEx(m_hComm, &overlapped, &dwBytesTransferred, dwMilliseconds, bAlertable);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL CancelIo() throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return ::CancelIo(m_hComm);
|
|
|
+ }
|
|
|
+
|
|
|
+ __if_exists(::CancelIoEx)
|
|
|
+ {
|
|
|
+ BOOL CancelIoEx(LPOVERLAPPED lpOverlapped = NULL) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+
|
|
|
+ return ::CancelIoEx(m_hComm, lpOverlapped);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL BytesWaiting(DWORD& dwBytesWaiting) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ //Check to see how many characters are unread
|
|
|
+ dwBytesWaiting = 0;
|
|
|
+ COMSTAT stat;
|
|
|
+ if (!GetStatus(stat))
|
|
|
+ return FALSE;
|
|
|
+ dwBytesWaiting = stat.cbInQue;
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ //Configuration Methods
|
|
|
+ BOOL GetConfig(COMMCONFIG& config) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+
|
|
|
+ DWORD dwSize = sizeof(COMMCONFIG);
|
|
|
+ return GetCommConfig(m_hComm, &config, &dwSize);
|
|
|
+ }
|
|
|
+
|
|
|
+ static BOOL GetDefaultConfig(int nPort, COMMCONFIG& config)
|
|
|
+ {
|
|
|
+ CString sPort;
|
|
|
+ sPort.Format(_T("COM%d"), nPort);
|
|
|
+ //Delegate to the other version of the method
|
|
|
+ return GetDefaultConfig(sPort, config);
|
|
|
+ }
|
|
|
+
|
|
|
+ static BOOL GetDefaultConfig(LPCTSTR pszPort, COMMCONFIG& config) throw()
|
|
|
+ {
|
|
|
+ DWORD dwSize = sizeof(COMMCONFIG);
|
|
|
+ return GetDefaultCommConfig(pszPort, &config, &dwSize);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL SetConfig(COMMCONFIG& config) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ const DWORD dwSize = sizeof(COMMCONFIG);
|
|
|
+ return SetCommConfig(m_hComm, &config, dwSize);
|
|
|
+ }
|
|
|
+
|
|
|
+ static BOOL SetDefaultConfig(int nPort, COMMCONFIG& config)
|
|
|
+ {
|
|
|
+ CString sPort;
|
|
|
+ sPort.Format(_T("COM%d"), nPort);
|
|
|
+ //Delegate to the other version of the method
|
|
|
+ return SetDefaultConfig(sPort, config);
|
|
|
+ }
|
|
|
+
|
|
|
+ static BOOL SetDefaultConfig(LPCTSTR pszPort, COMMCONFIG& config) throw()
|
|
|
+ {
|
|
|
+ const DWORD dwSize = sizeof(COMMCONFIG);
|
|
|
+ return SetDefaultCommConfig(pszPort, &config, dwSize);
|
|
|
+ }
|
|
|
+
|
|
|
+ //Misc RS232 Methods
|
|
|
+ BOOL ClearBreak() throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return ClearCommBreak(m_hComm);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL SetBreak() throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return SetCommBreak(m_hComm);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL ClearError(DWORD& dwErrors) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return ClearCommError(m_hComm, &dwErrors, NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL GetStatus(COMSTAT& stat) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ DWORD dwErrors = 0;
|
|
|
+ return ClearCommError(m_hComm, &dwErrors, &stat);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL GetState(DCB& dcb) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return GetCommState(m_hComm, &dcb);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL SetState(DCB& dcb) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return SetCommState(m_hComm, &dcb);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL Escape(DWORD dwFunc) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return EscapeCommFunction(m_hComm, dwFunc);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL ClearDTR() throw()
|
|
|
+ {
|
|
|
+ return Escape(CLRDTR);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL ClearRTS() throw()
|
|
|
+ {
|
|
|
+ return Escape(CLRRTS);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL SetDTR() throw()
|
|
|
+ {
|
|
|
+ return Escape(SETDTR);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL SetRTS() throw()
|
|
|
+ {
|
|
|
+ return Escape(SETRTS);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL SetXOFF() throw()
|
|
|
+ {
|
|
|
+ return Escape(SETXOFF);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL SetXON() throw()
|
|
|
+ {
|
|
|
+ return Escape(SETXON);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL GetProperties(COMMPROP& properties) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return GetCommProperties(m_hComm, &properties);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL GetModemStatus(DWORD& dwModemStatus) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return GetCommModemStatus(m_hComm, &dwModemStatus);
|
|
|
+ }
|
|
|
+
|
|
|
+ //Timeouts
|
|
|
+ BOOL SetTimeouts(COMMTIMEOUTS& timeouts) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return SetCommTimeouts(m_hComm, &timeouts);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL GetTimeouts(COMMTIMEOUTS& timeouts) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return GetCommTimeouts(m_hComm, &timeouts);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL Set0Timeout() throw()
|
|
|
+ {
|
|
|
+ COMMTIMEOUTS Timeouts;
|
|
|
+ memset(&Timeouts, 0, sizeof(Timeouts));
|
|
|
+ Timeouts.ReadIntervalTimeout = MAXDWORD;
|
|
|
+ return SetTimeouts(Timeouts);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL Set0WriteTimeout() throw()
|
|
|
+ {
|
|
|
+ COMMTIMEOUTS Timeouts;
|
|
|
+ GetTimeouts(Timeouts);
|
|
|
+ Timeouts.WriteTotalTimeoutMultiplier = 0;
|
|
|
+ Timeouts.WriteTotalTimeoutConstant = 0;
|
|
|
+ return SetTimeouts(Timeouts);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL Set0ReadTimeout() throw()
|
|
|
+ {
|
|
|
+ COMMTIMEOUTS Timeouts;
|
|
|
+ GetTimeouts(Timeouts);
|
|
|
+ Timeouts.ReadIntervalTimeout = MAXDWORD;
|
|
|
+ Timeouts.ReadTotalTimeoutMultiplier = 0;
|
|
|
+ Timeouts.ReadTotalTimeoutConstant = 0;
|
|
|
+ return SetTimeouts(Timeouts);
|
|
|
+ }
|
|
|
+
|
|
|
+ //Event Methods
|
|
|
+ BOOL SetMask(DWORD dwMask) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return SetCommMask(m_hComm, dwMask);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL GetMask(DWORD& dwMask) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return GetCommMask(m_hComm, &dwMask);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL WaitEvent(DWORD& dwMask) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return WaitCommEvent(m_hComm, &dwMask, NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL WaitEvent(DWORD& dwMask, OVERLAPPED& overlapped) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ ATLASSERT(overlapped.hEvent != NULL);
|
|
|
+
|
|
|
+ return WaitCommEvent(m_hComm, &dwMask, &overlapped);
|
|
|
+ }
|
|
|
+
|
|
|
+ //Queue Methods
|
|
|
+ BOOL Flush() throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return FlushFileBuffers(m_hComm);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL Purge(DWORD dwFlags) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return PurgeComm(m_hComm, dwFlags);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL TerminateOutstandingWrites() throw()
|
|
|
+ {
|
|
|
+ return Purge(PURGE_TXABORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL TerminateOutstandingReads() throw()
|
|
|
+ {
|
|
|
+ return Purge(PURGE_RXABORT);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL ClearWriteBuffer() throw()
|
|
|
+ {
|
|
|
+ return Purge(PURGE_TXCLEAR);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL ClearReadBuffer() throw()
|
|
|
+ {
|
|
|
+ return Purge(PURGE_RXCLEAR);
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL Setup(DWORD dwInQueue, DWORD dwOutQueue) throw()
|
|
|
+ {
|
|
|
+ ATLASSERT(IsOpen());
|
|
|
+ return SetupComm(m_hComm, dwInQueue, dwOutQueue);
|
|
|
+ }
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+#endif // __ASYN_SERIAL__
|