说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

利用Visual Basic实现无线通讯

HTML文档下载 WORD文档下载 PDF文档下载
利用Visual Basic实现无线通讯
中科院空间中心 姜棣昭

  一、概述
  Visual Basic 是Mcrosoft公司推出的强有力的系列开发软件之一,而且以其实用、方便、快捷、开发周期短、广泛而强大的功能越来越被广大编程人员所亲赖,广为流传,似乎有些专业的编程人员放弃了Visaul C++ 而改用了Visaul Basic之类的RAD编程工具,尽管Visaul C++在灵活性、代码紧凑、运行速度快及底层开发等方面Visaul Basic无法比拟的,但编写C++应用程序过长的调试和开发周期确实有点不适应当今的应用程序开发环境。
  在Visaul Basic开发工具中提供了大量的控件(或称控制、组件)供编程人员使用,可以方便的利用这些组件中的属性、方法、语言等以事件驱动方式开发应用程序,还可以利用WINDOWS SDK中的API中的应用程序接口等工具开发应用程序。VB还自带一个控件开发软件包CDK,利用CDK可以开发自己需要的Controls 。在通讯问题中我们可以使用VB提供的通讯控件或调用WINDOWS API通讯函数。

  二、 VB串行通讯
  利用VB开发通信程序主要的方法有两种,一是利用VB本身提供的控件(CONTRALS),另一种方法是利用WINDOWS API应用程序接口,WINDOWS API 主要提供了三个动态连接库KERNEL.EXE、USER.EXE、GDI.EXE供开发人员调用,其中KERNEL.EXE 主要包括一些底层操作函数,完成一些资源管理、任务、内存等操作,USER.EXE包含了一些与WINDOWS管理有关的函数,如通讯、菜单、消息、光标、插入符、计时器以及绝大多数非显示函数,GDI.EXE图形设备接口库,主要内容为与设备输出有关的函数。和串口通讯有关系的函数BuilidCommDCB、ClearCommBreak、SetCommBreak、FlushComm、GetCommError、GetCommState、WriteComm、ReadComm、SetCommState、CloseComm等均在 \Windows\system 子目录下的USER.EXE动态连接库中,在VB调用之前应该先在全局变量定义处声明API通讯函数、定义常量。
  在我们的实践中,用VB 控件实现通讯的方法比调用SDK的API动态连接库的方法更加方便、快捷,而且用较少的代码可以实现相同的功能,这就是用VB 控件实现通讯的优点所在,下面主要介绍一下利用VB 控件实现无线通讯的问题。
  在VB的控件工具箱中,提供了一个使用非常方便的串行通讯控件MSComm,它全面的提供了使用RS-232串行通讯上层开发的所有细则,它既可以使用查询方式又可以使用事件驱动方式来完成串行通讯。
  在MSCOMM控件中提供了一系列的编程要素,这些编程要素有属性、事件和函数,利用这些要素编程,可以实现几乎全部的串行通讯功能。在VB中提供了30多个属性、一个事件和两个函数,其中主要的属性为CommPort、Settings、PortOpen、InBufferSize、OutBufferSize、InBufferCount、OutBufferCount、Break、InputLen、SThreshold、Rthreshold、RTSEnable、CommEvent、ParityReplace、NullDiscard等。
  控件MSComm提供了一个事件OnComm,该事件可以截取串口的任何消息,转入事件处理程序。WINDOWS操作系统的运行机制为事件驱动,在VB编程中事件驱动方式同样是软件运行的主要方式之一,当没有事件发生时程序可能处于某一循环、等待或任务状态当事件发生时,程序转入事件处理程序。每个控件下都有一些事件供程序员使用,MSCOMM控件中OnComm事件是唯一的,OnComm可以扑获通讯时发生的串口事件和错误信息,当有串口事件或错误发生时,VB会立刻触发一个OnComm事件,程序就会自动转入OnComm事件处理程序中。CommEvent属性是OnComm事件的指示器,该属性在设计时不能使用,在程序运行时为只读,CommEvent 属性存有最近的事件或错误的数值代码,可以在程序中随时读取CommEvent 属性值来了解通讯的状况,OnComm事件是和CommEvent属性密切相关、一起使用,当任何一个OnComm 事件或错误发生时,都会使得CommEvent属性值改变,在OnComm事件处理过程中,可以通过判断CommEvent属性值,对于不同的属性值转入不同的事件处理过程,一般采用的办法是SELECT CASE…….END SELECT。由于在无线通讯中没有使用有线MODEM,CommEvent 属性涉及到的有线MODEM的属性数值代码和本项目无关。

  三、 无线传输接口和协议
  在我们的项目中用Intel 586/120的PC机为上位机,通讯程序使用VB开发的,用8031单片机做CPU、 AD574作数据采集的下位机,上位机作数据接收和数据处理中心站,下位机实时采集数据之后,进行简单的数据平均计算,当收到上位机发来的发送指令之后,开始向上位机发送数据。
  上位机无线通讯接口使用的是一块插在ISA扩展槽中的无线MODEM ZX-02,无线MODEM与KENWOOD公司的TK-378无线对讲机相连,数字信号通过无线MODEM调制成为音频信号之后,送到TK-378无线对讲机上的MIC口。
  下位机有一台外置无线MODEM ZX-01,单片机的数字信号经过串口送入无线MODEM,MODEM对信号进行调制后送入KENWOOD TK-378无线对讲机上,接收数据的方式与上述相同,由TK-378收到信号后,经无线MODEM将音频信号解调为数字信号进入计算机或单片机处理。
  由于在我们的通讯网络中,并非点对点的通讯,而是一点对多点的广播式的通讯方式,因此,我们在通讯协议中曾加站点识别码,每个站有自己特定的识别码,给下位机编码可以保证网络通讯的有序性。
  由于无线通讯可能会有空间的燥声干扰,因此,我们采取了多项抗干扰措施,首先是包头识别码,在发送了传输命令之后,下位机开始以打包的形式传输数据,每一包都有一个包头和包尾识别码,假如识别码有误,这一次的传输为不正常数据处理。打包发送另外一个原因是TK-270对讲机连续发送数据的时间不能超过一分钟,超过一分钟就会自动中断发送,因此,当数据较多时不打包连续发送的时间就会超过一分钟,发送数据中断。
  在下位机中有32KB的NVRAM,可以保存32KB的数据该数据可以由上位机发送清除命令的方法清楚掉,当32KB满了以后,最早放入的数据就会丢掉,由于我们的采样速率不高,在慢采的情况下,两天的时间才能存满,这样不论上位机或下位机出现断电、死机等问题,数据不会丢失掉。
  在发送过程中,由于干扰的原因数据传输出现错误,上位机不给下位机发送清楚命令,数据保存在NVRAM中,下次上位机发送传输命令之后,这些数据还会重新发送到上位机来,这样可以避免了线路带来的数据损失,
从下位机向上位机传送的代码有ASCII码和BCD码,测量数据部分用的是BCD码主要是为了节省资源,由上位机向下位机发送的命令均为ASCII码。
  我们还对字段长度和包的长度作了规定,一个字段有多少个字节,一包有多少个字段组成,如果数据最后不够一整包,也按照整字段的格式作为半包发送过来。
  考虑到下位机的分散性,可能固定在偏远、不宜接近的地带,用上位机对下位机发送校时命令并校时的方法来统一网络时间。
  由于我们使用的无线MODEM 所限,传输速率只能达到2400BPS,而在我们的使用中1200BPS、N PARITY、8 DATA、1 STOP为较稳定状态。
  上位机向下位机发送的命令有校时命令并校时、请内存命令、发送数据命令、快采命令和慢采命令等。发送命令有两种发送方式,即手动方式和自动方式,自动方式是由定时器来完成的。
  在无线通讯过程中,除了规定合理的协议之外,为了保证通讯的正确性,在数据发送时适当的增加延时是必要的,当速度较慢的计算机向速度较快的计算机发送数据时应适当的增加延时。

  四、 应用实例
  由于该项目的软件源代码较长,我们只拿出和串口通讯有关的程序片段来供大家参考。在我们的工作中实践了三种通讯方式,即查询方式、事件驱动方式、事件驱动转查询方式,这三种方式各有利敝,查询方式有方便可靠的特点,可利用协议或设定时钟进入和退出查询状态,但不是资源的有效利用方式,事件触发方式对于定长通讯非常有效,但定长通讯在有些场合不实用,事件驱动转查询方式既有事件驱动的特点又有转查询方式特点,可以说是集二者之长,有效利用资源。下面着重介绍事件驱动转查询方式。
  首先在公共模块中定义和ONCOMM有关的参数:
.
.
.
Global Const MSCOMM_EV_RECEIVE = 2'收到 Rthreshold 个字符。该事件将持续产生直到用 Input 属性从接收缓冲区中删除数据。
Global Const MSCOMM_ER_RXOVER = 1008'接受缓冲区溢出。接收缓冲区没有空间。
Global Const MSCOMM_ER_TXFULL = 1010 '传输缓冲区已满。传输字符时传输缓冲区已满

  在启动过程中对串口和输入输出缓冲区初始化:
Sub Form_Load ()
 .
 .
 .
 comm1.Settings = "1200,n,8,1" '设定波特率1200bps,无校验,8位数据位,1位停止位
 comm1.CommPort = 1 '串口1
 comm1.InputLen = 1 '一次从输入缓冲区中读取一个字符
 comm1.InBufferSize = 512 '定义输入缓冲区为512字节(bytes)
 comm1.InBufferCount = 0 '清空输入缓冲区
 comm1.OutBufferCount = 0 '清空输出缓冲区
 comm1.PortOpen = True '启动串口
End Sub
  下面是发送数传命令的子过程,启动该过程由一个定时器控制:
Sub sample_data ()
 .
 .
 .
 comm1.RTSEnable = True '将Modem的PTT置高,同时打开对讲机
 Call time_delay '适当延时
 comm1.Output = "*TRNS" + Chr$(13) '发送命令
 Do '该循环用来检测命令是否全部发送完毕
 Loop Until comm1.OutBufferCount = 0
 Call time_delay '适当延时
 comm1.RTSEnable = False '将Modem的PTT置低,将对讲机改为接受状态
 comm1.InBufferCount = 0 '清空接收缓冲区
 comm1.RThreshold = 1 '设定RThreshold = 1,等待出发OnComm事件
 .
 .
 .
End Sub
  在OnComm编写接收和处理代码:
Sub Comm1_OnComm ()
 Select Case comm1.CommEvent
  .
  .
  .
  Case MSCOMM_ER_RXOVER '接收缓冲区溢出。可插入相应的代码
  Case MSCOMM_ER_TXFULL '传输缓冲区已满。可插入处理代码
  Case MSCOMM_ER_RECEIVE '收到1个字符,可进入以下处理过程
   comm1.RThreshold = 0 '不再响应OnComm事件,转入查寻方式接收
   ii = 0
   iii = 0: sinn = Chr$(42): sinn1 = Chr$(42) '初始化变量
   Do
    duration = Timer + .2 '设定超时退出的时间值
    iii = iii + 1
    sinn1 = sinn
    Do '该循环判断输入缓冲区是否有数据或是否超时
     'dummy% = DoEvents()
    Loop Until comm1.InBufferCount >= 1 Or Timer >= duration
    If Timer >= duration Then
     iii = iii - 1
     overtime = True '确定超时退出,并非正常退出
     Exit Do
    End If
    sinn = comm1.Input '正常退出,取值付给sinn
    If header_er = 0 Then
     GoTo test_header
    End If
    If Asc(sinn) > 175 Or Asc(sinn) < 160 Then '判断包头是否正确
     iii = 0
     GoTo station_number_er '包头不正确,丢掉该数据
    End If
test_header: header_er = 0 '包头正确,接受到包头,header_er=0
    ssin(iii) = sinn'----put date into string dimantion
    station_number = Asc(ssin(1))
    package_number = Asc(ssin(2))
    sentence_number = Asc(ssin(3))
    last_character = Asc(ssin(iii))
station_number_er:
   Loop Until sinn1 = Chr$(10) and sinn = Chr$(13) '当收到正确的包尾0A,0D后退出
   If overtime = True Then '如果超时非正常退出
    overtime = False
    comm1.RThreshold = 1 '重新启动OnComm事件,等待接收下一包
    timer6_wait.Enabled = True
    GoTo endsub
   End If
  以下是接收数据正确以后的数据处理程序,包括解码和计算这里从略。
   .
   .
   .
   If package_number = 1 Then '如果接收数据正确,而且是最后一包
    timer2_sample.Enabled = True '启动控制数传命令定时器
    comm1.RTSEnable = True '置PTT为高
    comm1.OutBufferCount = 0 '清空输出缓冲区
    Call time_delay '适当延时
    comm1.Output = "*MACK" + Chr$(13) '发送清内存命令
    Do '检测是否发送完毕
    Loop Until comm1.OutBufferCount = 0
    Call time_delay '适当延时
    comm1.RTSEnable = False '置PTT为低
   End If
   If package_number > 1 Then '如果不是最后一包
    comm1.RThreshold = 1 '启动OnComm准备接收下一包
    timer6_wait.Enabled = True
   End If
endsub: header_er = 1: comm1.InBufferCount = 0 '--empty inbuffer protect from bed data on the inbuffer
 End Select
End Sub

  五、 结论
  根据我们实践工作的经验,在本项目中无线通讯和有线通讯的主要区别在于用MSCOMM控件的RTSEnable属性对无线Modem的PTT操作以及适当的延时,延时的长短和使用的计算机有关。在开发的过程中,把握好上述两条,设定一个合理的通信协议,选择合适的硬件是至关重要的。
通用的MsgBox-Delphi资料 图象放大镜——实现图象局部放大的原理和方法-Delphi资料 图形的特殊显示效果-Delphi资料 图形整体拉出效果-Delphi资料 一个实用的Delphi屏幕拷贝程序的设计 用Delphi 显示122种图形特效 用Delphi编写DLL实现动态改变分辨率 用Delphi进行OpenGL编程学习心得 用Delphi开发windows95屏幕保护预览程序 用Delphi实现壁纸更换 用DELPHI实现位图显示特技 用DELPHI中Canvas特性开发图形软件 用构件变换法实现动画效果-Delphi资料 在Delphi中使用动态图标 在Delphi中显示Windows图标 在多媒体文件中批量抓取图象-Delphi资料 怎样读出不同格式图形的高和宽-Delphi资料 怎样使用PageUp、PageDown滚动窗体-Delphi资料 怎样制作全透明的窗口-Delphi资料 DELPHI:FormContainer简易手册 Delphi:用FormContainer渐变效果 Delphi4的窗口融合技术 Delphi使用技巧ABC Delphi使用技巧四则 DELPHI中自适应表单的实现 TList的用法-Delphi资料 不规则窗口的实现-Delphi资料 不用标题栏也移动窗体-Delphi资料 窗口建立和关闭时的特效-Delphi资料 窗口中状态行的显示-Delphi资料 动态提示的可视化实现-Delphi资料 在RedHat8.0上安装Kylix3出现的问题?(关于文件包glibc检查出错)??????? VSS: Unable to check out the file <file> because it is already checked out. 一个暴难问题,关于两台电脑通过一个modem上网的问题。谢谢。 谁是高手,立马给分! 如何使ListControl 内容排序? 无法安装sql2000! 关于inport()和outport()的问题! 哪位仁兄手上有灰度图像的傅立叶变换和反变换的程序代码? 请教高手!死机问题 如何可以让网页内容置中显示,不管客户端的分辨率是多少? 大家注意Acrobat 5与BDE有冲突!! 怎样向客户端输出数据 如何判断一个变量是否定义过?使用if(var)的方法不行,报错 Interbase树形结构和递归调用问题,高手请进!!急!!!! 有谁知道哪有pb8.0汉化版出售。本人是个十足的英语盲! Oracle8 的blob字段,BDE读取报“Invalid Field Type”的错误 Interbase树形结构和递归调用问题,高手请进!!急!!!! 如何选出表中相同的纪录? 下面这些对编程风格的说法是否正确? Interbase树形结构和递归调用问题,高手请进!!急!!!! 请教dos中有没有类似notify的命令用于邮件通知 java有没有RTTI(runtime type information) 在DOS下开发软件,应该如何调用扩展内存? 高分求:Antechinus C# Editor4.2c和JavaScript Editor的注册码! 想自己做个字典软件,但是没有词库 怎样做个链接?链接邮件地址。 如何在工具栏statusbar的右下角(最后一个panel里)做一个走动的时钟 大家讨论一下开发JSP Web站点用什么工具比较好? 我想编一个网页管理软件,有如下要求。。。 大家帮看一下,加注释的一句是什么意思 高分求救!!有关数据同步!! 北京的程序员薪水如何(6000/月)? 大放分﹗﹗即放即給﹗﹗ 关于WinSock通信 我用怎样得到过滤后有多少条记录呢? 存储过程问题,还有些小麻烦,帮帮忙呀,谢谢:) 急~~!关于ChildView类的问问题~~!!请大家帮助。谢谢。 怎么用Container Managed Persistence EntityBean实现对数据库的增删改,最好用jsp调用 如何知道光驱是打开的还是关闭的??? 程序运行一会儿,BDE 数据库引擎空间不够,什么原因?? 在asp.net里怎么引用word对象,和对它进行操作??? 这个问题不好弄! 讨论:关于使用UDP作为服务器主要协议会碰到的问题? 我安装的rh8.0中,/dev/里的东东怎么都是0字节啊?! 请教,有什么工具能把jpeg图片转换为mpeag1视频,使它能在vcd上观看 如何指定PB6.5访问oracle9 i的默认用户名 多线程资源释放的问题 高手救命!!用pb如何实现用热键调出程序的功能 浏览帖子的问题 高难度:列表视图的重绘问题 编写active控件的问题 报错:变量使用了一个VbScript中不支持的Automation类型oMail.send 陈豪承认正准备婚事 婚礼举办地选定在Selina昔日炸伤视频曝光 老公发姚晨黑白大片如茶花般娴静自若 流光溢罗志祥舞蹈老师卷入淫乱派对 狂欢视频俞灏明《爱在春天》爆炸前帅气萌照《爱在春天》公布爆炸视频 俞灏明:第清秀萌妹校服照走红网络杨丞琳曝陈妍希“傻大姐”:女神其实很熊黛林暗示有追求者 不介意与苟芸慧同《梦之声》现场韩红强吻黄晓明 令人大《合伙人》破两亿庆功 黄晓明邓超佟大刘烨微博曝半裸照秀人鱼线 粉丝过千万乔振宇复古大片曝光 沉静优雅突显男人《被偷走的那五年》张孝全再爱一次后街男孩巡演倒计时开启 新专辑曲目现许茹芸抵京引粉丝疯狂 5.25掀起京许艺娜做客《城市一对一》 畅谈延吉美黄晓明隔空喊话:唱的我想结婚了戛纳基努身材"走样&quo《富春》爆林志玲尼姑造型 牺牲秀发以陈数一家三口穿亲子装温馨郊游 儿子顽考生可适当报考外区示范性高中殷寿铣:蔡英文利用其青年军架空民进党周日足彩三玩法调场次为贵州好生态代言民进党桃园县党部主委改选 苏系占上风马英九就职满6年 将发表演说着重为青被野蜂蜇伤重症脑炎 廿岁壮小伙昏迷两道德广“播种” 清风润民心分析:绿营高谈“宪改”向公民团体交心第四中学:体艺成果丰 科技品牌强年内计划发行百家上市新股《奇怪的她》有笑有泪:哪个恶婆婆不想哪所学校适合你,且看校长怎么说美国越来越多高校认可雅思为贵州好生态代言道德广“播种” 清风润民心认真学习贯彻习近平总书记指导兰考县委抢抓新一轮发展机遇 千方百计保持经济广东免征39项行政事业性收费 企业一广东今年推进23类信息公开 公立医院广州市土地房产管理职业学校 中南地区
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘