注意:访问本站需要Cookie和JavaScript支持!请设置您的浏览器! • 打开购物车 • 查看留言 • 付款方式 • 联系我们 |
首页 | 电子入门 | 学单片机 | 免费资源 | 下载中心 | 商品列表 | 象棋在线 | 在线绘图 | 加盟五一 | 加入收藏 | 设为首页 |
选择分类:当前分类——电脑编程 相关联或者相类似的文章: 国产OS?中文CPU?(1213) JAVA教程 第一讲 Java语言概述(2)(796) JAVA教程 第三讲 Java语言中的面向对象特性(1)(785) vb的10个小技巧 (772) 学编程的人不能不看的好文章 (745) JAVASCRIPT简介 (736) 绝对不知道你的浏览器还有这个功能!!(722) JAVA对象入门第1章 对象入门(719) 给初学编程者的忠告 (702) JavaScript 对象与数组参考大全(650) JAVA教程 第三讲 Java语言中的面向对象特性(2)(631) JAVA教程 第三讲 Java语言中的面向对象特性(3)(587) VB开发Windows环境下的串行通信程序(560) SQL转ACCESS解决自动编号问题(531) JAVA教程 Java语言基础知识(452) JAVA教程 第二讲 Java语言基础知识(1)(364) DHTML参考手册(一)(210) [精]5分钟编写一个ASP论坛(99) Cookies常用命令简介(99) RegExp正则表达示用法(3) 首页 前页 后页 尾页 本站推荐: | VB开发Windows环境下的串行通信程序 VB开发Windows环境下的串行通信程序 发布时间:2004-7-14 随着Windows在国内的普及,特别是Windows95的推出,越来越多的微机用户转向了Windows操作系统。不过Windows应用软件的开发对于一般工程技术领域的技术人员来说并非易事,不但Windows的消息循环机制不易理解,而且要开发一个功能强、界面美观的应用软件,其编程和调试的工作量是非常大的。许多并非搞软件出身的工程技术人员对Windows编程望而生畏。然而使用微软的VisualBasic来开发这些方面的Windows应用软件就十分方便,一般工程技术人员易于掌握,设计软件界面非常方便,编程工作量相对较小,只需进行主要应用功能的编程和少量界面控制的编程。本文介绍了笔者使用VB在串行通信编程方面的一些收获,由于在报刊杂志上对Windows下串行通信编程的介绍多为用MicrosoftC++或BorlandC++,故笔者愿意就VB在该方面的应用与大家探讨。对于采用了RS-232接口进行串行通信的计算机测控系统软件的开发,具有一定的参考价值。 在该系统中使用了80C31单片机作为下位机采集惯性敏感部件的测量数据,经过一定的预处理后通过RS-232串行口将数据传送给上位PC机。在PC机上Windows环境下运行检测软件,接受串行口传来的数据,进行数据处理、显示、存盘等。数据处理结果以表格形式打印输出。 在VB3.0中,有许多专业厂商提供用户定制的控件(Customcontrol),这些控件以.VBX为后缀,其中MSCOMM.VBX即是用于串行通信的控件。对于VB3.0,启动后该控件就包含于控件工具箱(toolbox)内,否则可以通过File|AddFile将该控件加入控件工具箱。然后就可以利用该控件进行串行通信的程序设计。 下面举一个简单的例子,说明了如何进行串行通信的程序设计,该程序在Windows95环境下,使用VB3.0已经实现: 1.先建立一个项目文件,其控件如下表所示: 2.代码如下: SubForm_Load() comm1.CommPort=1‘使用串行口1 ’波特率9600,偶校验,8个数据位,1个停止位。 comm1.Settings=“9600,E,8,1” 当使用Comm1.Input时,每次从接收缓冲区取一个字节。 comm1.InputLen=1 timer1.interval=20‘定时器的中断间隔为20ms,用于更新显示时间。 EndSub SubcmdComm_Click() Dimechoch%‘命令变量 Staticmaxf01&,maxf02&,minf01&,minf02&‘最大值,最小值 OnErrorResumeNext‘简单的错误处理 maxf01&=maxf02&=0‘初始化变量 minf01&=32767 minf02&=32767 label2.Caption=comm1.Settings‘显示串行口的设置。 Ifcmdcomm.Caption=“通信”Then‘若当前命令按扭的提示为“通信”则开始发送和 cmdcomm.Caption=“停止”‘接受数据,并将命令按扭提示改为“停止”,以 cmdexit.Enabled=False‘允许停止通信。使退出命令在通信中失效。 IfNotcomm1.PortOpenThen‘若串行口没有打开,则打开串行口 comm1.PortOpen=True EndIf Ifcomm1.PortOpenThen Ifecho.Text<>“”Then‘若命令输入框不空,则将其转换为十六进制数值 echoch%=Val(“&H”+echo.Text) Else echoch%=&HF0‘否则确省命令为F0H EndIf comm1.Output=Chr(echoch%)‘向串行口写入一字节命令,由WINDOWS自 EndIf‘动将命令发出 label3.Caption=Hex(echoch%)‘显示刚发出的命令 DoWhilecomm1.PortOpen Ifcomm1.InBufferCount>0Then‘若comm1.InBufferCount>0表示接受缓冲 ch$=comm1.Input‘区有数据,并读出一个字符, IfAsc(ch$)=echoch%Then‘若与发出的命令相同,则退出当前循环 ExitDo‘进入下一循环 EndIf Else comm1.Output=Chr(echoch%)‘否则继续向下位机发命令,通知下位机 EndIf‘送数据 dummy=DoEvents()‘让系统处理其他消息 Loop ‘下位机接受到正确的命令,并回发命令正确时,进入下面循环 i=1 DoWhilecomm1.PortOpen Ifcomm1.InBufferCount>5Then ch$=comm1.Input DoWhileAsc(ch$)<>echoch%‘以命令字节同步测试数据 ch$=comm1.Input Loop ch1$=comm1.Input‘从WINDOWS串行数据接受缓冲区读测试数据 ch2$=comm1.Input ch3$=comm1.Input ch4$=comm1.Input newf01&=CLng(CLng(Asc(ch2$))*16*16+Asc(ch1$))‘合并为一个整数 newf02&=CLng(CLng(Asc(ch4$))*16*16+Asc(ch3$)) ifnewf01&>maxf01&Then‘判断最大值,最小值 maxf01&=newf01& EndIf Ifnewf01& minf01&=newf01& EndIf Ifnewf02&>maxf02&Then maxf02&=newf02& EndIf Ifnewf02& minf02&=newf02& EndIf labf01.Caption=Str(newf01&)‘显示数据 labf02.Caption=Str(newf02&) labmaxf01.Caption=Str(maxf01&) labminf01.Caption=Str(minf01&) labmaxf02.Caption=Str(maxf02&) labminf02.Caption=Str(minf02&) Else comm1.Output=Chr(echoch%) EndIf dummy=DoEvents() Loop Else‘在通讯过程中,按下cmdCOMM按钮则停止通信,发出停止测试 cmdcomm.Caption=“通信”‘命令,关闭串行口,使退出按钮有效。 comm1.Output=Chr(&H5F) comm1.PortOpen=False cmdexit.Enabled=True EndIf EndSub SubcmdExit_Click() Ifcomm1.PortOpenThen‘确认关闭串行口 comm1.PortOpen=False EndIf End‘终止整个程序 EndSub SubTimer1_Timer()‘更新显示时间 Iflabtime.Caption<>Time&Then labtime.Caption=Time$ EndIf EndSub 3.程序说明: a.上述程序的通信协议为:波特率9600,偶校验,8个数据位,1个停止位。由上位机发送开始测试命令,下位机接收到命令后每隔500ms向上位机发送检测到的数据。每次发送5个字节,第一个字节为下位机接受到的命令,第二三字节为16Byte的值,第四五字节为16Byte的值。上位机循环接受并处理和显示数据; b.由于在控制软件中,串行通讯发送和接受的数据多为十六进制,故在命令输入时为十六进制数,在程序中通过echoch%=Val(“&H”+echo.Text)将输入的echo.Text转换为十六进制数,并赋给变量echoch%。而在通过串行口发送时comm1.Output要求接受字符型变量,故通过语句comm1.Output=Chr(echoch%)实现; c.接受数据时,每次要判断第一个字节是否为发出的命令,只有是后面4个字节才为正确的数据,否则查看下一字节。通过设置COMM1.InputLen=1来实现每次从接受缓冲区内读取一个字节; d.当退出程序时,一定要关闭串行口,通过comm1.PortOpen=False完成; e.如果需要上位机定时查询下位机,可以将串行通讯在定时器Timer1-Timer事件中进行; f.要实现完善的功能,必须进一步改善程序,甚至要用到WindowsAPI、OLE等,上述程序只是一个简单的例子; 上面介绍了笔者在使用VB开发Windows环境下测控软件的一点收获,笔者使用上述原理开发了一个界面友好、功能全面、使用方便的卫星控制系统惯性敏感部件检测软件,实际使用效果良好,提高了工作效率,甚至实现了测试和数据处理的自动化。 WIN95 Visual Basic5.0( 以 下 简 称VB) 以 其 简 单 易 学、32 位 面 向 对 象 的 程 序 设 计 等 特 点, 倍 受 广 大 计 算 机 开 发 者 的 青 睐, 已 广 泛 地 应 用 于 各 个 领 域; 在 实 时 监 测 系 统 中 串 行 端 口 通 信 是 一 项 基 础 功 能, 因 此 我 们 使 用VB5 编 写 了 实 时 水 库 水 文 自 动 监 测 系 统 的 后 台 机 软 件。 本 文 就Windows 95 环 境 中 采 用VB5 设 计 串 行 端 口 通 信 程 序 进 行 讨 论 并 给 出 实 例。 一 般 用VB 开 发 串 行 通 信 程 序 有 两 种 方 法: 一 是 利 用Windows 的 通 信API 函 数; 另 一 种 是 采 用VB 标 准 控 件Mscomm 来 实 现。 Windows 95 的 通 信API Windows 95 中 的 串 口 通 信API 函 数 不 同 于Windows3.x 中 的OpenComm、CloseComm、ReadComm、WriteComm, 而 是 采 用 硬 件 与 文 件 通 用 的 函 数CreateFile、ReadFile、WriteFile、CloseHandle, 该 类 函 数 更 具 有 一 般 性, 并 且 可 以 用EscapeCommFunction 函 数 实 现 底 层 硬 件 操 作, 比 如:SETXOFF、 CLRDTR 等。 利 用API 编 写 串 口 通 信 程 序 较 为 复 杂, 需 要 掌 握 大 量 通 信 知 识, 其 优 点 是 可 实 现 的 功 能 更 丰 富、 应 用 面 更 广 泛, 更 适 合 于 编 写 较 为 复 杂 的 低 层 次 通 信 程 序。 采 用 这 种 方 法 编 写 串 行 端 口 通 信 程 序 一 般 可 分 为 以 下 几 个 过 程: 1. 初 始 化 串 行 端 口 首 先 用CreateFile 函 数 打 开 指 定 串 口, 置 参 数 中 访 问 类 型 为GENERIC_READ |GENERIC_WRITE、 共 享 模 式 为0、 创 建 标 志 为OPEN_EXISTING、 模 板 句 柄 为NULL。 2. 配 置 串 口 Windows 95 的 串 口 配 置 比Windows 3.x 较 为 复 杂, 但 其 功 能 更 强 大, 对 一 般 程 序 可 使 用CommConfigDialog 函 数 以 对 话 框 方 式 设 置 波 特 率、 数 据 位、 奇 偶 校 验、 停 止 位 和 流 控 制 方 式, 并 且 可 以 恢 复 缺 省 值。 3. 超 时 控 制 为 了 防 止 意 外 情 况 使 串 口 读 写 无 休 止 地 等 待,Windows 95 提 供 了 超 时 设 置, 这 是 由COMMTIMEOUTS 结 构 定 义 的, 通 过 调 用GetCcommTimeOuts 函 数 获 得 当 前 的 设 置, 用SetCommTimeOuts 函 数 来 完 成 设 置。 4. 数 据 传 输 读 写 串 行 端 口 与 读 写 文 件 采 用 的 函 数 相 同, 即ReadFile、WriteFile, 读 写 操 作 可 分 四 种 方 式: 查 询 方 式、 同 步I/O、 异 步( 后 台)I/O 和 事 件 驱 动I/O。 5. 关 闭 串 口 程 序 的 终 止 可 以 自 动 关 闭 串 口, 也 可 用 函 数CloseHandle(), 以 便 释 放 所 独 占 资 源。 VB 通 信 控 件Mscomm Mscomm 控 件 提 供 了 功 能 完 善 的 串 口 数 据 的 发 送 和 接 收 功 能,Mscomm 控 件 具 有 两 种 处 理 方 式: 1 事 件 驱 动 方 式: 由Mscomm 控 件 的OnComm 事 件 捕 获 并 处 理 通 信 错 误 及 事 件;2 查 询 方 式: 通 过 检 查CommEvent 属 性 的 值 来 判 断 事 件 和 错 误。 Mscomm 控 件 的 通 信 功 能 实 现, 实 际 上 是 调 用 了API 函 数, 而API 函 数 是 由Comm.drv 解 释 并 传 给 设 备 驱 动 程 序 执 行 的, 对 于VB 程 序 开 发 者 只 需 知 道Mscomm 控 件 的 属 性 和 事 件 的 用 法 即 可 以 实 现 串 口 的 操 作。 以 下 是Mscomm 控 件 的 主 要 属 性 和 方 法: 1)CommPort: 设 置 或 返 回 串 行 端 口 号, 其 取 值 范 围 为1 ~99, 缺 省 为1。 2) Setting 设 置 或 返 回 串 行 端 口 的 波 特 率、 奇 偶 校 验 位、 数 据 位 数、 停 止 位。 如:Mscomm.Setting=“9600,N,8,1”。 3)PortOpen: 打 开 或 关 闭 串 行 端 口, 格 式 为:Mscomm.PortOpen={TRUE|FALSE}。 4) InBufferSize: 设 置 或 返 回 接 收 缓 冲 区 的 大 小, 缺 省 为1024 字 节。 5) InBufferCount: 返 回 接 收 缓 冲 区 内 的 等 待 读 取 的 字 节 个 数, 可 通 过 设 置 该 属 性 为0 来 清 除 接 收 缓 冲 区。 6) RThreshold: 该 属 性 为 一 阀 值, 它 确 定 当 接 收 缓 冲 区 内 字 节 个 数 达 到 或 超 过 该 值 后 就 产 生 代 码 为MSCOMM_EV_RECEIVE 的OnComm 事 件。 7) InputLen: 设 置 或 返 回 接 收 缓 冲 区 内 用Input 读 入 的 个 数。 若 取0, 则INPUT 读 取 整 个 缓 冲 区 的 内 容。 8) Input: 该 属 性 表 示 从 接 收 缓 冲 区 移 走 一 串 字 符。 9) OutBufferSize: 设 置 或 返 回 发 送 缓 冲 区, 缺 省 为512 字 节。 10) OutBufferCounter: 返 回 发 送 缓 冲 区 内 等 待 发 送 的 字 符 数, 可 用 来 清 空 缓 冲 区。 11) Output: 向 发 送 缓 冲 区 传 送 一 字 符 串。 12) EOFEnable: 若 置TRUE, 则 当 输 入 中 出 现EOF, 就 停 止 输 入 并 产 生OnComm 事 件。 如 果 在 通 信 过 程 中 发 生 错 误 或 事 件, 就 会 引 发OnComm 事 件 并 且 改 变 属 性 值, 由CommEvent 属 性 代 码 反 映 错 误 类 型, 在 通 信 程 序 的 设 计 中 可 根 据 该 属 性 值 来 执 行 不 同 的 操 作, 以 下 是 部 分 属 性 常 数 值 及 其 含 义: 1)ComEvSend: 其 值 为1, 发 送 缓 冲 区 的 内 容 少 于SThreshold 指 定 的 值。 2) ComEvReceive: 其 值 为2, 接 收 缓 冲 区 内 字 符 数 达 到 RThreshold 值, 该 事 件 在 缓 冲 区 中 数 据 被 移 走 前 将 持 续 产 生。 3) ComEventFrame: 其 值 为1004, 硬 件 检 测 到 帧 错 误。 4) ComEventRxOver: 其 值 为1008, 接 收 缓 冲 区 溢 出。 5) ComEventTxFull: 其 值 为1010, 发 送 缓 冲 区 溢 出。 6) ComEventRxParity: 其 值 为1009, 奇 偶 校 验。 7) ComEvEOF: 其 值 为7, 接 收 数 据 中 出 现 文 件 结 束(ASCII 码 为 26) 字 符。 程 序 样 例 采 用Mscomm 控 件 实 现 串 口 通 信 时, 首 先 添 加 一Mscomm 控 件 到 窗 体 中, 该 控 件 一 般 不 在 通 用 工 具 窗 口 中, 而 是 需 通 过 菜 单 项“ 工 程(P) → 部 件(O)” 进 入 选 择 窗 口, 在 控 件tab 页 中 选 取Microsoft Comm Control 5.0 , 此 时 工 具 窗 口 中 出 现Mscomm 图 标, 即 可 被 使 用。 以 下 是 事 件 驱 动 方 式 的 接 收 程 序 的 主 要 部 分: Private Sub getdatafromserial_Click() CommonDialog1.InitDir = “c:\temp" CommonDialog1.ShowSave mainfrm.MSComm1.CommPort=1 hfile = FreeFile ’ 打 开 存 储 接 收 数 据 的 文 件 Open CommonDialog1.filename For Output As #hfile ’ 设 接 收 缓 冲 区 的 大 小, 可 按 量 确 定 mainfrm.MSComm1.InBufferSize = 4096 If Not mainfrm.MSComm1.PortOpen Then ’ 打 开 串 口 -- mainfrm.MSComm1.PortOpen = True End If If Err Then MsgBox “Communcation port cannot be opened!!" ’ 清 接 收 缓 冲 区 mainfrm.MSComm1.InBufferCount = 0 ’ 设 一 次 读 入 的 长 度, 可 根 据 数 据 格 式 设 置 mainfrm.MSComm1.InputLen = 77 ’ 设 置 接 收 事 件 触 发 的 阀 值 mainfrm.MSComm1.RThreshold = 77 counter = Timer + 10 Do If Timer > counter Then mainfrm.Label1.Caption = “ 正 在 通 信......" mainfrm.Label1.Refresh counter = Timer + 10 End If DoEvents Loop End Sub 以 下 为 事 件 处 理 子 程 序,flag 为 一 静 态 变 量 记 录 读 取 次 数, 以 便 改 变 接 收 数 据 的 长 度, 读 者 可 根 据 实 际 需 要 添 加 其 它 处 理 内 容: Private Sub MSComm1_OnComm() Select Case MSComm1.CommEvent Case comEvReceive If flag > 246 Then MSComm1.InputLen = 0: MSComm1.RThreshold = 32 End If buffer = MSComm1.Input temp = buffer Print #hfile, temp counter = Timer + 10 Do While Timer > counter Do Events Loop flag = flag + 1 Case comEvEOF EVMsg $ = “ 检 测 到 文 件 结 尾!!!" Case comFrame ERMsg $ = “ 帧 出 错!!!" Case comRxParity ERMsg $ = “ 奇 偶 错!!!" End Select If Len(EVMsg $) Then Text1.Text = “Status: " & EVMsg $ ElseIf Len(ERMsg $) Then Text1.Text = “Status: " & ERMsg $ Beep Ret = MsgBox(ERMsg $, 1, “Click Cancel to quit, OK to ignore.") MSComm1.PortOpen = False End If End Sub vb开发通信软件 一、PC串行通信程序机制 常用的PC串行通信程序大多利用BIOSINT14H中断,以查询I/O方式完成异步串行通信。 Windows系统提供中断方式驱动的串行通信驱动程序COMM.DRV。通信程序无需直接对串行端口进行操作,而是通过驱动程序这一编程接口进行间接操作。 Windows操作系统中,串行通信采用“事件通知”方式,支持数据按块传送。进行通信时,Windows开辟一个用户定义的输入输出缓冲区,每接收一个字符就产生一个低级硬件中断,串行驱动程序立即取得控制权,并将字符放入输入数据缓冲区,然后将控制权返还正在运行的应用程序。如果输入数据缓冲区满了,驱动程序用当前定义的流控制机制通知发送方停止发送数据。发送数据也采用类似的处理方式,应用程序将需要发送的数据放入输出数据缓冲区,串口每发送一个字符就产生一个低级硬件中断。 二、PC串行口远程通信的硬件配置 串行通信数据链中,计算机一端称为DTE,即数据终端设备;调制解调器一端称为DCE,即数据通信设备。PC串行通信的硬件连接方式分为零Modem连接和Modem连接。 零Modem连接即直接用调制解调器电缆将两台设备连接起来,Modem连接则通过DCE(Modem)将两台PC连接起来。 零Modem连接用于距离15m内两台DTE或DCE设备之间的连接。而Modem连接则通过电话网或专线用于长距离的通信。 TXD和RXD信号线用于计算机和Modem间传输数据信息;RTS从计算机端发送信号到Modem,表示希望把数据传给Modem,若Modem能接收这个数据,它将发送CTS信号给计算机;DTR从计算机端发送信号到Modem,表示计算机已作好通信准备,Modem将DTR信号作为初始化自己的信号,然后给计算机回送数据设置就绪信号DSR;当本地Modem接收到远地Modem的呼叫,则发送RING信号给计算机;Modem应答呼叫后,发送数据载波检测DCD信号到计算机,表示已建立连接。 Modem的工作状态分为命令状态和在线状态。处于命令状态时,Modem对串口发送的信息进行解释,可通过PC串口向Modem发送AT命令对其进行初始化、设置和操作。 例如,初始化命令为:“ATQOV1WOSOΚ1&C1&D2&YO&WO”,其含义为: QO:返回结果码; V1:以字符形式显示结果码; WO:不返回协商进程结果码; SOΚ1:振铃一次,即应答; &C1:追踪数据载波信号CD; &D2当DTR从开到关时,Modem挂机进入命令状态; &YO:Modem上电时重新调出用户方案; &WO:将以上设置存为动态设置用户方案0; 一旦本地Modem与远地Modem建立连接,Modem即处于在线状态,可进行数据传输。此时,Modem不响应AT命令,直接传送所收到的数据。 三、Modem连接远程通信软件的编制 通信过程中大部分的工作由串行通信驱动软件承担。 本文软件的运行环境为AST+4/66d,Hayes公司的ACCURA144+FAX144Modem,Windows3.2,VB3.0专业版。VB3.0专业版中提供了一个MSCOMM.VBX通信控件。它使用户能很方便地通过对控件属性的设置、检测,访问串行通信驱动程序的大多数特性,而不必考虑其实现细节。该控件为“事件驱动”,只响应“OnComm”事件,该事件可对已发生的事件或错误进行处理,与CommEvent属性紧密相关。 通信软件、通信驱动软件和Modem之间的通信关系 以下程序实现了通信的基本过程。包括初始化串口和Modem,上位机拨号呼叫下位机,下位机应答并开始定时传输数据,挂机停止传输等功能。 VB3.0编制的通信软件清单如下: 上位机控件清单: 控件名称 属性 Form1Form1Caption ″上位机通信″ MsComm comm1 CommandButton1CallCaption ″拨号″ CommandButton2hangCaption ″挂机″ CommandButton3ExitCaption ″退出″ 下位机控件清单 控件名称 属性 Form1Form1Caption ″下位机通信″ MsComm comm1 CommandButton1hangCaption ″挂机″ CommandButton2ExitCaption ″退出″ Timer1Timer1Interval 3000 Text(i)Text(i) 1.串口初始化、设置程序 在程序初始化时,先对串口初始化。因为使用RTS/CTS握手信号的硬件设备只有RTS信号置为高才能接收数据,所以需将MSCOMM通信控件的RTSenable属性设为TRUE。由于Modem在处于命令状态时,通过串口发送的命令以及命令结果均会回显在输入缓冲区中,因此在进入在线状态前,禁止产生EV-RECEIVE事件,避免数据误处理。 由于Windows是多任务系统,在进行数据收发循环处理时,应调用DOEVENTS事件,将控制权交还系统,允许Windows执行其他任务。但应注意,在处理OnComm事件时小心使用DOEVENTS,避免系统又产生OnComm事件,造成嵌套,出现堆栈溢出错误。 Sub Form-Load() comm1.CommportΚ1′COM1口通信 comm1.SettingsΚ″9600,N,8,1″′波特率9600,无校验,8位数据位1位停止位 comm1.OutBufferSizeΚOUTPACK′设置输出缓冲区大小 comm1.InBufferSizeΚINPACK′设置输入缓冲区大小 comm1.InputLenΚ1′每次从输入缓冲区中取一个字符 comm1.RTSenableΚ-1′RTS信号为高 comm1.RthresholdΚ0′不产生MSCOMM-EV-RECEIVE事件 comm1.PortOpenΚ-1′打开串口 cdΚcomm1.CDHolding′取载波检测信号线原始状态 comm1.outputΚ″ATQOV1WOSOΚ1&C1&D2&YOWO″′初始化Modem Do DoEventsLoopUntilcomm1.OutBufferCountΚ0 End Sub 2.上位机拨号呼叫下位机 SubCallcom-Click() Comm1.OutPutΚ″ATDT″&Phonnum$&chr$(13)′向Modem发拨号命令 Do DoEventsLoopUntilcomm1.OutBufferCountΚ0 End Sub 3.下位机Modem应答,连通后开始定时传输数据 下位机检测CD,判断是否连通: Sub Comm1-OnComm() Select Casecomm1.CommEvent Case5 ′MSCOMM-EV-CD Timer1.EnabledΚ-1′启动定时器 End Select End Sub VB传送定长字符串,数据接收处理相对简单。但在发送实时数据时,若将数据转换成定长字符串,这样会大大降低传输效率。在接收端,通知程序从输入缓冲区中取字符有两种方法:一是用轮询方法循环判断InBufferCount是否为0;另外就是利用Rthreshold属性触发“OnComm”事件及“CommEvent”属性中EV-RECEIVE事件。当Rthreshold的值不为0时,允许产生EV-RECEIVE事件。该属性设置和返回在通信控件设定CommEvent特性为接收和产生OnComm事件之前要接收的字符数。VB传送变长字符串时,接收端的Rthreshold值要作相应的改变,以确保接收数据及时准确。 下位机定时发送字符串“strin3$ΚFormat$(Len(strin1$),″0000″)&chr$(8)&strin2$”。strin1$为当前字符串,strin2$为上一字符串。上位机根据接收strin3$中Len(strin1$),相应改变RthresholdΚLen(strin1$)+4。这样,通过提前发送字符串长度,改变Rthreshold值可实现发送变长数据。 Windows串行通信驱动程序的事件驱动特性仍有不稳定的缺陷。如InputLenΚ0时,有可能取出不完整的数据。为保证可靠,采取降低处理速率的方法,保证下位机发送的数据流完整地进入输入缓冲区。设InputLenΚ1,即每次从缓冲区中取一个字符。也可采用轮询方法,定时检测输入缓冲区。下位机定时发送数据: Sub Timer1-Timer() If comm1.CDHoldingΙΛcdThen str1$-text1(i).Text strin2$Κstrin1$′上一字符串 strin1$Κstr1$′当前字符串 strin3$ΚFormat$(Len(strin1$),″0000″)&chr$(8)&strin2$ ′传送当前字符串长度,以及上一字符串内容 com m1.OutPutΚstrin3$ Do DoEventsLoopUntilcomm1.OutBufferCountΚ0 Else Timer1.EnabledΚ0 End If End Sub 上位机检测CD状态,判断是否连通、并接收处理数据。 Sub Comm1-OnComm() Select Case comm1.CommEvent Case5 ′MSCOMM-EV-CD检测CD状态,判断是否连通 comm1.InBufferCountΚ0′清输入缓冲区 comm1.RThresholdΚ4′当输入缓冲区中有五个字符, Case2′MSCOMM-EV-RECEIVE产生EV-RECEIVE事件,接收处理数据 Do DoEvents Ifcomm1.InBufferCountThen′循环从缓冲区中取数据 str1$Κstr1$+comm1.Input Else Exit Do End If Loop len2Κ1en1′当前字符串长度 len1ΚVa1(Left$(str1$,5))′即将发送的字符串长度 comm1.RThresholdΚlen1+4 strin$ΚRight$(str1$,len2)′数据处理 …… End Select str1$Κ″″ End Sub 4.根据设置的AT命令“&D2”,当置DTR信号为低时,Modem挂机进入命令状态。也可通过串口输出““+++ATH”+chr$(13)”字符串挂机。 Sub Hang-click() If comm1.CDHoldingΙΛcdThen′检测CD,判断是否挂机 comm1.DTRenableΚ0 comm1.DTRenableΚ-1′置DTR信号为高,为下一次通信准备 End If End Sub 5.退出程序时,一定要关闭串口 Sub Exitcomm() comm1.PortOpenΚfalse End End Sub 四、Windows通信机制和VB3.0通信控件潜在缺陷 在通信软件编制过程中,我们发现Windows下通信机制采用的“事件驱动”在实际运行中不稳定。如在文件传输过程中,误码和数据丢失的情况时有发生;若串口波特率过高,会产生无法通信或在通信过程中随机挂机的情况。这主要是由于Windows本身通信机制和通信线路介质及质量的影响。为保证数据传输稳定可靠,可采用通信协议如XModem-CRC或YModem。在MSCOMM.VBX通信控件中,Rthreshold属性值大小与输入缓冲区InBufferSize大小有关,当Rthreshold值较接近InBufferSize值时,有可能不产生EV-RECEIVE事件,为保证产生该事件,可将InBufferSize值取得较大 使用VB开发Windows环境下的串行通信程序 随着Windows在国内的普及,特别是Windows95的推出,越来越多的微机用户转向了Windows操作系统。不过Windows应用软件的开发对于一般工程技术领域的技术人员来说并非易事,不但Windows的消息循环机制不易理解,而且要开发一个功能强、界面美观的应用软件,其编程和调试的工作量是非常大的。许多并非搞软件出身的工程技术人员对Windows编程望而生畏。然而使用微软的VisualBasic来开发这些方面的Windows应用软件就十分方便,一般工程技术人员易于掌握,设计软件界面非常方便,编程工作量相对较小,只需进行主要应用功能的编程和少量界面控制的编程。本文介绍了笔者使用VB在串行通信编程方面的一些收获,由于在报刊杂志上对Windows下串行通信编程的介绍多为用MicrosoftC++或BorlandC++,故笔者愿意就VB在该方面的应用与大家探讨。对于采用了RS-232接口进行串行通信的计算机测控系统软件的开发,具有一定的参考价值。 在该系统中使用了80C31单片机作为下位机采集惯性敏感部件的测量数据,经过一定的预处理后通过RS-232串行口将数据传送给上位PC机。在PC机上Windows环境下运行检测软件,接受串行口传来的数据,进行数据处理、显示、存盘等。数据处理结果以表格形式打印输出。 在VB3.0中,有许多专业厂商提供用户定制的控件(Customcontrol),这些控件以.VBX为后缀,其中MSCOMM.VBX即是用于串行通信的控件。对于VB3.0,启动后该控件就包含于控件工具箱(toolbox)内,否则可以通过File|AddFile将该控件加入控件工具箱。然后就可以利用该控件进行串行通信的程序设计。 下面举一个简单的例子,说明了如何进行串行通信的程序设计,该程序在Windows95环境下,使用VB3.0已经实现: 1.先建立一个项目文件,其控件如下表所示: 2.代码如下: SubForm_Load() comm1.CommPort=1‘使用串行口1 "波特率9600,偶校验,8个数据位,1个停止位。 comm1.Settings=“9600,E,8,1” 当使用Comm1.Input时,每次从接收缓冲区取一个字节。 comm1.InputLen=1 timer1.interval=20‘定时器的中断间隔为20ms,用于更新显示时间。 EndSub SubcmdComm_Click() Dimechoch%‘命令变量 Staticmaxf01&,maxf02&,minf01&,minf02&‘最大值,最小值 OnErrorResumeNext‘简单的错误处理 maxf01&=maxf02&=0‘初始化变量 minf01&=32767 minf02&=32767 label2.Caption=comm1.Settings‘显示串行口的设置。 Ifcmdcomm.Caption=“通信”Then‘若当前命令按扭的提示为“通信”则开始发送和 cmdcomm.Caption=“停止”‘接受数据,并将命令按扭提示改为“停止”,以 cmdexit.Enabled=False‘允许停止通信。使退出命令在通信中失效。 IfNotcomm1.PortOpenThen‘若串行口没有打开,则打开串行口 comm1.PortOpen=True EndIf Ifcomm1.PortOpenThen Ifecho.Text<>“”Then‘若命令输入框不空,则将其转换为十六进制数值 echoch%=Val(“&H”+echo.Text) Else echoch%=&HF0‘否则确省命令为F0H EndIf comm1.Output=Chr(echoch%)‘向串行口写入一字节命令,由WINDOWS自 EndIf‘动将命令发出 label3.Caption=Hex(echoch%)‘显示刚发出的命令 DoWhilecomm1.PortOpen Ifcomm1.InBufferCount>0Then‘若comm1.InBufferCount>0表示接受缓冲 ch$=comm1.Input‘区有数据,并读出一个字符, IfAsc(ch$)=echoch%Then‘若与发出的命令相同,则退出当前循环 ExitDo‘进入下一循环 EndIf Else comm1.Output=Chr(echoch%)‘否则继续向下位机发命令,通知下位机 EndIf‘送数据 dummy=DoEvents()‘让系统处理其他消息 Loop ‘下位机接受到正确的命令,并回发命令正确时,进入下面循环 i=1 DoWhilecomm1.PortOpen Ifcomm1.InBufferCount>5Then ch$=comm1.Input DoWhileAsc(ch$)<>echoch%‘以命令字节同步测试数据 ch$=comm1.Input Loop ch1$=comm1.Input‘从WINDOWS串行数据接受缓冲区读测试数据 ch2$=comm1.Input ch3$=comm1.Input ch4$=comm1.Input newf01&=CLng(CLng(Asc(ch2$))*16*16+Asc(ch1$))‘合并为一个整数 newf02&=CLng(CLng(Asc(ch4$))*16*16+Asc(ch3$)) ifnewf01&>maxf01&Then‘判断最大值,最小值 maxf01&=newf01& EndIf Ifnewf01& minf01&=newf01& EndIf Ifnewf02&>maxf02&Then maxf02&=newf02& EndIf Ifnewf02& minf02&=newf02& EndIf labf01.Caption=Str(newf01&)‘显示数据 labf02.Caption=Str(newf02&) labmaxf01.Caption=Str(maxf01&) labminf01.Caption=Str(minf01&) labmaxf02.Caption=Str(maxf02&) labminf02.Caption=Str(minf02&) Else comm1.Output=Chr(echoch%) EndIf dummy=DoEvents() Loop Else‘在通讯过程中,按下cmdCOMM按钮则停止通信,发出停止测试 cmdcomm.Caption=“通信”‘命令,关闭串行口,使退出按钮有效。 comm1.Output=Chr(&H5F) comm1.PortOpen=False cmdexit.Enabled=True EndIf EndSub SubcmdExit_Click() Ifcomm1.PortOpenThen‘确认关闭串行口 comm1.PortOpen=False EndIf End‘终止整个程序 EndSub SubTimer1_Timer()‘更新显示时间 Iflabtime.Caption<>Time&Then labtime.Caption=Time$ EndIf EndSub 3.程序说明: a.上述程序的通信协议为:波特率9600,偶校验,8个数据位,1个停止位。由上位机发送开始测试命令,下位机接收到命令后每隔500ms向上位机发送检测到的数据。每次发送5个字节,第一个字节为下位机接受到的命令,第二三字节为16Byte的值,第四五字节为16Byte的值。上位机循环接受并处理和显示数据; b.由于在控制软件中,串行通讯发送和接受的数据多为十六进制,故在命令输入时为十六进制数,在程序中通过echoch%=Val(“&H”+echo.Text)将输入的echo.Text转换为十六进制数,并赋给变量echoch%。而在通过串行口发送时comm1.Output要求接受字符型变量,故通过语句comm1.Output=Chr(echoch%)实现; c.接受数据时,每次要判断第一个字节是否为发出的命令,只有是后面4个字节才为正确的数据,否则查看下一字节。通过设置COMM1.InputLen=1来实现每次从接受缓冲区内读取一个字节; d.当退出程序时,一定要关闭串行口,通过comm1.PortOpen=False完成; e.如果需要上位机定时查询下位机,可以将串行通讯在定时器Timer1-Timer事件中进行; f.要实现完善的功能,必须进一步改善程序,甚至要用到WindowsAPI、OLE等,上述程序只是一个简单的例子; 上面介绍了笔者在使用VB开发Windows环境下测控软件的一点收获,笔者使用上述原理开发了一个界面友好、功能全面、使用方便的卫星控制系统惯性敏感部件检测软件,实际使用效果良好,提高了工作效率,甚至实现了测试和数据处理的自动化。 1、 本站不保证以上观点正确,就算是本站原创作品,本站也不保证内容正确。 2、如果您拥有本文版权,并且不想在本站转载,请书面通知本站立即删除并且向您公开道歉! |
本站协议 |
版权信息 |
关于我们 |
本站地图 |
营业执照 |
发票说明 |
付款方式 |
联系方式
深圳市宝安区西乡五壹电子商行——粤ICP备16073394号-1;地址:深圳西乡河西四坊183号;邮编:518102 E-mail:51dz$163.com($改为@);Tel:(0755)27947428 工作时间:9:30-12:00和13:30-17:30和18:30-20:30,无人接听时可以再打手机13537585389 |