全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1112
推到 Plurk!
推到 Facebook!

Delphi中串列通信的實現

 
jackkcg
站務副站長


發表:891
回覆:1050
積分:848
註冊:2002-03-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-09-21 18:00:41 IP:61.64.xxx.xxx 未訂閱
Delphi中串列通信的實現 http://delphi.cxc.cc/jiqiao/021.htm 隨 著 現 代 信 息 技 術 的 發 展 以 及 計 算 機 網 絡 的 廣 泛 使 用, 計 算 機 通 信 技 術已 經 日 臻 成 熟, 但 串 行 通 信 作 爲 一 種 靈 活 方 便 可 靠 的 通 信 方 式, 仍 不 失 爲有 效 的 通 信 手 段, 被 廣 泛 應 用 於 工 業 控 制 中。 在 工 業 生 産 實 踐 中, 用PC 機 對工 程 實 現 實 時 監 控, 通 常 要 求PC 機 能 在 用 戶 界 面 上 具 有 數 據 采 集、 數 據 處理 以 及 控 制 信 號 的 産 生 與 傳 輸 等 功 能。 在 這 種 特 定 的 環 境 下,PC 機 要 與 過程 控 制 的 實 時 信 號 相 聯 系, 就 要 求 能 實 現 對PC 機 的 串 行 端 口 直 接 操作。Borland公 司 推 出 的Delphi 是 一 種 功 能 強 大 的 高 級 編 程 語 言, 其 具 有 的 可 視 化 面 向 物件 的 特 性, 特 別 適 於 在Windows 環 境 下 圖 形 界 面 和 用 戶 程 序 的 編 制。 本 文 就 是介 紹 基 於Windows95/NT 操 作 系 統 用Delphi 來 實 現PC 機 與 下 層PLC 控 制 器 之 間 的 串 口通 信 方 法。 基 於WIN95/NT 的 串 行 通 信 機 制 Windows 操 作 系 統 的 機 制 禁 止 應 用 程 序 直 接 訪 問 計 算 機 硬 件, 但 它 爲 程 序員 提 供 了 一 系 列 的 標 准API 函 數, 使 得 應 用 程 序 的 編 制 更 加 方 便 並 且 免 除 了對 有 關 硬 件 的 調 試 麻 煩。 在Windows95/NT 中, 原 來Windows3.X 的WM_COMMNOTIFY 消 息已 被 取 消, 操 作 系 統 爲 每 個 通 信 設 備 開 辟 了 用 戶 可 定 義 大 小 的 讀/ 寫 緩 沖 區, 數 據 進 出 通 信 口 均 由 操 作 系 統 後 台 完 成, 應 用 程 序 只 需 對 讀/ 寫 緩 沖 區操 作 即 可。WIN95/NT 中 幾 個 常 用 的 串 行 通 信 操 作 函 數 如 下: CreatFile 打 開 串 行 口 CloseHandle 關 閉 串 行 口 SetupComm 設 置 通 信 緩 沖 區 的 大 小 ReadFile 讀 串 口 操 作 WriteFile 寫 串 口 操 作 SetCommState 設 置 通 信 參 數 GetCommState 獲 取 默 認 通 信 參 數 ClearCommError 清 除 串 口 錯 誤 並 獲 取 當 前 狀 態 ---- 除 上 述 幾 個 函 數 外, 還 要 經 常 用 到 一 個 重 要 的 記 錄DCB( 設 備 控 制 塊)。DCB 中 記 錄 有 可 定 義 的 串 行 口 參 數, 設 置 串 行 口 參 數 時 必 須 先 用 GetCommState 函 數 將 系 統 默 認 值 填 入DCB 控 制 塊, 然 後 才 可 把 用 戶 想 改 變 的 自 定 義 值 設 定。 ---- 在WIN95/NT 中 進 行 串 行 通 信 除 了 解 基 本 的 通 信 操 作 函 數 外, 還 要 掌 握 多 線 程 編 程。 線 程 是 進 程 內 部 執 行 的 路 徑, 是 操 作 系 統 分 配CPU 時 間 的 基 本 實 體。 每 個 進 程 都 由 單 線 程 開 始 完 成 應 用 程 序 的 執 行。 串 行 通 信 需 要 利 用 多 線 程 技 術 實 現, 其 主 要 的 處 理 邏 輯 可 以 表 述 如 下: 進 程 一 開 始 先 由 主 線 程 做 一 些 必 要 的 初 始 化 工 作, 然 後 主 線 程 根 據 需 要 在 適 當 時 候 建 立 通 信 監 視 線 程 監 視 通 信 口, 當 指 定 的 串 行 口 事 件 發 生 時, 向 主 線 程 發 送 WM_COMMNOTIFY 消 息( 由 於WIN95 取 消 了WM_COMMNOTIFY 消 息, 因 此 必 須 自 己 創 建), 主 線 程 對 其 進 行 處 理。 若 不 需 要WM_COMMNOTIFY 消 息, 則 主 線 程 終 止 通 信 監 視 線 程。 ---- 多 線 程 同 時 執 行, 將 會 引 起 對 共 享 資 源 的 沖 突。 爲 避 免 沖 突, 就 要 用 同 步 多 線 程 對 共 享 資 源 進 行 訪 問。WIN95 提 供 了 許 多 保 持 線 程 同 步 的 方 法, 筆 者 采 用 創 建 事 件 對 象 來 保 持 線 程 同 步。 通 過CraeteEvent() 創 建 事 件 對 象, 使 用SetEvent() 或PulseEvent() 函 數 將 事 件 對 象 設 置 成 信 號 同 步。 在 應 用 程 序 中, 利 用WaitSingleObject() 函 數 等 待 同 步 的 觸 發, 等 到 指 定 的 事 件 被 其 它 線 程 設 置 爲 有 信 號 時, 才 繼 續 向 下 執 行 程 序。 ---- Delphi 下 的 具 體 實 現 方 法 ---- Delphi 的 強 大 功 能 和 支 持 多 線 程 的 面 向 對 象 編 程 技 術, 使 得 實 現 串 行 通 信 非 常 簡 單 方 便。 它 通 過 調 用 外 部 的API 函 數 來 實 現, 主 要 步 驟 如 下: 首 先, 利 用CreateFile 函 數 打 開 串 行 口, 以 確 定 本 應 用 程 序 對 此 串 行 口 的 占 有 權, 並 封 鎖 其 它 應 用 程 序 對 此 串 口 的 操 作; 其 次, 通 過GetCommState 函 數 填 充 設 備 控 制 塊DCB, 再 通 過 調 用SetCommState 函 數 配 置 串 行 口 的 波 特 率、 數 據 位、 校 驗 位 和 停 止 位。 然 後, 創 建 串 行 口 監 視 線 程 監 視 串 行 口 事 件。 在 此 基 礎 上 就 可 以 在 相 應 的 串 口 上 操 作 數 據 的 傳 輸; 最 後, 用CloseHandle 函 數 關 閉 串 行 口。 具 體 的 程 序 如 下, 本 程 序 用Delphi3.0 編 制 在Win95 環t 境 下 調 試 通 過, 已 投 入 實 際 應 用 中, 供 廣 大 讀 者 參 考。 ---- 程 序: unit comdemou; interface uses Windows Messages SysUtils Classes Graphics Controls Forms Dialogs; const Wm_commNotify=Wm_User 12; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private Procedure comminitialize; Procedure MsgcommProcess(Var Message:Tmessage); Message Wm_commnotify; { Private declarations } public { Public declarations } end; //線程聲明 TComm=Class(TThread) protected procedure Execute;override; end; var Form1: TForm1; hcom Post_Event:Thandle; lpol:Poverlapped; implementation {$R *.DFM} Procedure TComm.Execute; //線程執行過程 var dwEvtMask:Dword; Wait:Boolean; Begin fillchar(lpol sizeof(toverlapped) 0); While True do Begin dwEvtMask:=0; Wait:=WaitCommEvent(hcom dwevtmask lpol); //等待串列口事件; if Wait Then Begin waitforsingleobject(post_event infinite); //等待同步事件置位; resetevent(post_event); //同步事件重定; PostMessage(Form1.Handle WM_COMMNOTIFY 0 0);//發送消息; end; end; end; procedure Tform1.comminitialize; //串列口初始化 var lpdcb:Tdcb; Begin hcom:=createfile('com2' generic_read or generic_write 0 nil open_existing file_attribute_normal or file_flag_overlapped 0);//打開串列口 if hcom=invalid_handle_value then else setupcomm(hcom 4096 4096); //設置輸入,輸出緩衝區皆爲4096位元組 getcommstate(hcom lpdcb); //獲取串列口當前默認設置 lpdcb.baudrate:=2400; lpdcb.StopBits:=1; lpdcb.ByteSize:=8; lpdcb.Parity:=EvenParity; //偶校驗 Setcommstate(hcom lpdcb); setcommMask(hcom ev_rxchar); //指定串列口事件爲接收到字元; end; Procedure TForm1.Msgcomm Process(Var Message:Tmessage); var Clear:Boolean; Coms:Tcomstat; cbNum ReadNumber lpErrors:Integer; Read_Buffer:array[1..100]of char; Begin Clear:=Clearcommerror(hcom lpErrors @Coms); if Clear Then Begin cbNum:=Coms.cbInQue; ReadFile(hCom Read_Buffer cbNum ReadNumber lpol); //處理接收資料 SetEvent(Post_Event); //同步事件置位 end; end; procedure TForm1.FormCreate(Sender: TObject); begin comminitialize; post_event:=CreateEvent (nil true true nil); //創建同步事件; Tcomm.Create(False); //創建串列口監視線程; end; end. ********************************************************* 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind to make knowledge together! 希望能大家敞開心胸,將知識寶庫結合一起
------
**********************************************************
哈哈&兵燹
最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好

Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知
K.表Knowlege 知識,就是本站的標語:Open our mind
系統時間:2024-07-08 23:13:36
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!