




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、多線程,多接收模式串口類LsComm作者:Liu_sir下載示例源代碼描述:一個串口通訊類 應(yīng)用平臺:Windows 版本: v1.0 主要功能:設(shè)計了一個簡潔易用的多線程串行通訊接口,可以切換查詢和自動接收模式,進行對串口數(shù)據(jù)收發(fā)的類 接觸VC,很不習(xí)慣mscomm等Active控件老讓人去注冊的方式,所以參照Delphi中的SpComm設(shè)計了一個類CComPort,對PJ Naughter 的CSerialPort()進行了2次封裝,主要目的是簡化串口的使用.使其用簡單的代碼就可以完成串口通訊的過程.做了一個Demo程序演示了CComPort的使用,附圖如下: 下面我從如何使用和類的設(shè)計兩
2、個方面說明一下: 一 如何使用: 考慮到使用過程盡可能簡潔,實用,為了滿足不同的使用要求設(shè)計4種接收模式, 前兩種為手動接收方式,后兩種為自動類回調(diào)方式,下面是使用代碼 1.ManualReceiveByQuery 手動查詢接收#include ComPort.h LsComm:CComPort m_ComPort; /LsComm is namespace in c+m_ComPort.Open(2,LsComm:CComPort:AutoReceiveByquery);/ReCeive Com Data: 接收語句DWORD InBufferCount;byte pbuffer2048;I
3、nBufferCount = m_ComPort.GetInBufferCount();if(InBufferCount0) m_ComPort.GetInput(pbuffer,InBufferCount);/Write Com Data: 寫串口數(shù)據(jù)char a10=abcdefg;this-m_ComPort.Output(a,sizeof(a);2.ManualReceiveByConst(異步模式) 手動定常數(shù)接收模式 #include ComPort.h LsComm:CComPort m_ComPort;/LsComm is namespace in c+m_ComPort.Op
4、en(2,LsComm:CComPort:AutoReceiveByConst);/ReCeive Com Data: /接收數(shù)據(jù)DWORD InBufferCount=0;byte pbuffer2048;InBufferCount=this-m_ComPort.GetInput(pbuffer,10,1000);/上面我要在1000毫秒內(nèi)接收10字節(jié)的數(shù)據(jù),IbufferCount返回實際得到的數(shù)據(jù)if(InBufferCount=0)return;CString c;char a4; for(int i=0;iGetDlgItem(IDC_LIST1);for(int i=0;iAddS
5、tring(c);3.AutoReceiveBySignal 自動信號接收模式 #include ComPort.h LsComm:CComPort m_ComPort;/LsComm is namespace in c+m_ComPort.Open(2,LsComm:CComPort:AutoReceiveBySignal ); m_ComPort.SetReceiveFunc(FOnReceiveData)OnReceiveData,this); m_ComPort.SetBreakHandleFunc(OnComBreak); /ReCeive Com Data:接收數(shù)據(jù)函數(shù)in OnR
6、eceiveData(LPVOID pSender,void* pBuf,DWORD InBufferCount) /above/write data the same as the first mode; 4.AutoReceiveByBreak 中斷接收模式#include ComPort.h LsComm:CComPort m_ComPort;/LsComm is namespace in c+m_ComPort.Open(2,LsComm:CComPort:AutoReceiveByBreak ); m_ComPort.SetReceiveFunc(FOnReceiveData)OnR
7、eceiveData,this); /ReCeive Com Data:接收數(shù)據(jù)函數(shù)in OnReceiveData(LPVOID pSender,void* pBuf,DWORD InBufferCount) /above/write data the same as the first mode; 另外說明2點: (1)如果你需要處理中斷事件,你可以在每種模式中設(shè)置中斷接收事件:如下 /定義中斷事件接收函數(shù) void OnComBreak(LPVOID pSender,DWORD dwMask,COMSTAT stat) /deal with the break of com herem_
8、ComPort.SetBreakHandleFunc(OnComBreak); /設(shè)置中斷事件(2)如何處理如,改變波特率,以及其它參數(shù)呢?m_ComPort.GetSerialPort()可以獲得一個CSerialPort類的指針,如何就可以操作各種com屬性了. DCB dcb;this-m_ComPort.GetSerialPort()-GetState(dcb);二.類的設(shè)計與編程1. 類結(jié)構(gòu)為了說明一個大概的類構(gòu)成,我用Rose畫了一下類圖:如下CComPort內(nèi)部聚合了一個CSerialPort的串口類,并與一個CReadComThread線程關(guān)聯(lián),讓其去讀取串口數(shù)據(jù). LsCom
9、m:CComPort m_ComPort;/LsComm is namespace in c+m_ComPort.Open(2,LsComm:CComPort:AutoReceiveBySignal ); m_ComPort.SetReceiveFunc(OnReceiveData,this); m_ComPort.SetBreakHandleFunc(OnComBreak);這些語句是怎么實現(xiàn)串口數(shù)據(jù)的發(fā)送和讀取的呢? 2. 打開過程CComPort:Open() void CComPort:Open(int nPort,ReceiveMode mode, DWORD dwBaud, Par
10、ity parity, BYTE DataBits, StopBits stopbits,FlowControl fc) /1.新建串口this-m_pPort = new CSerialPort();/2.判斷收發(fā)模式if(mode=ReceiveMode:ManualReceiveByQuery) this-m_IsOverlapped = false;else this-m_IsOverlapped = true;this-m_RecvMode = mode; /3.轉(zhuǎn)換參數(shù),打開串口int index;index=parity-CComPort:EvenParity;CSerialPo
11、rt:Parity spParity=(CSerialPort:Parity)(CSerialPort:EvenParity+index);略去 this-m_pPort-Open(nPort,dwBaud,spParity,DataBits,spStopbits,spFC,m_IsOverlapped); this-m_pPort-Setup(4096,4096); this-m_pPort-Purge(PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);/it is important!COMMTIMEOUTS ti
12、meouts;this-m_pPort-GetTimeouts(timeouts);timeouts.ReadIntervalTimeout=100;this-m_pPort-SetTimeouts(timeouts);this-m_CurPortNum = nPort; /創(chuàng)建關(guān)閉事件this-m_hCloseEvent = CreateEvent(NULL,true,false,NULL);ASSERT(this-m_hCloseEvent); /4.創(chuàng)建線程類this-m_pReadThread = new CReadComThread();this-m_pReadThread-Band
13、SerialPort(this); this-m_pReadThread-Create();this-m_pReadThread-Resume(); if(this-IsOverlapped() this-m_hWriteEvent = :CreateEvent(NULL,false,false,NULL);主要做的工作是:新建串口 this-m_pPort = new CSerialPort(); 打開串口 this-m_pPort-Open 創(chuàng)建讀取線程 this-m_pReadThread = new CReadComThread(); 設(shè)立線程類與CComPort的關(guān)聯(lián)關(guān)系this-m
14、_pReadThread-BandSerialPort(this); void CReadComThread:BandSerialPort(CComPort* pPort)ASSERT(pPort);this-m_pPort = pPort;/創(chuàng)建異步讀取事件 if(this-m_pPort-IsOverlapped() this-m_ReadOverlapped.hEvent =:CreateEvent(NULL,false,false,NULL); ASSERT(this-m_ReadOverlapped.hEvent); this-m_BreakOverlapped.hEvent = :
15、CreateEvent(NULL,false,false,NULL); ASSERT(this-m_BreakOverlapped.hEvent); 模式主要在線程執(zhí)行的過程中發(fā)揮作用3.串口的發(fā)送數(shù)據(jù)過程 DWORD CComPort:Output(void* pBuf,DWORD Count) DWORD dwWriteBytes=0;if(this-IsOverlapped()/異步模式this-m_pPort-Write(pBuf,Count,this-m_WriteOverlapped);if(WaitForSingleObject(this-m_WriteOverlapped.hE
16、vent,INFINITE)=WAIT_OBJECT_0) this-m_pPort-GetOverlappedResult(this-m_WriteOverlapped,dwWriteBytes,false);elsedwWriteBytes= this-m_pPort-Write(pBuf,Count); return dwWriteBytes;再看this-m_pPort-Write(pBuf,Count);實際上是:調(diào)用DWORD CSerialPort:Write(const void* lpBuf, DWORD dwCount) ASSERT(IsOpen(); ASSERT(!m
17、_bOverlapped); DWORD dwBytesWritten = 0; if (!WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, NULL) TRACE(_T(Failed in call to WriteFilen); AfxThrowSerialException(); return dwBytesWritten;或者是BOOL CSerialPort:Write(const void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped, DWORD* pBytesWritten) 異
18、步寫串口的過程 4.串口的讀取過程分兩種:查詢讀取和線程自動讀取 (1) 查詢讀取 DWORD CComPort:GetInput(void* pBuf,DWORD Count,DWORD dwMilliseconds) /不能在自動模式下getinputif(this-GetReceiveMode()=CComPort:AutoReceiveByBreak|this-GetReceiveMode()=CComPort:AutoReceiveBySignal):AfxMessageBox(Cant use GetInput methord in this mode!);return 0;if(
19、this-IsOverlapped() ASSERT(this-m_pReadThread); DWORD dwBytes = this-m_pReadThread-ReadInput(pBuf,Count,dwMilliseconds); this-m_pPort-TerminateOutstandingReads(); return dwBytes;else return this-m_pPort-Read(pBuf,Count); 主要是調(diào)用m_pPort-Read(pBuf,Count);然后調(diào)用API函數(shù)ReadFile(2) 線程等待處理主要過程:在線程CreadComThread
20、的Execute中void CReadComThread:Execute()if(this-m_pPort-GetReceiveMode()=CComPort:ManualReceiveByQuery) this-ExecuteByManualQueryRecvMode(); else if(this-m_pPort-GetReceiveMode()=CComPort:ManualReceiveByConst) this-ExecuteByManualConstRecvMode(); else if(this-m_pPort-GetReceiveMode()=CComPort:AutoRece
21、iveBySignal) this-ExecuteByAutoSignalRecvMode(); else/中斷模式 this-ExecuteByAutoBreakRecvMode(); 主要是選擇模式然后執(zhí)行: 下面看看this-ExecuteByAutoSignalRecvMode(); void CReadComThread:ExecuteByAutoSignalRecvMode()DWORD dwMask=0;HANDLE WaitHandles3; /監(jiān)聽事件數(shù)組DWORD dwSignaledHandle;WaitHandles0 = this-m_pPort-GetCloseHa
22、ndle();WaitHandles1 = this-m_ReadOverlapped.hEvent;WaitHandles2 = this-m_BreakOverlapped.hEvent;this-m_pPort-GetSerialPort()-SetMask(EV_ERR | EV_RLSD | EV_RING ); if(!SetBreakEvent(dwMask)goto EndThread;/設(shè)置讀事件if(!SetReadEvent(this-m_ReadOverlapped)goto EndThread;/設(shè)置comEventfor(;)dwSignaledHandle=:Wa
23、itForMultipleObjects(3,WaitHandles,false,INFINITE);switch(dwSignaledHandle)case WAIT_OBJECT_0:goto EndThread; break;case WAIT_OBJECT_0+1:if(!this-HandleReadEvent(this-m_ReadOverlapped)goto EndThread;if(!this-SetReadEvent(this-m_ReadOverlapped)goto EndThread;break;case WAIT_OBJECT_0+2:if(!this-Handle
24、BreakEvent(dwMask)goto EndThread; if(!this-SetBreakEvent(dwMask)goto EndThread;break;default: /goto EndThread;break; EndThread:this-m_pPort-GetSerialPort()-Purge(PURGE_RXABORT | PURGE_RXCLEAR); :CloseHandle(this-m_ReadOverlapped.hEvent);:CloseHandle(this-m_BreakOverlapped.hEvent); return ; 主要是一個等待事件發(fā)送然后調(diào)用,響應(yīng)的過程,如果讀取事件發(fā)生則調(diào)用this-HandleReadEvent(this-m_ReadOverlapped); bool CR
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- Unit 1 Meeting new people Lesson 5(教學(xué)設(shè)計)-2024-2025學(xué)年人教PEP版(2024)英語三年級下冊
- 2 我學(xué)習(xí)我快樂 教學(xué)設(shè)計-2024-2025學(xué)年道德與法治三年級上冊統(tǒng)編版
- 8安全記心上 第一課時 平安出行(教學(xué)設(shè)計)-部編版道德與法治三年級上冊
- 股份合同范本
- 會所餐飲合同范本
- 菜地整治合同范本
- 出包合同范本
- 入股服裝合同范本
- 8《小心火災(zāi)》教學(xué)設(shè)計-2024-2025學(xué)年三年級上冊綜合實踐活動魯科版
- 紡織合同范本
- 學(xué)前兒童保育學(xué)(學(xué)前教育專業(yè))全套教學(xué)課件
- 畜牧養(yǎng)殖設(shè)備(共73張PPT)
- 消防安全每月防火檢查記錄
- 論文寫作與學(xué)術(shù)規(guī)范 課程教學(xué)大綱
- DB32/T 4443-2023 罐區(qū)內(nèi)在役危險化學(xué)品(常低壓)儲罐管理規(guī)范
- GB/T 678-2023化學(xué)試劑乙醇(無水乙醇)
- 新能源汽車電池石墨類負極材料一體化項目環(huán)境影響評價報告書
- 高中英語-what's in a name教學(xué)課件設(shè)計
- 小學(xué)家長接送學(xué)生協(xié)議書
- 小兒腹瀉病診療規(guī)范
- IT服務(wù)連續(xù)性實現(xiàn)指南
評論
0/150
提交評論