程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi實現遠程串口的數據采集

Delphi實現遠程串口的數據采集

編輯:Delphi

摘要:本文介紹了在Windows平台下串口開發的方法,並給出一個使用Delphi設計的遠程數據采集的實例。

關鍵詞:遠程數據采集 AcitiveX MSComm控件

1 引言

在工業生產實踐中,使用PC機對Inprise公司推出的Delphi是一種功能強大的高級編程語言,其具有可視化面向對象的特征,特別適合Windows平台下的圖形界面和用戶程序的編制。本文就介紹在Windows平台下用Delphi開發串口的方法和使用Delphi設計的一個實現遠程串行數據采集的實例。

2 串口工作原理及軟件實現方法

串口進行通信的方式有兩種:同步通信方式和異步通信方式。同步通信方式要求通信雙方以相同的時鐘頻率進行,而且准確協調,通過共享一個單個時鐘或定時脈沖源保證發送方和接收方的准確同步,效率較高;異步通信方式不要求雙方同步,收發方可采用各自的時鐘源,雙方遵循異步的通信協議,以字符為數據傳輸單位,發送方傳送字符的時間間隔不確定,發送效率比同步傳送效率低。

在Windows平台下,Win32 API支持同步和異步兩種I/O操作。同步操作的方式的程序設計相對比較簡單,但是I/O操作函數在I/O操作結束前不能返回,這將掛起調用線程,直到I/O操作結束;異步操作方式要相對復雜一些,但是可以讓I/O操作在後台運行,而不會掛起調用線程,這在大數據量通信情況下對改善調用線程的響應速度是相當有效的。同時由於Win9x和WinNT下對串行通信的處理不同,這就導致了在Win9x下開發的同步方式串行通信程序在NT下會發生工作線程之間的協作阻塞,即當讀線程在等待WaitCommEvent的時候,寫線程不能正常工作,停在那裡,整個程序處於癱瘓狀態。這個問題是Windows的API函數處理串行通信的一個BUG,所以對於適應性強的程序都是選擇異步方式。下面,本文對在Windows平台下對串口進行開發的方法進行介紹:

1. 匯編程序直接讀寫串口

匯編語言的編譯效率和執行效率都很高,使用匯編語言直接對串口進行操作可以部分彌補串行通信速度較慢的缺陷,具體做法是:用匯編語言編寫讀、寫串口的函數,在通信程序中直接調用,或者在Delphi中直接內嵌匯編程序進行對端口的讀寫。

例如:

asm

mov dx,0001h

mov ax,005eh

int 14h

end;

這樣可以達到直接讀到端口的效果。但是在WinNT和Win2000下,系統使用了保護機制,不允許用戶態的程序直接讀取端口,所以在WinNT和Win2000下,這種方法不能被允許執行。Ring3的用戶態的程序要進入Ring0去讀寫端口必須先提供一個驅動(sys)程序,然後通過DLL導出函數供用戶程序調用,顯然,這種方法比較不容易實現。

2. 使用API函數進行串口編程

Windows系統通信一般都以WOSA(Windows Open Service Architecture,即Windows開放式服務體系)模型為基礎,在此模型中位於上層的應用程序通過調用各種通信API(Application Programming Interfaces,即應用程序接口)與位於下層的設備驅動程序進行數據交換。

在Windows平台下,Windows將設備看作是文件進行管理,對設備的操作也可以看作是對文件的操作。Win32 API提供了CreateFile(),WriteFile(),ReadFile(),WaitForSingleObject(),WaitForMultipleObjects(),CreateEvent(),CreateMutex(),CreateSemaphore(),CreateThread()等函數,其基本步驟如下:

(1) 利用CreateFile()函數打開串口。該函數有七個參數,其中dwCreationDistribution參數取OPEN_EXISTING,表明打開的串口對應於實際的物理串口;lpFileName參數是要打開的串口名稱,如"COM1";DwFlagsAndAttributes參數決定對串口的操作是同步操作還是異步操作;DwDesiredAccess參數是訪問方式,可取GENERIC_READ或GENERIC_WRITE;DwShareMode參數是共享模式,對串口物理設備必須取0;LpSecurityAttributes參數是安全屬性,取值為NULL;DwFlagsAndAttributes是文件屬性和標識,一般取值為FILE_ATTRIBUTE_NORMAL。該函數返回串口操作的句柄。

(2) 對該串口句柄對應的設備進行配置,如波特率、數據位、停止位、是否奇偶校驗等。這部分首先使用GetCommState()函數得到當前的串口配置信息,將這些信息存放在一個DCB結構中,然後對該DCB結構裡面的內容進行重新按要求設置,最後調用SetCommState()函數使修改的設置生效。

(3) 配置串口事件。SetCommMask()函數可以設置多個串口信息事件,其串口的信息事件可以是以下任意的組合:

EV_BREAK:在輸入時Windows檢測到中斷;

EV_CTS :CTS信號改變狀態;

EV_DSR :DSR信號改變狀態;

EV_ERR :發生線狀態錯誤;

EV_RING :檢測到振鈴指示;

EV_RLSD :接收線信號探測狀態發生改變;

EV_RXCHAR:接收緩沖區裡收到字符;EV_RXFLAG:收到事件字符,並放入接收緩沖區;

EV_TXEMPTY:輸出緩沖區空。

(4) 創建串口監視線程監視串口事件。首先使用WaitForSingleObject()、WaitForCommEvent()、WaitForMultipleObjects()等等待函數對線程進行控制,當沒有數據收發時,將線程阻塞,減少其CPU的資源占用;當有數據收發時,線程自動啟動,完成數據的收發。最後調用CreateThread()函數啟動線程。

(5) 串口使用結束,用CloseHandle()函數關閉串口,回收資源。

由此可見,利用Win32 API函數編寫串口通信程序比較復雜,需要掌握大量的系統和通信知識,其優點是實現的功能強大,應用面廣泛,適合編寫較為復雜的地層次應用程序。

3. 使用MSComm控件進行串口編程

Microsoft Communication Control(MSComm)是Microsoft公司提供的Windows下串行通信編程的AcitiveX控件。該控件具有豐富的與串口通信密切相關的屬性及事件,提供了一系列標准通信命令接口,可以用它創建全雙工、事件驅動、高效實用的通信程序。MSComm控件通過串口傳輸和接收數據,為應用程序提供串行通信功能。

MSComm的主要屬性及事件:

(1) CommPort:設置或返回串行端口號,缺省值1;

(2) Setting:設置或返回串口通信參數,格式為"波特率,奇偶校驗位,數據位,停止位";

(3) PortOpen:打開或關閉串行端口;

(4) InBufferSize:設置或返回接收緩沖區的大小,缺省值為1024字節;

(5) InBufferCount:返回接收緩沖區內等待讀取的字節數,可通過設置該屬性為0來清空接收緩沖區;

(6) RThreshold:該屬性為一閥值,它確定當接收緩沖區內的字節個數達到或超過該值後就產生代碼為ComEvReceive的OnComm事件;

(7) SThreshold:該屬性為一閥值,它確定當發送緩沖區內的字節個數少於該值後就產生代碼為ComEvSend的OnComm事件;

(8) InputLen:設置或返回接收緩沖區內用Input讀入的字節數,設置該屬性為0表示Input讀取整個緩沖區的內容;

(9) Input:從接收緩沖區讀取一串字符;

(10) InputMode:返回從Input中取回的數據類型,可以是ANSI碼和二進制數據數組;

(11) OutBufferSize:設置或返回發送緩沖區的大小,缺省值為512字節;

(12) OutBufferCount:返回發送緩沖區內等待發送的字節數,可通過設置該屬性為0來清空緩沖區;

(13) OutPut:向發送緩沖區傳送一串字符。

如果在通信過程中發生錯誤或事件,就會觸發OnComm事件,並由CommEvent屬性代碼反映錯誤類型,在通信程序的設計中可根據該屬性值來執行不同的操作。CommEvent屬性值及其含義如下:

(1) ComEvSend:值為1,發送緩沖區的內容少於SThreshold指定的值;

(2) ComEvReceive:值為2,接收緩沖區內字符數達到RThreshold指定的值;

(3) ComEvFrame:值為1004,硬件檢測到幀錯誤;

(4) ComEvRxOver:值為1008,接收緩沖區溢出;

(5) ComEvTxFull:值為1010,發送緩沖區溢出;

(6) ComEvRxParity:值為1009,奇偶校驗錯誤;

(7) ComEvEOF:值為7,接收數據中出現文件尾(ASCII碼為26)字符。

所以,MSComm控件主要提供下列兩種處理通信的方式:

(1) 事件驅動通信方式。當串口發送或接收到數據時,可以利用MSComm控件OnComm事件捕獲並處理這些通信事件。OnComm事件還可以檢查和處理通信錯誤。

(2) 查詢方式。在關鍵程序之後可以通過檢查CommEvent屬性來查詢事件和錯誤。

3 系統功能設計

本遠程數據采集子系統就是利用MSComm控件,通過Moderm同遠端的下位機進行通信,發送命令,獲得下位機采集的實時數據,通信流程如下:

當PC機檢測到下位機摘機的信號,將控制命令寫入MSComm的發送緩沖區,控制命令為定長的數據報,格式如下:

其中,當命令代碼不是向下位機要數據的命令的時候,起始時間和終止時間均為0。下位機上傳的數據報也為定長數據報,格式如下:

數據報標志表明正在傳輸是數據,為0xFFFF,數據報序號說明當前傳輸的是第幾個數據報,當序號校驗碼出錯時,PC機停止接收數據,並向下位機發重傳命令,此時控制命令的起始時間字段填入需要重傳的數據報的序號。最後一個數據報將結束標志置為0xFFFF,檢測線程檢測到該標志時,認為數據接收完畢,向主線程發消息,通知主線程做進一步的處理。

數據傳輸模式采用二進制數據流形式即MSComm的InputMode屬性設置為ComInputModeBinary,收到數據之後使用如下程序進行轉換:

vDataBuffer: oleVariant;

DataBuffer: variant;

vDataBuffer := MSComm1.Input;

DataBuffer := VarArrayCreate([0,2048], varByte);

DataBuffer := vDataBuffer;

主線程向下位機發要數據命令的同時,生成檢測線程,每收到1032個字節,檢測線程對收到的數據報的結束標志和數據報序號進行檢驗,發現數據報序號錯誤立即向主線程發錯誤消息,主線程停止從緩沖中取數據,向下位機發重傳數據報的命令。檢測線程發現數據報接收完畢,向主線程發消息,主線程結束檢測線程,回收資源。

4 結論

整個系統在遠程心電醫療診斷軟件上已經得到了應用,實際運行表明,該通信方式簡單、可靠、穩定,具有比較高的效率和很好的差錯控制功能,可供其他遠程通信系統借鑒參考。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved