vc串口编程.pdf
《vc串口编程.pdf》由会员分享,可在线阅读,更多相关《vc串口编程.pdf(18页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、3.多线程串口类使用多线程串口通信更方便的途径是编写一个多线程的串口类,例如Remon Spekreijse编写了一个CSerialPort串口类。仔细分析这个类的源代码,将十分有助于我们对先前所学多线程及同步知识的理解。3.1 类的定义#ifndef _SERIALPORT_H_#define _SERIALPORT_H_#define WM_COMM_BREAK_DETECTED WM_USER+1/A break was detected on input.#define WM_COMM_CTS_DETECTED WM_USER+2/The CTS(clear-to-send)signa
2、l changed state.#define WM_COMM_DSR_DETECTED WM_USER+3/The DSR(data-set-ready)signal changed state.#define WM_COMM_ERR_DETECTED WM_USER+4/A line-status error occurred.Line-status errors are CE_FRAME,CE_OVERRUN,and CE_RXPARITY.#define WM_COMM_RING_DETECTED WM_USER+5/A ring indicator was detected.#def
3、ine WM_COMM_RLSD_DETECTED WM_USER+6/The RLSD(receive-line-signal-detect)signal changed state.#define WM_COMM_RXCHAR WM_USER+7/A character was received and placed in the input buffer.#define WM_COMM_RXFLAG_DETECTED WM_USER+8/The event character was received and placed in the input buffer.#define WM_C
4、OMM_TXEMPTY_DETECTED WM_USER+9/The last character in the output buffer was sent.class CSerialPort public:/contruction and destruction CSerialPort();virtual CSerialPort();/port initialisation BOOL InitPort(CWnd*pPortOwner,UINT portnr=1,UINT baud=19200,char parity=N,UINT databits=8,UINT stopsbits=1,DW
5、ORD dwCommEvents=EV_RXCHAR|EV_CTS,UINT nBufferSize=512);/start/stop comm watching BOOL StartMonitoring();BOOL RestartMonitoring();BOOL StopMonitoring();DWORD GetWriteBufferSize();DWORD GetCommEvents();DCB GetDCB();void WriteToPort(char*string);protected:/protected memberfunctions void ProcessErrorMe
6、ssage(char*ErrorText);static UINT CommThread(LPVOID pParam);static void ReceiveChar(CSerialPort*port,COMSTAT comstat);static void WriteChar(CSerialPort*port);/thread CWinThread*m_Thread;/synchronisation objects CRITICAL_SECTION m_csCommunicationSync;BOOL m_bThreadAlive;/handles HANDLE m_hShutdownEve
7、nt;HANDLE m_hComm;HANDLE m_hWriteEvent;/Event array./One element is used for each event.There are two event handles for each port./A Write event and a receive character event which is located in the overlapped structure(m_ov.hEvent)./There is a general shutdown when the port is closed.HANDLE m_hEven
8、tArray3;/structures OVERLAPPED m_ov;COMMTIMEOUTS m_CommTimeouts;DCB m_dcb;/owner window CWnd*m_pOwner;/misc UINT m_nPortNr;char*m_szWriteBuffer;DWORD m_dwCommEvents;DWORD m_nWriteBufferSize;#endif _SERIALPORT_H_ 3.2 类的实现3.2.1 构造函数与析构函数进行相关变量的赋初值及内存恢复:CSerialPort:CSerialPort()m_hComm=NULL;/initialize
9、 overlapped structure members to zero m_ov.Offset=0;m_ov.OffsetHigh=0;/create events m_ov.hEvent=NULL;m_hWriteEvent=NULL;m_hShutdownEvent=NULL;m_szWriteBuffer=NULL;m_bThreadAlive=FALSE;/Delete dynamic memory/CSerialPort:CSerialPort()do SetEvent(m_hShutdownEvent);while(m_bThreadAlive);TRACE(Thread en
10、dedn);delete m_szWriteBuffer;3.2.2 核心函数:初始化串口在初始化串口函数中,将打开串口,设置相关参数,并创建串口相关的用户控制事件,初始化临界区(Critical Section),以成队的 EnterCriticalSection()、LeaveCriticalSection()函数进行资源的排它性访问:BOOL CSerialPort:InitPort(CWnd*pPortOwner,/the owner(CWnd)of the port(receives message)UINT portnr,/portnumber(1.4)UINT baud,/bau
11、drate char parity,/parity UINT databits,/databits UINT stopbits,/stopbits DWORD dwCommEvents,/EV_RXCHAR,EV_CTS etc UINT writebuffersize)/size to the writebuffer assert(portnr 0&portnr m_bThreadAlive=TRUE;/Misc.variables DWORD BytesTransfered=0;DWORD Event=0;DWORD CommEvent=0;DWORD dwError=0;COMSTAT
12、comstat;BOOL bResult=TRUE;/Clear comm buffers at startup if(port-m_hComm)/check if the port is opened PurgeComm(port-m_hComm,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);/begin forever loop.This loop will run as long as the thread is alive.for(;)/Make a call to WaitCommEvent().This call
13、will return immediatly/because our port was created as an async port(FILE_FLAG_OVERLAPPED/and an m_OverlappedStructerlapped structure specified).This call will cause the/m_OverlappedStructerlapped element m_OverlappedStruct.hEvent,which is part of the m_hEventArray to/be placed in a non-signeled sta
14、te if there are no bytes available to be read,/or to a signeled state if there are bytes available.If this event handle/is set to the non-signeled state,it will be set to signeled when a/character arrives at the port./we do this for each port!bResult=WaitCommEvent(port-m_hComm,&Event,&port-m_ov);if(
15、!bResult)/If WaitCommEvent()returns FALSE,process the last error to determin/the reason.switch(dwError=GetLastError()case ERROR_IO_PENDING:/This is a normal return value if there are no bytes/to read at the port./Do nothing and continue break;case 87:/Under Windows NT,this value is returned for some
16、 reason./I have not investigated why,but it is also a valid reply/Also do nothing and continue.break;default:/All other error codes indicate a serious error has/occured.Process this error.port-ProcessErrorMessage(WaitCommEvent();break;else /If WaitCommEvent()returns TRUE,check to be sure there are/a
17、ctually bytes in the buffer to read./If you are reading more than one byte at a time from the buffer/(which this program does not do)you will have the situation occur/where the first byte to arrive will cause the WaitForMultipleObjects()/function to stop waiting.The WaitForMultipleObjects()function/
18、resets the event handle in m_OverlappedStruct.hEvent to the non-signelead state/as it returns./If in the time between the reset of this event and the call to/ReadFile()more bytes arrive,the m_OverlappedStruct.hEvent handle will be set again/to the signeled state.When the call to ReadFile()occurs,it
19、will/read all of the bytes from the buffer,and the program will/loop back around to WaitCommEvent()./At this point you will be in the situation where m_OverlappedStruct.hEvent is set,/but there are no bytes available to read.If you proceed and call/ReadFile(),it will return immediatly due to the asy
20、nc port setup,but/GetOverlappedResults()will not return until the next character arrives./It is not desirable for the GetOverlappedResults()function to be in/this state.The thread shutdown event(event 0)and the WriteFile()/event(Event2)will not work if the thread is blocked by GetOverlappedResults()
21、./The solution to this is to check the buffer with a call to ClearCommError()./This call will reset the event handle,and if there are no bytes to read/we can loop back through WaitCommEvent()again,then proceed./If there are really bytes to read,do nothing and proceed.bResult=ClearCommError(port-m_hC
22、omm,&dwError,&comstat);if(comstat.cbInQue=0)continue;/end if bResult/Main wait function.This function will normally block the thread/until one of nine events occur that require action.Event=WaitForMultipleObjects(3,port-m_hEventArray,FALSE,INFINITE);switch(Event)case 0:/Shutdown event.This is event
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- vc 串口 编程
限制150内