串口通信模块4:串口操作自定义类(1)
生活随笔
收集整理的這篇文章主要介紹了
串口通信模块4:串口操作自定义类(1)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
為了以后使用方便,將串口的屬性及操作封裝成一個類。對串口的操作可以直接通過調用這個串口類提供的幾個函數(shù)接口即可。
1.CMySerial類的定義:MySerial.h
#pragma once #include <Windows.h> #include <afxwin.h> class CMySerial { public:CMySerial();virtual ~CMySerial(); public:bool OpenSerial(CWnd* pParent, UINT portnr, UINT baud, CHAR parity,UINT databits, UINT stopbits, DWORD dwCommEvents, UINT writebuffersize); //Open the Serialvoid ClosePort();// the control function of monitoring threadBOOL StartMonitoring();BOOL RestarMonitoring();BOOL StopMonitoring();DWORD GetWriteBufferSize();DWORD GetCommEvents();DCB GetDCB();// Attain & Save the Data that will transfor and trigle the transfor event.void WriteToPort(char* string);void WriteToPort(char* string, int n);void WriteToPort(LPCSTR string);void WriteToPort(LPCSTR string, int n);protected:void ProcessErrorMessage(char* ErrorText); //deal error eventstatic UINT CommTread(LPVOID pParam); // function to deal serial threadstatic void ReceiveChar(CMySerial* port, //read serial dataCOMSTAT comstat);static void WriteChar(CMySerial* port); //write data to serialpublic:HANDLE m_hComm; //handle to operate serialint m_nWriteSize; //send dataprotected:CWinThread* m_Thread; // a pointer to threadCRITICAL_SECTION m_csCommunicationSync; // critial臨界 resourseBOOL m_bThreadAlive; // the alive state of serial //serial eventHANDLE m_hWriteEvent; //write eventHANDLE m_hShutdownEvent; //shut down eventHANDLE m_hEventArray[3]; //event arrayDWORD m_dwCommEvents; //mask code of serial eventOVERLAPPED m_ov; //set asynchonous I/O operationCOMMTIMEOUTS m_CommTimeouts; //structure of serial overtimeDCB m_dcb; //DCB structure in serial communicationCWnd* m_pParent; //include window pointer of serial operationUINT m_nPortNr; //port numberchar* m_szWriteBuffer; //area of writedata bufferDWORD m_nWriteBufferSize; //size of writedata buffer }; 在這個類中,事件數(shù)組m_hEventArray中的每個數(shù)組元素都對應著一個事件。這個數(shù)組共有三個元素:一個是寫事件,一個是收事件,還有一個是串口關閉事件。
2.CMySerial類的實現(xiàn)及代碼解析:CMySerial.c
構造及解析函數(shù)的實現(xiàn): CMySerial::CMySerial() {m_hComm = NULL; //初始化串口句柄//初始化異步操作成員變量m_ov.Offset = 0;m_ov.OffsetHigh = 0;//創(chuàng)建異步操作的事件成員變量m_ov.hEvent = NULL;//初始化發(fā)送及關閉事件m_hWriteEvent = NULL;m_hShutdownEvent = NULL;//初始化發(fā)送變量m_szWriteBuffer = NULL;m_nWriteBufferSize = 1;m_bThreadAlive = FALSE; //串口監(jiān)控線程處于非激活狀態(tài) } CMySerial::~CMySerial() {do{SetEvent(m_hShutdownEvent);} while ( m_bThreadAlive ); //監(jiān)控線程處于激活狀態(tài)時,關閉串口if (m_hComm != NULL){CloseHandle(m_hComm);m_hComm = NULL; //如果上面串口關閉不成功,繼續(xù)關閉窗口}if (m_hShutdownEvent != NULL)CloseHandle( m_hShutdownEvent ); //關閉串口并關閉事件句柄if (m_ov.hEvent != NULL)CloseHandle( m_ov.hEvent ); //關閉串口異步操作事件句柄if (m_hWriteEvent != NULL )CloseHandle(m_hWriteEvent); //關閉串口寫事件句柄TRACE("Thread ended\n");delete[] m_szWriteBuffer; //釋放發(fā)送緩沖區(qū) } 打開串口:bool CMySerial::OpenSerial(CWnd* pParent, UINT portnr, UINT baud, CHAR parity,UINT databits, UINT stopbits, DWORD dwCommEvents, UINT writebuffersize) {assert(portnr > 0 && portnr < 5);assert(pParent != NULL);if (m_bThreadAlive) //如果串口監(jiān)控程序處于激活態(tài),那我們關閉它{do{SetEvent(m_hShutdownEvent);} while (m_bThreadAlive); TRACE("Thread ended\n");}if (m_ov.hEvent != NULL) //創(chuàng)建串口異步通信事件ResetEvent(m_ov.hEvent);elsem_ov.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );if (m_hWriteEvent != NULL) //創(chuàng)建數(shù)據(jù)發(fā)送事件ResetEvent(m_hWriteEvent);elsem_hWriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL );if (m_hShutdownEvent != NULL) //創(chuàng)建關閉串口事件ResetEvent(m_hShutdownEvent);elsem_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//串口事件設定 及 優(yōu)先級分配m_hEventArray[0] = m_hShutdownEvent; //優(yōu)先級最高m_hEventArray[1] = m_ov.hEvent;m_hEventArray[2] = m_hWriteEvent;//初始化臨界資源InitializeCriticalSection(&m_csCommunicationSync);m_pParent = pParent; //保存串口操作窗口指針if (m_szWriteBuffer != NULL) //為發(fā)送緩存清理空間{delete[] m_szWriteBuffer;}m_szWriteBuffer = new char[writebuffersize]; //發(fā)送字符型的信息m_nPortNr = portnr; //保存串口號m_nWriteBufferSize = writebuffersize; //將要發(fā)送的數(shù)據(jù)m_dwCommEvents = dwCommEvents; //串口事件BOOL bResult = FALSE;char *szPort = new char[50]; //數(shù)據(jù)緩沖區(qū)char *szBaud = new char[50];EnterCriticalSection(&m_csCommunicationSync);//鎖定臨界變量if (m_hComm != NULL) //確保串口處于關閉狀態(tài){CloseHandle(m_hComm);m_hComm = NULL;}sprintf(szPort, "COM%d", portnr); //串口狀態(tài)信息sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d",baud, parity, databits, stopbits);//打開串口m_hComm = CreateFile((LPCWSTR)szPort, //串口號 出現(xiàn)char*與LPCWSTR不兼容 強制轉換GENERIC_READ | //讀模式GENERIC_WRITE, //寫模式0, //必須為零NULL, //安全型屬性結構OPEN_EXISTING, //必須置為此FILE_FLAG_OVERLAPPED,//采用異步的輸入輸出形式NULL); //必須為NULLif (m_hComm == INVALID_HANDLE_VALUE) {//串口打開失敗delete [] szPort;delete [] szBaud;return FALSE;}//設置超時參數(shù)m_CommTimeouts.ReadIntervalTimeout = 1000;m_CommTimeouts.ReadTotalTimeoutConstant = 1000;m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000;m_CommTimeouts.WriteTotalTimeoutConstant = 1000;m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000;if (SetCommTimeouts(m_hComm, &m_CommTimeouts))//設置串口參數(shù){//超時設置if (SetCommMask(m_hComm, dwCommEvents)){//事件設置if (GetCommState(m_hComm, &m_dcb)){ //參數(shù)設置m_dcb.EvtChar = 'q';m_dcb.fRtsControl = RTS_CONTROL_ENABLE;if (BuildCommDCB((LPCWSTR)szBaud, &m_dcb)){if (!SetCommState(m_hComm, &m_dcb))ProcessErrorMessage("SetCommState()");}else //串口參數(shù)設置失敗ProcessErrorMessage("BuildCommDCB()");}else //參數(shù)獲取失敗ProcessErrorMessage("GetCommState()");}else//串口事件設置失敗ProcessErrorMessage("SetCommMask()");}else//串口超時設置失敗ProcessErrorMessage("SetCommTimeouts()"); delete [] szPort; //清空數(shù)據(jù)區(qū)delete [] szBaud;PurgeComm(m_hComm, PURGE_RXABORT | PURGE_TXABORT | PURGE_RXCLEAR | PURGE_TXCLEAR);LeaveCriticalSection(&m_csCommunicationSync);//解鎖臨時變量return TRUE; }
打開串口代碼設計的核心思想為: 1.判斷串口監(jiān)控線程是否處于激活狀態(tài)?如果是,那么需要將它關閉; 2.創(chuàng)建并啟動串口的3個事件; 3.創(chuàng)建的事件句柄保存到事件數(shù)組里; 4.初始化臨界資源;并申請一段數(shù)據(jù)發(fā)送緩存區(qū); 5.保存?zhèn)魅氲膮?shù),并鎖定臨界資源;
6.驗證串口是否已關閉?如果沒有關閉,則要關閉; 7.打開串口,并判斷是否打開串口成功?否則需要我們釋放資源后返回; 8.設置串口通信的超時參數(shù)。 9.將前面準備好的串口的所有屬性設置到串口上,設置失敗后需要調用消息盒子進行失敗處理。 10.釋放資源,清空緩存區(qū),并解鎖臨界資源,使得其它進程以后可以使用這個臨界資源。
總結
以上是生活随笔為你收集整理的串口通信模块4:串口操作自定义类(1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 秋赛牧飞鸽传书
- 下一篇: 美研申请,你应该知道的那些事?