摘要
本文介紹了在Windows平台下串口開發的方法
並給出一個使用Delphi設計的遠程數據采集的實例
引言
在工業生產實踐中
使用PC機對Inprise公司推出的Delphi是一種功能強大的高級編程語言
其具有可視化面向對象的特征
特別適合Windows平台下的圖形界面和用戶程序的編制
本文就介紹在Windows平台下用Delphi開發串口的方法和使用Delphi設計的一個實現遠程串行數據采集的實例
串口工作原理及軟件實現方法
串口進行通信的方式有兩種
同步通信方式和異步通信方式
同步通信方式要求通信雙方以相同的時鐘頻率進行
而且准確協調
通過共享一個單個時鐘或定時脈沖源保證發送方和接收方的准確同步
效率較高
異步通信方式不要求雙方同步
收發方可采用各自的時鐘源
雙方遵循異步的通信協議
以字符為數據傳輸單位
發送方傳送字符的時間間隔不確定
發送效率比同步傳送效率低
在Windows平台下
Win
API支持同步和異步兩種I/O操作
同步操作的方式的程序設計相對比較簡單
但是I/O操作函數在I/O操作結束前不能返回
這將掛起調用線程
直到I/O操作結束
異步操作方式要相對復雜一些
但是可以讓I/O操作在後台運行
而不會掛起調用線程
這在大數據量通信情況下對改善調用線程的響應速度是相當有效的
同時由於Win
x和WinNT下對串行通信的處理不同
這就導致了在Win
x下開發的同步方式串行通信程序在NT下會發生工作線程之間的協作阻塞
即當讀線程在等待WaitCommEvent的時候
寫線程不能正常工作
停在那裡
整個程序處於癱瘓狀態
這個問題是Windows的API函數處理串行通信的一個BUG
所以對於適應性強的程序都是選擇異步方式
下面
本文對在Windows平台下對串口進行開發的方法進行介紹
. 匯編程序直接讀寫串口
匯編語言的編譯效率和執行效率都很高
使用匯編語言直接對串口進行操作可以部分彌補串行通信速度較慢的缺陷
具體做法是
用匯編語言編寫讀
寫串口的函數
在通信程序中直接調用
或者在Delphi中直接內嵌匯編程序進行對端口的讀寫
例如
asm
mov dxh
mov axeh
int h
end;
這樣可以達到直接讀到端口的效果
但是在WinNT和Win
下
系統使用了保護機制
不允許用戶態的程序直接讀取端口
所以在WinNT和Win
下
這種方法不能被允許執行
Ring
的用戶態的程序要進入Ring
去讀寫端口必須先提供一個驅動(sys)程序
然後通過DLL導出函數供用戶程序調用
顯然
這種方法比較不容易實現
. 使用API函數進行串口編程
Windows系統通信一般都以WOSA(Windows Open Service Architecture
即Windows開放式服務體系)模型為基礎
在此模型中位於上層的應用程序通過調用各種通信API(Application Programming Interfaces
即應用程序接口)與位於下層的設備驅動程序進行數據交換
在Windows平台下
Windows將設備看作是文件進行管理
對設備的操作也可以看作是對文件的操作
Win
API提供了CreateFile()
WriteFile()
ReadFile()
WaitForSingleObject()
WaitForMultipleObjects()
CreateEvent()
CreateMutex()
CreateSemaphore()
CreateThread()等函數
其基本步驟如下
(
) 利用CreateFile()函數打開串口
該函數有七個參數
其中dwCreationDistribution參數取OPEN_EXISTING
表明打開的串口對應於實際的物理串口
lpFileName參數是要打開的串口名稱
如
COM
DwFlagsAndAttributes參數決定對串口的操作是同步操作還是異步操作
DwDesiredAccess參數是訪問方式
可取GENERIC_READ或GENERIC_WRITE
DwShareMode參數是共享模式
對串口物理設備必須取
LpSecurityAttributes參數是安全屬性
取值為NULL
DwFlagsAndAttributes是文件屬性和標識
一般取值為FILE_ATTRIBUTE_NORMAL
該函數返回串口操作的句柄
(
) 對該串口句柄對應的設備進行配置
如波特率
數據位
停止位
是否奇偶校驗等
這部分首先使用GetCommState()函數得到當前的串口配置信息
將這些信息存放在一個DCB結構中
然後對該DCB結構裡面的內容進行重新按要求設置
最後調用SetCommState()函數使修改的設置生效
(
) 配置串口事件
SetCommMask()函數可以設置多個串口信息事件
其串口的信息事件可以是以下任意的組合
EV_BREAK在輸入時Windows檢測到中斷
EV_CTS CTS信號改變狀態
EV_DSR DSR信號改變狀態
EV_ERR 發生線狀態錯誤
EV_RING 檢測到振鈴指示
EV_RLSD 接收線信號探測狀態發生改變
EV_RXCHAR接收緩沖區裡收到字符EV_RXFLAG收到事件字符並放入接收緩沖區
EV_TXEMPTY輸出緩沖區空
(
) 創建串口監視線程監視串口事件
首先使用WaitForSingleObject()
WaitForCommEvent()
WaitForMultipleObjects()等等待函數對線程進行控制
當沒有數據收發時
將線程阻塞
減少其CPU的資源占用
當有數據收發時
線程自動啟動
完成數據的收發
最後調用CreateThread()函數啟動線程
(
) 串口使用結束
用CloseHandle()函數關閉串口
回收資源
由此可見
利用Win
API函數編寫串口通信程序比較復雜
需要掌握大量的系統和通信知識
其優點是實現的功能強大
應用面廣泛
適合編寫較為復雜的地層次應用程序
[] []
From:http://tw.wingwit.com/Article/program/Delphi/201311/24926.html