---- 隨 著 現(xiàn) 代 信 息 技 術(shù) 的 發(fā) 展 以 及 計(jì) 算 機(jī) 網(wǎng) 絡(luò) 的 廣 泛 使 用, 計(jì) 算 機(jī) 通 信 技 術(shù) 已 經(jīng) 日 臻 成 熟, 但 串 行 通 信 作 為 一 種 靈 活 方 便 可 靠 的 通 信 方 式, 仍 不 失 為 有 效 的 通 信 手 段, 被 廣 泛 應(yīng) 用 于 工 業(yè) 控 制 中。 在 工 業(yè) 生 產(chǎn) 實(shí) 踐 中, 用PC 機(jī) 對(duì) 工 程 實(shí) 現(xiàn) 實(shí) 時(shí) 監(jiān) 控, 通 常 要 求PC 機(jī) 能 在 用 戶(hù) 界 面 上 具 有 數(shù) 據(jù) 采 集、 數(shù) 據(jù) 處 理 以 及 控 制 信 號(hào) 的 產(chǎn) 生 與 傳 輸 等 功 能。 在 這 種 特 定 的 環(huán) 境 下,PC 機(jī) 要 與 過(guò) 程 控 制 的 實(shí) 時(shí) 信 號(hào) 相 聯(lián) 系, 就 要 求 能 實(shí) 現(xiàn) 對(duì)PC 機(jī) 的 串 行 端 口 直 接 操 作。Borland 公 司 推 出 的Delphi 是 一 種 功 能 強(qiáng) 大 的 高 級(jí) 編 程 語(yǔ) 言, 其 具 有 的 可 視 化 面 向 對(duì) 象 的 特 性, 特 別 適 于 在Windows 環(huán) 境 下 圖 形 界 面 和 用 戶(hù) 程 序 的 編 制。 本 文 就 是 介 紹 基 于Windows95/NT 操 作 系 統(tǒng) 用Delphi 來(lái) 實(shí) 現(xiàn)PC 機(jī) 與 下 層PLC 控 制 器 之 間 的 串 口 通 信 方 法。
CreatFile | 打 開(kāi) 串 行 口 |
CloseHandle | 關(guān) 閉 串 行 口 |
SetupComm | 設(shè) 置 通 信 緩 沖 區(qū) 的 大 小 |
ReadFile | 讀 串 口 操 作 |
WriteFile | 寫(xiě) 串 口 操 作 |
SetCommState | 設(shè) 置 通 信 參 數(shù) |
GetCommState | 獲 取 默 認(rèn) 通 信 參 數(shù) |
ClearCommError | 清 除 串 口 錯(cuò) 誤 并 獲 取 當(dāng) 前 狀 態(tài) |
---- 除 上 述 幾 個(gè) 函 數(shù) 外, 還 要 經(jīng) 常 用 到 一 個(gè) 重 要 的 記 錄DCB( 設(shè) 備 控 制 塊)。DCB 中 記 錄 有 可 定 義 的 串 行 口 參 數(shù), 設(shè) 置 串 行 口 參 數(shù) 時(shí) 必 須 先 用GetCommState 函 數(shù) 將 系 統(tǒng) 默 認(rèn) 值 填 入DCB 控 制 塊, 然 后 才 可 把 用 戶(hù) 想 改 變 的 自 定 義 值 設(shè) 定。
---- 在WIN95/NT 中 進(jìn) 行 串 行 通 信 除 了 解 基 本 的 通 信 操 作 函 數(shù) 外, 還 要 掌 握 多 線 程 編 程。 線 程 是 進(jìn) 程 內(nèi) 部 執(zhí) 行 的 路 徑, 是 操 作 系 統(tǒng) 分 配CPU 時(shí) 間 的 基 本 實(shí) 體。 每 個(gè) 進(jìn) 程 都 由 單 線 程 開(kāi) 始 完 成 應(yīng) 用 程 序 的 執(zhí) 行。 串 行 通 信 需 要 利 用 多 線 程 技 術(shù) 實(shí) 現(xiàn), 其 主 要 的 處 理 邏 輯 可 以 表 述 如 下: 進(jìn) 程 一 開(kāi) 始 先 由 主 線 程 做 一 些 必 要 的 初 始 化 工 作, 然 后 主 線 程 根 據(jù) 需 要 在 適 當(dāng) 時(shí) 候 建 立 通 信 監(jiān) 視 線 程 監(jiān) 視 通 信 口, 當(dāng) 指 定 的 串 行 口 事 件 發(fā) 生 時(shí), 向 主 線 程 發(fā) 送WM_COMMNOTIFY 消 息( 由 于WIN95 取 消 了WM_COMMNOTIFY 消 息, 因 此 必 須 自 己 創(chuàng) 建), 主 線 程 對(duì) 其 進(jìn) 行 處 理。 若 不 需 要WM_COMMNOTIFY 消 息, 則 主 線 程 終 止 通 信 監(jiān) 視 線 程。
---- 多 線 程 同 時(shí) 執(zhí) 行, 將 會(huì) 引 起 對(duì) 共 享 資 源 的 沖 突。 為 避 免 沖 突, 就 要 用 同 步 多 線 程 對(duì) 共 享 資 源 進(jìn) 行 訪 問(wèn)。WIN95 提 供 了 許 多 保 持 線 程 同 步 的 方 法, 筆 者 采 用 創(chuàng) 建 事 件 對(duì) 象 來(lái) 保 持 線 程 同 步。 通 過(guò)CraeteEvent() 創(chuàng) 建 事 件 對(duì) 象, 使 用SetEvent() 或PulseEvent() 函 數(shù) 將 事 件 對(duì) 象 設(shè) 置 成 信 號(hào) 同 步。 在 應(yīng) 用 程 序 中, 利 用WaitSingleObject() 函 數(shù) 等 待 同 步 的 觸 發(fā), 等 到 指 定 的 事 件 被 其 它 線 程 設(shè) 置 為 有 信 號(hào) 時(shí), 才 繼 續(xù) 向 下 執(zhí) 行 程 序。
---- 程 序:
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; // 線 程 執(zhí) 行 過(guò) 程 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); // 同 步 事 件 復(fù) 位; PostMessage(Form1.Handle,WM_COMMNOTIFY,0,0);// 發(fā) 送 消 息; 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);// 打 開(kāi) 串 行 口 if hcom=invalid_handle_value then else setupcomm(hcom,4096,4096); // 設(shè) 置 輸 入, 輸 出 緩 沖 區(qū) 皆 為4096 字 節(jié) getcommstate(hcom,lpdcb); // 獲 取 串 行 口 當(dāng) 前 默 認(rèn) 設(shè) 置 lpdcb.baudrate:=2400; lpdcb.StopBits:=1; lpdcb.ByteSize:=8; lpdcb.Parity:=EvenParity; // 偶 校 驗(yàn) Setcommstate(hcom,lpdcb); setcommMask(hcom,ev_rxchar); // 指 定 串 行 口 事 件 為 接 收 到 字 符; end; Procedure TForm1.MsgcommProcess(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); // 處 理 接 收 數(shù) 據(jù) SetEvent(Post_Event); // 同 步 事 件 置 位 end; end; procedure TForm1.FormCreate(Sender: TObject); begin comminitialize; post_event:=CreateEvent(nil,true,true,nil); // 創(chuàng) 建 同 步 事 件; Tcomm.Create(False); // 創(chuàng) 建 串 行 口 監(jiān) 視 線 程; end; end.
---- 南 京 理 工 大 學(xué) 經(jīng) 濟(jì) 管 理 學(xué) 院96 研 究 生 210094 王
琛
---- 聯(lián) 系 電 話(huà):025-4315011-405 或025-8760087 CALL 39787(
中 文)