日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

串口通信模块5:串口操作自定义类(2)

發(fā)布時間:2025/3/15 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 串口通信模块5:串口操作自定义类(2) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.ProcessErrorMessage()函數(shù)的實現(xiàn):

ProcessErrorMessage()函數(shù)負責(zé)處理并提示錯誤信息,其實現(xiàn)過程如下: void CMySerial::ProcessErrorMessage(char* ErrorText) {char* Temp = new char[200];LPVOID lpMsgBuf; //保存錯誤信息的指針//將GetLastError()得到的錯誤信息轉(zhuǎn)化成字符串信息FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR)&lpMsgBuf,0,NULL);sprintf(Temp, "WARNING: %s Failed with the following error:\n %s \nPort: %d\n",(char*)ErrorText,lpMsgBuf,m_nPortNr); //整合完整的錯誤信息MessageBox(NULL, (LPCWSTR)Temp, (LPTSTR)"Application Error", MB_ICONSTOP); //提示錯誤信息LocalFree(lpMsgBuf); //釋放資源delete[] Temp; }設(shè)計思想: 首先,調(diào)用FormatMessage()函數(shù),將GetLastError()函數(shù)返回的錯誤號轉(zhuǎn)化成字符串信息。然后,將剛剛轉(zhuǎn)化的字符串信息與錯誤發(fā)生的位置,整合成一個完整的錯誤信息字符串,并保存到Temp指向的空間中。最后,調(diào)用MessageBox()函數(shù),將整合后的信息以消息框的形式彈出給用戶。 FormatMessage()函數(shù)原型如下: /* DWORD FormatMessageA(DWORD dwFlags, //錯誤信息類型標(biāo)志LPCVOID lpSource, //指定本地信息定義,其依賴于第一個參數(shù)的設(shè)置DWORD dwMessageId, //指定被請求消息標(biāo)識DWORD dwLanguageId, //指定被請求的消息語言標(biāo)示LPSTR lpBuffer, //指向一個格式化的消息緩沖區(qū)DWORD nSize, //指定輸出緩沖區(qū)的大小va_list *Arguments //指向在格式化消息中被用來插入數(shù)值的一個32位數(shù)值的數(shù)組); */

2.串口線程函數(shù)的實現(xiàn)

串口線程處理函數(shù)CommThread()實現(xiàn)監(jiān)控差UN扣時間愛你的功能,根據(jù)串口事件進行相應(yīng)的實現(xiàn),實現(xiàn)如下: UINT CMySerial::CommTread(LPVOID pParam) {CMySerial* port = (CMySerial*)pParam; //串口類型的指針//串口線程活動標(biāo)識port->m_bThreadAlive = TRUE;//串口信息變量DWORD BytesTransferred = 0;DWORD Event = 0;DWORD COommEvent = 0;DWORD dwError = 0;COMSTAT comstat;//強制關(guān)閉串口if (port->m_hComm){//清空串口緩存PurgeComm(port->m_hComm, PURGE_RXABORT | PURGE_TXABORT | PURGE_RXCLEAR | PURGE_TXCLEAR);}//線程的循環(huán)體for (;;){BOOL bResult = WaitCommEvent(port->m_hComm, &Event, &port->m_ov);if (!bResult){//讀取失敗處理switch ( dwError = GetLastError() ){case ERROR_IO_PENDING: break; //讀取串口為空case 87: break;default: //錯誤處理{port->ProcessErrorMessage("WaitCommEvent()");break;}}}else{//清空串口錯誤BOOL bResult = ClearCommError(port->m_hComm, &dwError, &comstat);if (comstat.cbInQue == 0)continue;}//獲取串口事件并進行相應(yīng)處理Event = WaitForMultipleObjects(3, port->m_hEventArray, FALSE, INFINITE);switch (Event){case 0: //關(guān)閉串口CloseHandle(port->m_hComm);port->m_hComm = NULL;port->m_bThreadAlive = FALSE;AfxEndThread(100);break;case 1: //讀串口GetCommMask( port->m_hComm, &CommEvent );if (CommEvent & EV_RXCHAR)ReceiveChar(port, comstat);break;case 2: //寫串口WriteChar(port);break;}}return 0; }設(shè)計思想: 1.獲取保存串口類的指針;并將串口線程活動標(biāo)識設(shè)置為真。 2.判斷串口是否已經(jīng)打開?如果是,那么清空串口緩沖。 3.設(shè)計串口線程主循環(huán)體:首先,等待串口的異步通信事件,如果等待失敗調(diào)用相應(yīng)處理函數(shù);否則獲取串口中尚未讀取的字節(jié)數(shù)。然后,我們需要對獲取的字節(jié)數(shù)進行判斷是否為空?如果為空,跳出本次循環(huán);最后,等待串口的3個事件,并判斷接收到的串口事件類型。包括:關(guān)閉串口事件;處理讀串口事件;處理寫串口事件。
這里需要強調(diào)WaitCommEvent()函數(shù),該函數(shù)是指為一個特指的通信設(shè)備等待一個事件發(fā)生,該函數(shù)所監(jiān)控的事件是與該設(shè)備句柄相關(guān)聯(lián)的一系列事件

/* BOOL WINAPI WaitCommEvent(HANDLE hFile, //指向通信設(shè)備的一個句柄LPDWORD lpEvtMask, //一個指向DWORD的指針LPOVERLAPPED lpOverlapped //指向OVERLAPPED結(jié)構(gòu)體的指針); */參數(shù)lpOverlapped是指向OVERLAPPED結(jié)構(gòu)體的一個指針。如果hFile采用異步方式打開,在CreateFile()函數(shù)中,該參數(shù)設(shè)置為FILE_FLAG_OVERLAPPED。該參數(shù)不能指向一個空的OVERLAPPED結(jié)構(gòu)體。如果hfile是采用異步方式打開的,而lpOverlapped指向了一個空的結(jié)構(gòu)體,那么函數(shù)就會發(fā)出錯誤報告,等到的操作已經(jīng)完成(而此時等待的操作可能還沒有完成)。

3.串口進程監(jiān)控函數(shù)的實現(xiàn)

這里采用函數(shù)StartMonitoring()、函數(shù)RestartMonitoring()、函數(shù)StopMonitoring()分別監(jiān)控串口進程的開始、重啟和掛起。 //啟動串口線程 BOOL CMySerial::StartMonitoring() {if (!(m_Thread = AfxBeginThread(CommTread, this)))return FALSE;TRACE(" Thread started\n ");return TRUE; } //重啟串口進程 BOOL CMySerial::RestarMonitoring() {TRACE(" Thread resumed\n ");m_Thread->ResumeThread();return TRUE; } //掛起串口線程 BOOL CMySerial::StopMonitoring() {TRACE(" Thread suspended\n ");m_Thread->SuspendThread();return TRUE; }設(shè)計思想:
這3個函數(shù)實現(xiàn)起來是非常輕松的,分別調(diào)用了AfxBginThread()、ResumeThread()和SuspendThread()函數(shù)來實現(xiàn)串口進程的開啟、重啟以及掛起功能。

4.串口關(guān)閉函數(shù)的實現(xiàn)

關(guān)閉串口函數(shù)直接調(diào)用SetEvent()函數(shù)就可以實現(xiàn),具體是設(shè)置關(guān)閉串口事件的狀態(tài)為標(biāo)記。 //串口關(guān)閉 void CMySerial::ClosePort() {SetEvent(m_hShutdownEvent); }

總結(jié)

以上是生活随笔為你收集整理的串口通信模块5:串口操作自定义类(2)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。