用DELPHI如何对并口进行操作?(200分)

  • 主题发起人 主题发起人 glede
  • 开始时间 开始时间
G

glede

Unregistered / Unconfirmed
GUEST, unregistred user!
请问各路神仙,用DELPHI如何对并口进行操作?<br>如果不直接嵌入汇编代码,<br>可以全部用win api 搞定吗?<br>如果可以,有哪些API可供使用?<br>
 
不用嵌入式汇编好像不行...
 
用COMM32控件
 
用标准API,CreateFile可以的
 
靠,真的没有API可以代替吗?<br>难道这就是DELPHI编程的一个死角。<br>
 
如果你硬是要用,CreateFile和INLINE就是你的惟2选择了。
 
TO 白河愁:<br>&nbsp; &nbsp; COMM32控件好象只能操作串口吧?它能操作并口吗?
 
如果你再2000/nt 还可以用CreateFile, 9x好像不行...
 
忘记了,可以用 windriver 写。
 
啊,还要自己写驱动?不会吧:(
 
用CreateFile嘛
 
你在什么系统上?
 
用CreateFile怎么操作,各位能否段读写操作的代码参考一下。谢谢<br><br>To tseug<br>&nbsp; &nbsp;系统是win98。<br>&nbsp;
 
98不用那么复杂, 嵌入式汇编最简单<br><br>procedure OutByte(aAddr: Word; aValue: Byte); register;<br>function InByte(aAddr: Word): Byte; register;<br><br>implementation<br><br>procedure OutByte(aAddr: Word; aValue: Byte);<br>asm<br>&nbsp; XCHG &nbsp;AX, DX<br>&nbsp; OUT &nbsp; DX, AL<br>end;<br><br>function InByte(aAddr: Word): Byte;<br>asm<br>&nbsp; XCHG &nbsp;AX, DX<br>&nbsp; IN &nbsp; &nbsp;AL, DX<br>end;
 
谢谢tseug大力支持。<br>虽然目前的这个项目用户的平台可能是win98,以后就不一定。<br><br>我参考了一下SPComm, 如果用CreateFile的话,可以这么用吗?<br><br>CreateFile( ‘LPT1’,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GENERIC_READ or GENERIC_WRITE,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0, {not shared}<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nil, {no security ??}<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OPEN_EXISTING,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 {template} );<br><br><br>
 
这儿有串囗的文章,大体应差不多。 <br><br><br>  <br>Delphi 中 串 行 通 信 的 实 现 <br><br><br>南 京 理 工 大 学 经 济 管 理 学 院96 研 究 生 王 琛 <br>---- 随 着 现 代 信 息 技 术 的 发 展 以 及 计 算 机 网 络 的 广 泛 使 用, 计 算 机 通 信 技 术 <br>已 经 日 臻 成 熟, 但 串 行 通 信 作 为 一 种 灵 活 方 便 可 靠 的 通 信 方 式, 仍 不 失 为 <br>有 效 的 通 信 手 段, 被 广 泛 应 用 于 工 业 控 制 中。 在 工 业 生 产 实 践 中, 用PC 机 对 <br>工 程 实 现 实 时 监 控, 通 常 要 求PC 机 能 在 用 户 界 面 上 具 有 数 据 采 集、 数 据 处 <br>理 以 及 控 制 信 号 的 产 生 与 传 输 等 功 能。 在 这 种 特 定 的 环 境 下,PC 机 要 与 过 <br>程 控 制 的 实 时 信 号 相 联 系, 就 要 求 能 实 现 对PC 机 的 串 行 端 口 直 接 操作。Borland <br>公 司 推 出 的Delphi 是 一 种 功 能 强 大 的 高 级 编 程 语 言, 其 具 有 的 可 视 化 面 向 对 <br>象 的 特 性, 特 别 适 于 在Windows 环 境 下 图 形 界 面 和 用 户 程 序 的 编 制。 本 文 就 是 <br>介 绍 基 于Windows95/NT 操 作 系 统 用Delphi 来 实 现PC 机 与 下 层PLC 控 制 器 之 间 的 串 口 <br>通 信 方 法。 <br><br>---- 基 于WIN95/NT 的 串 行 通 信 机 制 <br><br>---- Windows 操 作 系 统 的 机 制 禁 止 应 用 程 序 直 接 访 问 计 算 机 硬 件, 但 它 为 程 序 <br>员 提 供 了 一 系 列 的 标 准API 函 数, 使 得 应 用 程 序 的 编 制 更 加 方 便 并 且 免 除 了 <br>对 有 关 硬 件 的 调 试 麻 烦。 在Windows95/NT 中, 原 来Windows3.X 的WM_COMMNOTIFY 消 息 <br>已 被 取 消, 操 作 系 统 为 每 个 通 信 设 备 开 辟 了 用 户 可 定 义 大 小 的 读/ 写 缓 冲 <br>区, 数 据 进 出 通 信 口 均 由 操 作 系 统 后 台 完 成, 应 用 程 序 只 需 对 读/ 写 缓 冲 区 <br>操 作 即 可。WIN95/NT 中 几 个 常 用 的 串 行 通 信 操 作 函 数 如 下: <br><br>CreatFile <br>打 开 串 行 口 <br>CloseHandle <br>关 闭 串 行 口 <br>SetupComm <br>设 置 通 信 缓 冲 区 的 大 小 <br>ReadFile <br>读 串 口 操 作 <br>WriteFile <br>写 串 口 操 作 <br>SetCommState <br>设 置 通 信 参 数 <br>GetCommState <br>获 取 默 认 通 信 参 数 <br>ClearCommError <br>清 除 串 口 错 误 并 获 取 当 前 状 态 <br>---- 除 上 述 几 个 函 数 外, 还 要 经 常 用 到 一 个 重 要 的 记 录DCB( 设 备 控 制 <br>块)。DCB 中 记 录 有 可 定 义 的 串 行 口 参 数, 设 置 串 行 口 参 数 时 必 须 先 用 <br>GetCommState 函 数 将 系 统 默 认 值 填 入DCB 控 制 块, 然 后 才 可 把 用 户 想 改 变 的 自 定 <br>义 值 设 定。 <br><br>---- 在WIN95/NT 中 进 行 串 行 通 信 除 了 解 基 本 的 通 信 操 作 函 数 外, 还 要 掌 握 多 线 <br>程 编 程。 线 程 是 进 程 内 部 执 行 的 路 径, 是 操 作 系 统 分 配CPU 时 间 的 基 本 实 <br>体。 每 个 进 程 都 由 单 线 程 开 始 完 成 应 用 程 序 的 执 行。 串 行 通 信 需 要 利 用 多 <br>线 程 技 术 实 现, 其 主 要 的 处 理 逻 辑 可 以 表 述 如 下: 进 程 一 开 始 先 由 主 线 程 <br>做 一 些 必 要 的 初 始 化 工 作, 然 后 主 线 程 根 据 需 要 在 适 当 时 候 建 立 通 信 监 视 <br>线 程 监 视 通 信 口, 当 指 定 的 串 行 口 事 件 发 生 时, 向 主 线 程 发 送 <br>WM_COMMNOTIFY 消 息( 由 于WIN95 取 消 了WM_COMMNOTIFY 消 息, 因 此 必 须 自 己 创 <br>建), 主 线 程 对 其 进 行 处 理。 若 不 需 要WM_COMMNOTIFY 消 息, 则 主 线 程 终 止 通 <br>信 监 视 线 程。 <br><br>---- 多 线 程 同 时 执 行, 将 会 引 起 对 共 享 资 源 的 冲 突。 为 避 免 冲 突, 就 要 用 同 <br>步 多 线 程 对 共 享 资 源 进 行 访 问。WIN95 提 供 了 许 多 保 持 线 程 同 步 的 方 法, 笔 <br>者 采 用 创 建 事 件 对 象 来 保 持 线 程 同 步。 通 过CraeteEvent() 创 建 事 件 对 象, 使 <br>用SetEvent() 或PulseEvent() 函 数 将 事 件 对 象 设 置 成 信 号 同 步。 在 应 用 程 序 中, <br>利 用WaitSingleObject() 函 数 等 待 同 步 的 触 发, 等 到 指 定 的 事 件 被 其 它 线 程 设 置 <br>为 有 信 号 时, 才 继 续 向 下 执 行 程 序。 <br><br>---- Delphi 下 的 具 体 实 现 方 法 <br><br>---- Delphi 的 强 大 功 能 和 支 持 多 线 程 的 面 向 对 象 编 程 技 术, 使 得 实 现 串 行 通 信 <br>非 常 简 单 方 便。 它 通 过 调 用 外 部 的API 函 数 来 实 现, 主 要 步 骤 如 下: 首 先, 利 <br>用CreateFile 函 数 打 开 串 行 口, 以 确 定 本 应 用 程 序 对 此 串 行 口 的 占 有 权, 并 封 <br>锁 其 它 应 用 程 序 对 此 串 口 的 操 作; 其 次, 通 过GetCommState 函 数 填 充 设 备 控 制 <br>块DCB, 再 通 过 调 用SetCommState 函 数 配 置 串 行 口 的 波 特 率、 数 据 位、 校 验 位 和 <br>停 止 位。 然 后, 创 建 串 行 口 监 视 线 程 监 视 串 行 口 事 件。 在 此 基 础 上 就 可 以 <br>在 相 应 的 串 口 上 操 作 数 据 的 传 输; 最 后, 用CloseHandle 函 数 关 闭 串 行 口。 具 体 <br>的 程 序 如 下, 本 程 序 用Delphi3.0 编 制 在Win95 环t 境 下 调 试 通 过, 已 投 入 实 际 应 用 <br>中, 供 广 大 读 者 参 考。 <br><br>---- 程 序: <br><br>unit comdemou; <br>interface <br>uses <br>Windows, Messages, SysUtils, Classes, <br>Graphics, Controls, Forms, Dialogs; <br><br>const <br>Wm_commNotify=Wm_User+12; <br>type <br>TForm1 = class(TForm) <br>procedure FormCreate(Sender: TObject); <br>private <br>Procedure comminitialize; <br>Procedure MsgcommProcess(Var <br>Message:Tmessage); Message Wm_commnotify; <br>{ Private declarations } <br>public <br>{ Public declarations } <br>end; <br><br>//线程声明 <br>TComm=Class(TThread) <br>protected <br>procedure Execute;override; <br>end; <br><br>var <br>Form1: TForm1; <br>hcom,Post_Event:Thandle; <br>lpol:Poverlapped; <br>implementation <br><br>{$R *.DFM} <br><br>Procedure TComm.Execute; //线程执行过程 <br>var <br>dwEvtMask:Dword; <br>Wait:Boolean; <br>Begin <br>fillchar(lpol,sizeof(toverlapped),0); <br>While True do Begin <br>dwEvtMask:=0; <br>Wait:=WaitCommEvent(hcom,dwevtmask,lpol); <br>//等待串行口事件; <br>if Wait Then Begin <br>waitforsingleobject(post_event,infinite); <br>//等待同步事件置位; <br>resetevent(post_event); //同步事件复位; <br>PostMessage(Form1.Handle, <br>WM_COMMNOTIFY,0,0);//发送消息; <br>end; <br>end; <br>end; <br><br>procedure Tform1.comminitialize; <br>//串行口初始化 <br>var <br>lpdcb:Tdcb; <br>Begin <br>hcom:=createfile('com2',generic_read or <br>generic_write,0,nil,open_existing, <br>file_attribute_normal or <br>file_flag_overlapped,0);//打开串行口 <br>if hcom=invalid_handle_value then <br>else <br>setupcomm(hcom,4096,4096); <br>//设置输入,输出缓冲区皆为4096字节 <br>getcommstate(hcom,lpdcb); <br>//获取串行口当前默认设置 <br>lpdcb.baudrate:=2400; <br>lpdcb.StopBits:=1; <br>lpdcb.ByteSize:=8; <br>lpdcb.Parity:=EvenParity; //偶校验 <br>Setcommstate(hcom,lpdcb); <br>setcommMask(hcom,ev_rxchar); <br>//指定串行口事件为接收到字符; <br>end; <br><br>Procedure TForm1.Msgcomm <br>Process(Var Message:Tmessage); <br>var <br>Clear:Boolean; <br>Coms:Tcomstat; <br>cbNum,ReadNumber,lpErrors:Integer; <br>Read_Buffer:array[1..100]of char; <br>Begin <br>Clear:=Clearcommerror(hcom,lpErrors,@Coms); <br>if Clear Then Begin <br>cbNum:=Coms.cbInQue; <br>ReadFile(hCom,Read_Buffer, <br>cbNum,ReadNumber,lpol); <br>//处理接收数据 <br>SetEvent(Post_Event); <br>//同步事件置位 <br>end; <br>end; <br><br>procedure TForm1.FormCreate(Sender: TObject); <br>begin <br>comminitialize; <br>post_event:=CreateEvent <br>(nil,true,true,nil); //创建同步事件; <br>Tcomm.Create(False); <br>//创建串行口监视线程; <br>end; <br><br>end. <br>
 
可以.../不过, 有些参数和API要改动
 
有人做过这方面的应用吗?
 
多人接受答案了。
 
后退
顶部