古詩詞大全網 - 團隊口號 - 用VC 6.0實現串行通信的三種方法

用VC 6.0實現串行通信的三種方法

中國科學院王贏摘要本文介紹了Windows平臺下串行通信的實現機制,並根據不同情況討論了用Visual C++設計串行通信程序的三種方法,結合實際實現了溫度數據的接收和監控。

在實驗室和工業應用中,串口是計算機和外部串行設備之間常用的數據傳輸通道。由於串行通信方便易行,我們有必要根據不同的條件廣泛實現對串口的靈活編程控制。

在光學鏡片鍍膜過程中,采用單片機采集和控制多路溫度數據。采集的結果以串行方式進入上位機,每隔壹秒向上位機發送采樣數據,上位機向單片機發送相關控制命令,實現串行數據接收、處理、記錄顯示、實時繪制曲線。串口通信程序開發環境是VC++。

Windows下的串行通信

與以往DOS下的串行通信程序不同,Windows並不提倡應用程序直接控制硬件,而是通過Windows操作系統提供的設備驅動程序來傳輸數據。串口在Win中被當作壹個文件而不是直接操作端口,為串口通信Win提供了相應的文件I/o函數和通信函數通過了解這些函數的使用,可以編寫出滿足不同需求的通信程序。與通信設備相關的結構包括mconfig MPROP MTime OUTS stat dcb Modemdevcaps mode settings * * *與通信相關的Windows API函數* * *詳細描述請參考MSDN幫助文件。下面將結合實例給出實現串行通信的三種方法。

實現串行通信的三種方法

方法壹:使用VC++提供的串口通信控件MSComm。首先,在對話框中創建壹個通信控件。如果控件工具欄中缺少此控件,可以單擊項目>;添加到項目& gt可以插入組件和控件,將控件從工具箱拖到對話框中。這時妳只需要關心控件給Windows通訊驅動程序的API函數提供的接口,換句話說,妳只需要設置和監控MSComm控件的屬性和事件。

在ClassWizard中為新創建的通信控件定義成員對象(CMSComm _ Serial ),通過該對象可以設置串口屬性。MSComm控件* * *有壹個屬性,這裏只介紹幾個常用的屬性。

CommPort設置並返回通信端口號。默認值為

Settings以字符串形式設置並返回波特率奇偶校驗數據停止位。

PortOpen設置並返回通信端口的狀態,也可以打開和關閉端口。

輸入從接收緩沖區返回和刪除字符。

輸出將壹個字符串寫入發送緩沖區。

InputLen設置每個輸入讀取的字符數。默認值表示接收緩沖區中的所有內容都被讀取。

InBufferCount返回接收緩沖區中接收的字符數。將其設置為清除接收緩沖區。

InputMode定義了Input屬性獲取數據的方式(文本和二進制)。

RThreshold和SThreshold屬性指示在OnComm事件發生之前,接收緩沖區或發送緩沖區中可以接收的字符數。

以下是通過設置控件屬性來初始化串行端口的示例。

BOOL CSampleDlg::PortOpen(){ BOOL m _ Opened;m _ Serial SetCommPort();//指定序列號m _ Serial set settings(N);//通信參數設置m _ Serial SetInBufferSize();//指定接收緩沖區大小m _ Serial SetInBufferCount();//清除接收緩沖區m _ Serial input mode();//設置數據采集模式m _ Serial SetInputLen();//設置讀取模式m _ Opened = m _ Serail SetPortOpen();//打開指定的串口返回m _ Opened}?

打開所需串口後,我們需要考慮串口通信的時序。在接收或發送數據的過程中,我們可能需要監控和響應壹些事件和錯誤,所以事件驅動程序就是用來處理串口的。壹種非常有效的交互方法是通過使用OnComm事件和CommEvent屬性來捕獲和檢查通信事件和錯誤的值。當通信事件或錯誤發生時,將觸發OnComm事件。CommEvent屬性的值將被更改。應用程序將檢查CommEvent屬性的值,並做出相應的響應。在程序中,ClassWizard將用於CMSCo。Mm控件增加了on com消息處理函數Void csampledlg::on com(){ switch(m _ serial get comment()){ case://串口數據接收處理}}?

方法2:在單線程中實現自定義串行通信類。

該控件簡單易用,但由於必須在對話框中使用,控件的使用被拉長了。這時候如果能根據不同的需求定制靈活的串口通信類,就彌補了控件的不足。下面將介紹如何在單線程中建立自定義通信類。

通信類CSimpleComm需要手動添加頭文件和源文件,其基類是CObject。壹般的建立步驟如下

()打開串口獲取串口資源句柄。

通信程序從CreateFile中指定串口設備和相關操作屬性,然後返回壹個句柄,該句柄將用於後續的通信操作,並貫穿整個通信過程。CreateFile()函數中有幾個值得註意的參數。串口* * *享受模式應該設置為* * *。享受設備的創建模式必須是OPEN_EXISTING,即打開現有的串口。參數dwFlagAndAttribute對串口有意義的值是FILE_FLAG_OVERLAPPED。該標誌表示串口采用異步通信方式,可以重疊。如果值為空,則為同步通信模式。在同步模式下,應用程序將始終控制程序流,直到程序結束。如果發生通信失敗,應用程序將永遠等待,所以壹般使用異步通信。

()串行端口設置

串口打開後,其屬性設置為默認值。根據具體需要,調用getCommState(HComm & amp;Dcb)讀取當前串行設備控制塊DCB(設備控制塊)的設置並修改,然後傳遞setcommstate(HComm & amp;Dcb)寫壹下,然後註意異步讀寫的超時控制設置。通過MTIMEOUTS結構設置超時,並調用setCommTimeouts(HComm & amp;超時)將結果寫入溫度監控程序中的以下串行端口初始化成員函數。

BOOL CSimpleComm::Open(){ DCB DCB;m _ hIDComDev = create FILE(GENERIC _ READ | GENERIC _ WRITE NULL OPEN _ EXISTING FILE _ ATTRIBUTE _ NORMAL | FILE _ FLAG _ OVE RLAPPED NULL);//Open串行異步操作if (m _ hidcomdev = = null)返回(false);DCB DCBlength = sizeof(DCB);GetCommState(m _ hIDComDev & amp;dcb);//獲取端口默認設置dcb BaudRate = CBR _;dcb字節大小=;dcb奇偶= NOPARITYdcb stop bits =(BYTE)ONESTOPBIT;}?

()串口讀寫操作

主要使用ReadFile()和WriteFile()API函數。如果通信模式是異步的,那麽兩個函數的最後壹個參數是壹個指向重疊結構的非空指針。當讀寫函數的返回值為FALSE時,調用GetLastError()函數,返回值為ERROR_IO_PENDING,表示I/ O操作暫停,即操作轉移到後臺繼續執行。此時可以使用WaitForSingleObject()等待結束信號,設置最長等待時間。例子如下。

布爾面包狀態;bread status = ReadFile(m _ hIDComDev buffer dwbytes read & amp;dwBytesRead & ampm _ OverlappedRead);如果(!bread status){ if(GetLastError()= = ERROR _ IO _ PENDING){ WaitForSingleObject(m _ overlappedred hEvent);return((int)dwBytesRead);} return();} return((int)dwBytesRead);?

全局變量m_Serial定義為新的通信類CSimpleComm的對象,通過調用該類的成員函數可以實現所需的串行通信功能。與第壹種方法相比,第二種方法賦予了串行通信程序更大的讀寫端口的靈活性。您可以選擇壹個更簡單的查詢或設置壹個與外設數據傳輸時間間隔相同的定時器(TimeCycle null)。

csample view::on time(UINT nIDEvent){ char input data[];m _ Serial ReadData(input data);//數據處理}?

如果端口數據的響應時間比較嚴格,可以使用事件驅動的I/O進行讀寫。Windows定義了壹種常用的串行通信事件。

EV_RXCHAR:接收到壹個字節並將其放入輸入緩沖區。

EV_TXEMPTY:輸出緩沖區中的最後壹個字符被發送出去。

EV_RXFLAG:接收到的事件字符(DCB結構中的EvtChar成員)被放入輸入緩沖區。

用SetCommMask()指定壹個有用的事件後,應用程序可以調用WaitCommEvent()來等待事件發生。SetCommMask(hComm)可以停止WaitCommEvent()。

方法三,多線程下實現串行通信。

方法壹或二適用於單線程通信。在很多工業控制系統中,往往通過擴展串口連接多個外設,每個外設發送數據的重復頻率是不同的。它要求在後臺實時無誤地捕獲、處理和記錄每個端口的數據。這需要在用戶定義的串行通信類中創建壹個端口監控線程,以便在特定事件發生時向相關窗口發送通知消息。