串口通信模块5:串口操作自定义类(2)
生活随笔
收集整理的這篇文章主要介紹了
串口通信模块5:串口操作自定义类(2)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1.ProcessErrorMessage()函數(shù)的實(shí)現(xiàn):
ProcessErrorMessage()函數(shù)負(fù)責(zé)處理并提示錯(cuò)誤信息,其實(shí)現(xiàn)過(guò)程如下: void CMySerial::ProcessErrorMessage(char* ErrorText) {char* Temp = new char[200];LPVOID lpMsgBuf; //保存錯(cuò)誤信息的指針//將GetLastError()得到的錯(cuò)誤信息轉(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); //整合完整的錯(cuò)誤信息MessageBox(NULL, (LPCWSTR)Temp, (LPTSTR)"Application Error", MB_ICONSTOP); //提示錯(cuò)誤信息LocalFree(lpMsgBuf); //釋放資源delete[] Temp; }設(shè)計(jì)思想: 首先,調(diào)用FormatMessage()函數(shù),將GetLastError()函數(shù)返回的錯(cuò)誤號(hào)轉(zhuǎn)化成字符串信息。然后,將剛剛轉(zhuǎn)化的字符串信息與錯(cuò)誤發(fā)生的位置,整合成一個(gè)完整的錯(cuò)誤信息字符串,并保存到Temp指向的空間中。最后,調(diào)用MessageBox()函數(shù),將整合后的信息以消息框的形式彈出給用戶(hù)。 FormatMessage()函數(shù)原型如下: /* DWORD FormatMessageA(DWORD dwFlags, //錯(cuò)誤信息類(lèi)型標(biāo)志LPCVOID lpSource, //指定本地信息定義,其依賴(lài)于第一個(gè)參數(shù)的設(shè)置DWORD dwMessageId, //指定被請(qǐng)求消息標(biāo)識(shí)DWORD dwLanguageId, //指定被請(qǐng)求的消息語(yǔ)言標(biāo)示LPSTR lpBuffer, //指向一個(gè)格式化的消息緩沖區(qū)DWORD nSize, //指定輸出緩沖區(qū)的大小va_list *Arguments //指向在格式化消息中被用來(lái)插入數(shù)值的一個(gè)32位數(shù)值的數(shù)組); */2.串口線(xiàn)程函數(shù)的實(shí)現(xiàn)
串口線(xiàn)程處理函數(shù)CommThread()實(shí)現(xiàn)監(jiān)控差UN扣時(shí)間愛(ài)你的功能,根據(jù)串口事件進(jìn)行相應(yīng)的實(shí)現(xiàn),實(shí)現(xiàn)如下: UINT CMySerial::CommTread(LPVOID pParam) {CMySerial* port = (CMySerial*)pParam; //串口類(lèi)型的指針//串口線(xiàn)程活動(dòng)標(biāo)識(shí)port->m_bThreadAlive = TRUE;//串口信息變量DWORD BytesTransferred = 0;DWORD Event = 0;DWORD COommEvent = 0;DWORD dwError = 0;COMSTAT comstat;//強(qiáng)制關(guān)閉串口if (port->m_hComm){//清空串口緩存PurgeComm(port->m_hComm, PURGE_RXABORT | PURGE_TXABORT | PURGE_RXCLEAR | PURGE_TXCLEAR);}//線(xiàn)程的循環(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: //錯(cuò)誤處理{port->ProcessErrorMessage("WaitCommEvent()");break;}}}else{//清空串口錯(cuò)誤BOOL bResult = ClearCommError(port->m_hComm, &dwError, &comstat);if (comstat.cbInQue == 0)continue;}//獲取串口事件并進(jìn)行相應(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: //寫(xiě)串口WriteChar(port);break;}}return 0; }設(shè)計(jì)思想: 1.獲取保存串口類(lèi)的指針;并將串口線(xiàn)程活動(dòng)標(biāo)識(shí)設(shè)置為真。 2.判斷串口是否已經(jīng)打開(kāi)?如果是,那么清空串口緩沖。 3.設(shè)計(jì)串口線(xiàn)程主循環(huán)體:首先,等待串口的異步通信事件,如果等待失敗調(diào)用相應(yīng)處理函數(shù);否則獲取串口中尚未讀取的字節(jié)數(shù)。然后,我們需要對(duì)獲取的字節(jié)數(shù)進(jìn)行判斷是否為空?如果為空,跳出本次循環(huán);最后,等待串口的3個(gè)事件,并判斷接收到的串口事件類(lèi)型。包括:關(guān)閉串口事件;處理讀串口事件;處理寫(xiě)串口事件。這里需要強(qiáng)調(diào)WaitCommEvent()函數(shù),該函數(shù)是指為一個(gè)特指的通信設(shè)備等待一個(gè)事件發(fā)生,該函數(shù)所監(jiān)控的事件是與該設(shè)備句柄相關(guān)聯(lián)的一系列事件。
/* BOOL WINAPI WaitCommEvent(HANDLE hFile, //指向通信設(shè)備的一個(gè)句柄LPDWORD lpEvtMask, //一個(gè)指向DWORD的指針LPOVERLAPPED lpOverlapped //指向OVERLAPPED結(jié)構(gòu)體的指針); */參數(shù)lpOverlapped是指向OVERLAPPED結(jié)構(gòu)體的一個(gè)指針。如果hFile采用異步方式打開(kāi),在CreateFile()函數(shù)中,該參數(shù)設(shè)置為FILE_FLAG_OVERLAPPED。該參數(shù)不能指向一個(gè)空的OVERLAPPED結(jié)構(gòu)體。如果hfile是采用異步方式打開(kāi)的,而lpOverlapped指向了一個(gè)空的結(jié)構(gòu)體,那么函數(shù)就會(huì)發(fā)出錯(cuò)誤報(bào)告,等到的操作已經(jīng)完成(而此時(shí)等待的操作可能還沒(méi)有完成)。
3.串口進(jìn)程監(jiān)控函數(shù)的實(shí)現(xiàn)
這里采用函數(shù)StartMonitoring()、函數(shù)RestartMonitoring()、函數(shù)StopMonitoring()分別監(jiān)控串口進(jìn)程的開(kāi)始、重啟和掛起。 //啟動(dòng)串口線(xiàn)程 BOOL CMySerial::StartMonitoring() {if (!(m_Thread = AfxBeginThread(CommTread, this)))return FALSE;TRACE(" Thread started\n ");return TRUE; } //重啟串口進(jìn)程 BOOL CMySerial::RestarMonitoring() {TRACE(" Thread resumed\n ");m_Thread->ResumeThread();return TRUE; } //掛起串口線(xiàn)程 BOOL CMySerial::StopMonitoring() {TRACE(" Thread suspended\n ");m_Thread->SuspendThread();return TRUE; }設(shè)計(jì)思想:這3個(gè)函數(shù)實(shí)現(xiàn)起來(lái)是非常輕松的,分別調(diào)用了AfxBginThread()、ResumeThread()和SuspendThread()函數(shù)來(lái)實(shí)現(xiàn)串口進(jìn)程的開(kāi)啟、重啟以及掛起功能。
4.串口關(guān)閉函數(shù)的實(shí)現(xiàn)
關(guān)閉串口函數(shù)直接調(diào)用SetEvent()函數(shù)就可以實(shí)現(xiàn),具體是設(shè)置關(guān)閉串口事件的狀態(tài)為標(biāo)記。 //串口關(guān)閉 void CMySerial::ClosePort() {SetEvent(m_hShutdownEvent); }總結(jié)
以上是生活随笔為你收集整理的串口通信模块5:串口操作自定义类(2)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 新浪uc2010官方下载
- 下一篇: 超可爱桌面电子宠物下载