| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- /************************************************************************/
- /* Copyright (C), 2016-2020, [Home], 保留所有权利;
- /* 模 块 名:异步串口模块;
- /* 描 述:;
- /*
- /* 版 本:[V];
- /* 作 者:[Home];
- /* 日 期:[12/20/2017];
- /*
- /*
- /* 注 意:;
- /*
- /* 修改记录:[Home];
- /* 修改日期:;
- /* 修改版本:;
- /* 修改内容:;
- /************************************************************************/
- #ifndef __ASYN_SERIAL__
- #define __ASYN_SERIAL__
- #pragma once
- class CAsynSerial
- {
- 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;
- OVERLAPPED m_ovWait;
- OVERLAPPED m_ovRead;
- OVERLAPPED m_ovWrite;
- public:
- CAsynSerial(void);
- virtual ~CAsynSerial(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);
- }
- // 必须先启用:SetMask(EV_ERR | EV_RXCHAR),才能使用WaitCommEvent;
- BOOL ReadAsyn(void* lpBuffer, DWORD dwNumberOfBytesToRead, DWORD &dwNumberOfBytesRead) throw()
- {
- ATLASSERT(IsOpen());
- COMSTAT cs = { 0 };
- DWORD dwErrors = 0;
- DWORD dwEvtMask = 0;
- DWORD dwNumberOfBytesTransferred;
- m_ovWait.Offset = 0;
- m_ovRead.Offset = 0;
- BOOL Status = WaitCommEvent(m_hComm, &dwEvtMask, &m_ovWait);
- // WaitCommEvent也是一个异步命令,所以需要等待
- if (!Status && GetLastError() == ERROR_IO_PENDING)
- {
- // 如果缓存中无数据线程会停在此,如果hCom关闭会立即返回False
- Status = ::GetOverlappedResult(m_hComm, &m_ovWait, &dwNumberOfBytesTransferred, TRUE);
- }
-
- ClearCommError(m_hComm, &dwErrors, &cs);
- if (Status && dwEvtMask & EV_RXCHAR && cs.cbInQue > 0) //有数据
- {
- dwNumberOfBytesTransferred = 0;
- memset(lpBuffer, 0, dwNumberOfBytesToRead);
- // 数据已经到达缓存区,ReadFile不会当成异步命令,而是立即读取并返回True
- Status = ReadFile(m_hComm, lpBuffer, dwNumberOfBytesToRead, &dwNumberOfBytesRead, &m_ovRead);
- PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_RXABORT);
- }
- return Status;
- }
- 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);
- }
- // SetMask(EV_ERR | EV_RXCHAR);
- BOOL WriteAsyn(const void* lpBuffer, DWORD dwNumberOfBytesToWrite, DWORD &dwNumberOfBytesWritten) throw()
- {
- ATLASSERT(IsOpen());
- PurgeComm(m_hComm, PURGE_TXCLEAR|PURGE_TXABORT);
- m_ovWait.Offset = 0;
- BOOL bRet = WriteFile(m_hComm, lpBuffer, dwNumberOfBytesToWrite, &dwNumberOfBytesWritten, &m_ovWrite);
- if (!bRet && GetLastError() == ERROR_IO_PENDING)//后台读取
- {
- //等待数据写入完成
- if (FALSE == ::GetOverlappedResult(m_hComm, &m_ovWrite, &dwNumberOfBytesWritten, TRUE))
- {
- return FALSE;
- }
- }
- return bRet;
- }
- 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__
|