📄 m59.htm
字号:
<html>
<head>
<title>VB教程</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<p align="center"><script src="../../1.js"></script></a>
<body bgcolor="#ffffff" leftmargin="5" topmargin="1" marginheight="5" marginwidth="5">
<div align=center>
<table border=0 cellpadding=0 cellspacing=0 width=680 align="center">
<tbody>
<tr>
<td bgcolor=#000000 height=9>
<div align=center class=H1> 基于Win95的VB5串口通信程序</font> </font> </font></div>
</td>
</tr>
<tr valign=top>
<td class=H1 height=76>
<p align="left"> <br>
</font><font color="#000000">Visual Basic5.0( 以 下 简 称VB)
以 其 简 单 易 学、32 位 面 向 对 象 的 程 序 设 计 等 特 点, 倍 受 广 大 计 算 机 开 发 者 的 青 睐,
已 广 泛 地 应 用 于 各 个 领 域; 在 实 时 监 测 系 统 中 串 行 端 口 通 信 是 一 项 基 础 功 能, 因
此 我 们 使 用VB5 编 写 了 实 时 水 库 水 文 自 动 监 测 系 统 的 后 台 机 软 件。 本 文 就Windows
95 环 境 中 采 用VB5 设 计 串 行 端 口 通 信 程 序 进 行 讨 论 并 给 出 实 例。 </font></p>
<p> 一 般 用VB 开 发 串 行 通 信 程 序 有 两 种 方 法: 一 是 利 用Windows
的 通 信API 函 数; 另 一 种 是 采 用VB 标 准 控 件Mscomm 来 实 现。 </font>
<h3><font color="#000000">Windows 95 的 通 信API</font></h3>
Windows 95 中 的 串 口 通 信API 函 数 不 同 于Windows3.x
中 的OpenComm、CloseComm、ReadComm、WriteComm, 而 是 采 用 硬 件 与 文 件 通 用 的 函 数CreateFile、ReadFile、WriteFile、CloseHandle,
该 类 函 数 更 具 有 一 般 性, 并 且 可 以 用EscapeCommFunction 函 数 实 现 底 层 硬 件 操 作,
比 如:SETXOFF、 CLRDTR 等。 </font>
<p> 利 用API 编 写 串 口 通 信 程 序 较 为 复 杂, 需 要 掌 握 大
量 通 信 知 识, 其 优 点 是 可 实 现 的 功 能 更 丰 富、 应 用 面 更 广 泛, 更 适 合 于 编 写 较 为 复
杂 的 低 层 次 通 信 程 序。 采 用 这 种 方 法 编 写 串 行 端 口 通 信 程 序 一 般 可 分 为 以 下 几 个
过 程: </font>
<p> 1. 初 始 化 串 行 端 口 </font>
<p> 首 先 用CreateFile 函 数 打 开 指 定 串 口, 置 参 数 中 访
问 类 型 为GENERIC_READ |GENERIC_WRITE、 共 享 模 式 为0、 创 建 标 志 为OPEN_EXISTING、
模 板 句 柄 为NULL。 </font>
<p> 2. 配 置 串 口 </font>
<p> Windows 95 的 串 口 配 置 比Windows 3.x 较 为 复 杂,
但 其 功 能 更 强 大, 对 一 般 程 序 可 使 用CommConfigDialog 函 数 以 对 话 框 方 式 设 置 波
特 率、 数 据 位、 奇 偶 校 验、 停 止 位 和 流 控 制 方 式, 并 且 可 以 恢 复 缺 省 值。 </font>
<p> 3. 超 时 控 制 </font>
<p> 为 了 防 止 意 外 情 况 使 串 口 读 写 无 休 止 地 等 待,Windows
95 提 供 了 超 时 设 置, 这 是 由COMMTIMEOUTS 结 构 定 义 的, 通 过 调 用GetCcommTimeOuts
函 数 获 得 当 前 的 设 置, 用SetCommTimeOuts 函 数 来 完 成 设 置。 </font>
<p> 4. 数 据 传 输 </font>
<p> 读 写 串 行 端 口 与 读 写 文 件 采 用 的 函 数 相 同, 即ReadFile、WriteFile,
读 写 操 作 可 分 四 种 方 式: 查 询 方 式、 同 步I/O、 异 步( 后 台)I/O 和 事 件 驱 动I/O。 </font>
<p> 5. 关 闭 串 口 </font>
<p> 程 序 的 终 止 可 以 自 动 关 闭 串 口, 也 可 用 函 数CloseHandle(),
以 便 释 放 所 独 占 资 源。 </font>
<h3><font color="#000000">VB 通 信 控 件Mscomm</font></h3>
Mscomm 控 件 提 供 了 功 能 完 善 的 串 口 数 据 的 发 送 和 接
收 功 能,Mscomm 控 件 具 有 两 种 处 理 方 式: 1 事 件 驱 动 方 式: 由Mscomm 控 件 的OnComm 事
件 捕 获 并 处 理 通 信 错 误 及 事 件;2 查 询 方 式: 通 过 检 查CommEvent 属 性 的 值 来 判 断 事
件 和 错 误。 </font>
<p> Mscomm 控 件 的 通 信 功 能 实 现, 实 际 上 是 调 用 了API
函 数, 而API 函 数 是 由Comm.drv 解 释 并 传 给 设 备 驱 动 程 序 执 行 的, 对 于VB 程 序 开 发
者 只 需 知 道Mscomm 控 件 的 属 性 和 事 件 的 用 法 即 可 以 实 现 串 口 的 操 作。 </font>
<p> 以 下 是Mscomm 控 件 的 主 要 属 性 和 方 法: </font>
<p> 1)CommPort: 设 置 或 返 回 串 行 端 口 号, 其 取 值 范 围
为1 ~99, 缺 省 为1。 </font>
<p> 2) Setting 设 置 或 返 回 串 行 端 口 的 波 特 率、 奇 偶
校 验 位、 数 据 位 数、 停 止 位。 如:Mscomm.Setting=“9600,N,8,1”。 </font>
<p> 3)PortOpen: 打 开 或 关 闭 串 行 端 口, 格 式 为:Mscomm.PortOpen={TRUE|FALSE}。
</font>
<p> 4) InBufferSize: 设 置 或 返 回 接 收 缓 冲 区 的 大 小,
缺 省 为1024 字 节。 </font>
<p> 5) InBufferCount: 返 回 接 收 缓 冲 区 内 的 等 待 读
取 的 字 节 个 数, 可 通 过 设 置 该 属 性 为0 来 清 除 接 收 缓 冲 区。 </font>
<p> 6) RThreshold: 该 属 性 为 一 阀 值, 它 确 定 当 接 收
缓 冲 区 内 字 节 个 数 达 到 或 超 过 该 值 后 就 产 生 代 码 为MSCOMM_EV_RECEIVE 的OnComm
事 件。 </font>
<p> 7) InputLen: 设 置 或 返 回 接 收 缓 冲 区 内 用Input
读 入 的 个 数。 若 取0, 则INPUT 读 取 整 个 缓 冲 区 的 内 容。 </font>
<p> 8) Input: 该 属 性 表 示 从 接 收 缓 冲 区 移 走 一 串 字
符。 </font>
<p> 9) OutBufferSize: 设 置 或 返 回 发 送 缓 冲 区, 缺 省
为512 字 节。 </font>
<p> 10) OutBufferCounter: 返 回 发 送 缓 冲 区 内 等 待
发 送 的 字 符 数, 可 用 来 清 空 缓 冲 区。 </font>
<p> 11) Output: 向 发 送 缓 冲 区 传 送 一 字 符 串。 </font>
<p> 12) EOFEnable: 若 置TRUE, 则 当 输 入 中 出 现EOF,
就 停 止 输 入 并 产 生OnComm 事 件。 </font>
<p> 如 果 在 通 信 过 程 中 发 生 错 误 或 事 件, 就 会 引 发OnComm
事 件 并 且 改 变 属 性 值, 由CommEvent 属 性 代 码 反 映 错 误 类 型, 在 通 信 程 序 的 设 计 中
可 根 据 该 属 性 值 来 执 行 不 同 的 操 作, 以 下 是 部 分 属 性 常 数 值 及 其 含 义: </font>
<p> 1)ComEvSend: 其 值 为1, 发 送 缓 冲 区 的 内 容 少 于SThreshold
指 定 的 值。 </font>
<p> 2) ComEvReceive: 其 值 为2, 接 收 缓 冲 区 内 字 符 数
达 到 RThreshold 值, 该 事 件 在 缓 冲 区 中 数 据 被 移 走 前 将 持 续 产 生。 </font>
<p> 3) ComEventFrame: 其 值 为1004, 硬 件 检 测 到 帧 错
误。 </font>
<p> 4) ComEventRxOver: 其 值 为1008, 接 收 缓 冲 区 溢
出。 </font>
<p> 5) ComEventTxFull: 其 值 为1010, 发 送 缓 冲 区 溢
出。 </font>
<p> 6) ComEventRxParity: 其 值 为1009, 奇 偶 校 验。 </font>
<p> 7) ComEvEOF: 其 值 为7, 接 收 数 据 中 出 现 文 件 结 束(ASCII
码 为 26) 字 符。 </font>
<h3> 程 序 样 例</font></h3>
采 用Mscomm 控 件 实 现 串 口 通 信 时, 首 先 添 加 一Mscomm
控 件 到 窗 体 中, 该 控 件 一 般 不 在 通 用 工 具 窗 口 中, 而 是 需 通 过 菜 单 项“ 工 程(P) → 部
件(O)” 进 入 选 择 窗 口, 在 控 件tab 页 中 选 取Microsoft Comm Control 5.0 , 此 时 工
具 窗 口 中 出 现Mscomm 图 标, 即 可 被 使 用。 </font>
<p> 以 下 是 事 件 驱 动 方 式 的 接 收 程 序 的 主 要 部 分: Private
Sub getdatafromserial_Click() </font>
<p> CommonDialog1.InitDir = “c:\temp" </font>
<p> CommonDialog1.ShowSave </font>
<p> mainfrm.MSComm1.CommPort=1 </font>
<p> hfile = FreeFile </font>
<p> ’ 打 开 存 储 接 收 数 据 的 文 件 </font>
<p> Open CommonDialog1.filename For Output As
#hfile </font>
<p> ’ 设 接 收 缓 冲 区 的 大 小, 可 按 量 确 定 </font>
<p> mainfrm.MSComm1.InBufferSize = 4096 </font>
<p> If Not mainfrm.MSComm1.PortOpen Then ’ 打 开
串 口 </font>
<p> -- mainfrm.MSComm1.PortOpen = True </font>
<p> End If </font>
<p> If Err Then </font>
<p> MsgBox “Communcation port cannot be opened!!"
</font>
<p> ’ 清 接 收 缓 冲 区 </font>
<p> mainfrm.MSComm1.InBufferCount = 0 </font>
<p> ’ 设 一 次 读 入 的 长 度, 可 根 据 数 据 格 式 设 置 </font>
<p> mainfrm.MSComm1.InputLen = 77 </font>
<p> ’ 设 置 接 收 事 件 触 发 的 阀 值 </font>
<p> mainfrm.MSComm1.RThreshold = 77 </font>
<p> counter = Timer + 10 </font>
<p> Do </font></p>
<br>
If Timer > counter Then<br>
<br>
mainfrm.Label1.Caption = “ 正 在 通 信......"<br>
<br>
mainfrm.Label1.Refresh<br>
<br>
counter = Timer + 10<br>
<br>
End If<br>
<br>
DoEvents<br>
<br>
Loop <br>
<br>
End Sub<br>
<br>
</font>
<p> 以 下 为 事 件 处 理 子 程 序,flag 为 一 静 态 变 量 记 录 读
取 次 数, 以 便 改 变 接 收 数 据 的 长 度, 读 者 可 根 据 实 际 需 要 添 加 其 它 处 理 内 容: </font></p>
<br>
Private Sub MSComm1_OnComm()<br>
<br>
Select Case MSComm1.CommEvent<br>
<br>
Case comEvReceive<br>
<br>
If flag > 246 Then<br>
<br>
MSComm1.InputLen = 0: MSComm1.RThreshold = 32<br>
<br>
End If<br>
<br>
buffer = MSComm1.Input<br>
<br>
temp = buffer<br>
<br>
Print #hfile, temp<br>
<br>
counter = Timer + 10<br>
<br>
Do While Timer > counter<br>
<br>
Do Events<br>
<br>
Loop<br>
<br>
flag = flag + 1<br>
<br>
Case comEvEOF<br>
<br>
EVMsg $ = “ 检 测 到 文 件 结 尾!!!"<br>
<br>
Case comFrame<br>
<br>
ERMsg $ = “ 帧 出 错!!!"<br>
<br>
Case comRxParity<br>
<br>
ERMsg $ = “ 奇 偶 错!!!"<br>
<br>
End Select<br>
<br>
If Len(EVMsg $) Then<br>
<br>
Text1.Text = “Status: " & EVMsg $<br>
<br>
ElseIf Len(ERMsg $) Then<br>
<br>
Text1.Text = “Status: " & ERMsg $<br>
<br>
Beep<br>
<br>
Ret = MsgBox(ERMsg $, 1, “Click Cancel to <br>
<br>
quit, OK to ignore.")<br>
<br>
MSComm1.PortOpen = False<br>
<br>
End If<br>
<br>
End Sub<br>
</font>
<p align="left"> <br>
</table>
</div>
<p align="center"><a href="../../pian/vb.htm">回首页</a>
<p align="center"><script src="../../2.js"></script></a>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -