欢迎来到学术参考网

基于VB的串口通讯及其软件实现

发布时间:2015-07-07 09:29

  摘要:串口通信因为其简单,灵活易用,在许多领域有着广阔的应用前景。本文在深入了解串口通讯技术的基础上,结合自身的工程实践经验,阐述了vb串口编程的技术要点。并结合一个通讯实例,分析通讯的具体实现,给相关领域的研究人员提供值得参考的信息。
  关键词:串口;rs232;api;pcomm;mscomm;通信程序
  abstract:serial communication has broad application in many fields because of its simple communication circuitry and flexibility. based on deep comprehension of the technology of the serial communications, this article expounds important technology detail integrated with practice experience. an example of communication program is presented and analyzed, which gives other researchers valuable reference information.
  key words:serial; rs232; api; pcomm; mscomm; communication program
  
  现在通讯方式越来越多,速度越来越快,但串行通讯由于自身价格低、协议透明、硬件投资少、软件编程简单等诸多优点在远程数据采集、监视、通信及控制领域里一直占据着极其重要的地位。它不仅没有因为时代的进步而被淘汰,反而在规格上越来越完善、应用越来越广,长久不衰。
  
  1串口通信的通信机理
  
  pc串行通信是指直接对串行端口的uart(pc机的通用异步收发器,也叫异步通信适配器,是pc机用于异步通信的接口)进行编程实现的通信。pc机每个uart中的ins8250中有10个可编程的单字节寄存器,可用于控制、监视操作串行端口,com1的寄存器地址3f8h-3feh,com2的寄存器地址为2f8h-2feh。10个寄存器由7个地址访问,其中5个寄存器的访问条件是先设置3fbh线路控制寄存器的最高位为“1”,该位也称为dlab状态位。[1]
  一般说来,pc机都有一个或多个串行端口,它们依次为com1、com2……。这些串口提供了外部设备与pc进行数据传输和通信的通道,在cpu和外设之间充当了解释器的角色。当字符数据从cpu发送给外设时,这些字符数据将被转换成串行比特流数据;而当接受数据时,从外界进来的比特流数据被转换成字符数据传递给cpu进行处理。在操作系统方面,windows用通信驱动程序()调用api函数发送和接受数据。当用通信控件或声明调用api函数时,它们由解释并传递给设备驱动程序。
  作为一个vb程序员,要编写串口通信程序,只需知道通信控件提供给windows通信api函数的接口即可,换言之,只需设定和监视通信控件的属性和时间即可。
  
  2串行通讯接口rs-232
  
  前一章节讨论了串口通讯的通信机理,但为了实现具体的数据采集、监视、通信功能,必须了解具体的串口形式。目前使用最广泛的串行接口有两种:rs-232和rs-485。本文着重讨论rs-232,rs- 485不作介绍。
  rs-232c标准的全称是eia-rs-232c标准,其中eia代表美国电子工业协会,rs代表推荐标准,232是标识号,c代表rs232的最新一次修改(1969年),在这之前,有rs232a、rs232b协议。它规定连接电缆和机械、电气特性、信号功能及传送过程。eia-rs-232c定义了按位串行传输的数据终端设备(dte)和数据通讯设备(dce)之间的接口信息。rs-232c是从dte或计算机串行接口角度来定义引脚信号的。
  目前rs-232是pc机与通信工业中应用最广泛的一种串行接口。rs232被定义为一种在低速率串行通讯中增加通讯距离的单端标准。rs232采取不平衡传输方式,即所谓的单端通讯。[2]
  db9(9针串口)的接线方式如下:1脚,数据载波检测dcd;2脚,接收数据rxd;3脚,发送数据txd;4脚,数据终端准备dtr;5脚,信号地gnd;6脚,数据设备就绪dsr;7脚,请求发送rts;8脚,清除发送cts;9脚,振铃指示dell。
  db25(25阵串口),常用的针脚也有9个,且和db9可以一一对应,具体接线方式为:8脚,数据载波检测dcd;3脚,接收数据rxd;2脚,发送数据txd;20脚,数据终端准备dtr;7脚,信号地gnd;6脚,数据设备就绪dsr;4脚,请求发送rts;5脚,清除发送cts;22脚,振铃指示dell。
  一般来说,对于要求不太高的场合,使用接收数据rxd,发送数据txd,信号地gnd三个脚即可实现数据传输。如果要求有硬件流控制,则必须使用dtr、dsr、rts和cts这四个脚。
  值得注意的是rs-232c是用正负电压来表示逻辑状态,与ttl以高电平表示逻辑状态的规定不同。因此,为了能够与计算机接口或终端的ttl器件连接,必须在rs-232c与ttl电路之间进行电平和逻辑关系的变换。目前较为广泛地使用集成电路转换器件,如mc1489、sn75150芯片可完成ttl电平到eia电平的转换,而mc1489、sn75154可实现eia电平到ttl电平的转换。
  
  3三种读取串口数据的方式
  
  目前通用的串口通讯的软件实现方式有3种,本文都进行详细的介绍,它们各有自身的优缺点,读者在编程时可根据具体的情况选择合适的方式。
  3.1利用mscomm控件
  vb提供的这个通信控件“隐藏”了大部分串口通信的底层运行过程,程序员只需编写少量的代码就可以完成软件的开发过程。在通信数据量不大,通信要求不是很高的情况下建议采取此方式。
  利用mscomm控件实现通信最需要掌握的就是它的几个主要属性,下面选取其中重要的进行介绍,其余的可以参考相关资料。[3]
  (1)settings属性:以字符串的形式设置并返回波特率、 奇偶校验位、数据位、停止位。这个属性很重要,针对不同的终端设备需要根据设备的具体情况进行调整(比如日本的设备不同于美国的设备,通常会采用奇校验)。
  (2)inputmode属性:设置接收数据的类型,0为文本格式,1为二进制格式。
  (3)input属性:读取并删除接收缓冲区中的数据流。
  (4)output属性:向发送缓冲区传送一数据流。
  (5)rthreshold属性:该属性为一阀值,它确定当接收缓冲区内的字节个数达到或超过该值后就产生代码为comevreceive的oncomm事件。
  (6)handshaking属性:设置和返回握手协议,即计算机内部cpu与串口之间的通讯协议,保证在缓冲区过载时数据不会丢失。这个属性在保证数据传输的正确性方面有很大的作用,共有四个选项,分别表示:①无流控制;②软件流控制;③硬件流控制;④软硬件流控制。采用硬件流控时,要求串口之间和电缆支持硬件握手,在自己制作串口通信线时,有关硬件握手的线rts、cts、dsr、dtr要连接正确。
  在正确设置这些属性的基础上,剩下的就是打开串口,通过串口发送及接受数据了。本文后续章节利用一个实例详细讲解了这些属性的设置及具体代码。
  3.2直接调用win32 api通信函数
  直接调用windows api函数,可以清楚地理解串口通信的机制,根据需要灵活地配置串口的各种参数和属性,而且直接调用低层api函数,通信效率比较高,但付出的代价就是程序较复杂,编程周期长,适合于大型通信程序及通讯质量要求较高的场合。
  在32位的windows系统中,串口通信是作为文件处理的,串口操作一般为打开、关闭、读取、写入等操作,相应的windows api函数如下:[4]
  (1) createfile()函数:实现串口的初始化并打开串口,返回串口句柄资源以供后续进程调用。
  (2) closefile()函数:关闭串口,串口是非共享资源,应用程序以独占方式使用,通信结束应立即关闭。

  (3) readfile()函数:从串口输入缓冲区读取数据流。
  (4) writefile()函数:向串口输出缓冲区发送数据。
  (5) getcommstate()函数:获取串口的当前配置。
  (6) setcommstate()函数:重新分配串口资源的各个参数。
  由于windows api函数大部分是用c或c++编写,所以在visual basic 6.0 中调用windows api函数之前必须先在模块级代码上用declare语句对所调用的函数和用到的数据结构进行声明,具体的函数声明及数据结构请参考朱友芹编《新编windows api参考大全》。
  3.3调用第三方函数库(如pcomm函数库)
  dll(dynamic link library)动态链接库是一种可以被vb语言调用的程序模块。dll中包含的可执行代码不能单独执行,而应由windows应用程序调用执行。一般数据采集卡的供应商都会提供该采集卡的dll库函数,使用这些dll库函数,可以做到程序代码共享,减少程序的编写工作量。用户不需要知道这些代码的实现细节,只需要了解调用函数的参数和函数处理后的返回值。
  pcomm函数库是由台湾moxa公司为开发串口通信程序提供的一套函数库。通过对windows api函数的进一步封装,提供50多个串口操作函数。覆盖了windows操作系统下几乎所有异步通信的问题,可以简洁的开发多线程通讯程序。采用该库,通信的可靠性与使用mscomm32控件比较有了明显提高, 而相对直接使用win32api函数编程则降低了程序开发难度, 缩短了程序开发周期。
  这种方式上述直接调用windows api函数有相似之处,但也有明显的差异。api函数常采取的方法是在串口监视线程中设置串口通信事件掩码及重叠机制,允许程序在后台等待串口通信事件。通过waitcommevent检测特定的串行通信事件。而在pcomm中,可以采用中断处理的方式,为各种事件指定相应的中断处理函数,如接收到一定数目的字符,接收到结束字符,接收到中止信号以及发送缓冲区为空等;同时还可以采用线程控制的方式,直接采用库中的sio_read()和sio_write()函数读写串口。
  pcomm..dll中的函数按功能分为6项:端口设置、数据发送与接收、串口状态检测、事件服务、文件传输、杂项。pcomm..dll中主要的函数介绍如下。[5]
  sio_open:打开端口;sio_close: 关闭端口。
  sio_ioctl:设置端口参数,如波特率等。
  sio_read:从端口接收数据;sio_write向端口发送数据。
  sio_iqueue:得到接收缓冲区中的数据长度。
  sio_oqueue:得到发送缓冲区中的数据长度。
  pcomm在串口通信中的功能十分强大,但基于篇幅的考虑,在此不便赘述,读者可参考相关书籍或pcomm自带的帮助文档。
  
  4串口通讯的错误及处理
  
  由于外界干扰或电压波动等原因,串口通讯可能会出现错误,如接受缓冲区溢出,奇偶校验错误等。为了处理这些错误,在mscomm控件中就提供了一个oncomm事件,它可以捕获通信时发生的串口事件和错误信息,自动转入事件处理程序。在oncomm事件中,commevent属性是oncomm事件的指示,下面简单介绍几个重要的commevent属性值。
  comeventbreak:表示收到一个中断信号;
  comeventframe:表示硬件检测到一个数据帧错误;
  comevenrxover:表示接收缓冲区溢出;
  comeventtxfull:表示输出缓冲区已满;
  comevreceive:表示接手到了rthreshold个字符;
  comeveof:表示接受到了eof字符(ascii字符26)。
  编程时用selectcase语句,根据不同的commevent属性值,去执行不同的处理程序。
  除了以上所述的通讯错误外,在串口通信时,如果数据传输突然中断,对串口的读写操作可能会进入无限期的等待状态, 为避免这种情况发生, 必须设置串口读写操作的等待时间, 等待超时后,串口的读写操作将被主动放弃,这样即使数据传输突然中断程序也不会被挂起或阻塞。可以根据具体要求规定串口读写操作的最长时间值,即串口读写必须在这段时间内完成,否则提示串口操作失败。
  
  5串口通讯实例
  
  本实例是一个采集设备电流及功率的通讯程序,采集仪为横河wt230数字功率计,因为要采集的数据量不大,且工程结构简单,故采用mscomm控件的形式进行串口读写操作。
  具体实现步骤如下:
  (1) 在窗体form上添加两个重要的控件:timer1和mscomm1;
  (2) 在程序的form_load事件过程中添加如下代码:
  rt=1 ‘使用com1端口
  g=“9600,o,8,1” ‘设置通信口参数,注意是奇校验,具体的校验方式要视具体的仪器而定
  ode=cominputmodebinary ‘设置接收模式为二进制形式,注意一般对于数据采集这类设备通信,都应该设置为二进制形式
  en=true ‘参数设置好后打开端口
  aking=2-comrts ‘设置为硬件流控制,可以有效避免数据丢失的情况发生
  (3) 程序开始后在一定情况设置d属性值为true 激活timer1_time事件,可以在固定的时间间隔下执行timer1_timer过程中的代码程序,完成数据采集。在timer1_timer过程中添加如下代码:
   = "communicate:wait 1" + chr(13) + chr(10)
   = "measure:normal:value?" + chr(13) + chr(10)
  上述语句是将读取指令发送到串口输出缓冲区(注意每个命令字符串后都要加上回车和换行符chr(13) + chr(10)),再由系统将其自动发送给通过rs232通信线与计算机端口连接的wt230数字功率计,功率计在接收到命令字符串后,经过自身的单片机处理,就自动地把它测到的电压、电流、功率数据以固定的格式和字符形式通过rs232通信线传回至计算机,计算机程序从输入缓冲区读取这些字符数据并利用vb字符处理函数(如val,instr)进行处理就得到了所要的数据,下面是具体的程序代码。
  dim bytinput() as byte ‘注意要将bytinput定义为不定长数组
  dim strtem as string
  dim i as integer
  bytinput = ‘将输入缓冲区数据读入给字节型数组bytinput
  for i = 0 to ubound(bytinput)
  strtem = strtem + chr(bytinput(i)) ‘字节数组中的ascii码值转换成相应 next 的字符
  得到的strtem字符就形象的展示了电流、电压和功率值。对于wt230而言,它的数据结构是这样的,每个数据之间由逗号字符“,”隔开,每个数据以用科学计数法表示,且每个数据以字符“e”分为前半部分和后半部分,前半部分为具体的数据(整数形式),后半部分为此数据的指数,指数的底为10。

  例如得到strtem的值为“23423e-2,00241e-3,05645e-2”这就表示电压值为234.23 v,电流值为0.241 a,功率为56.45 w。
  
  6结论
  
  串口通讯的硬件投资少,软件编程简单,在低速少量数据传输方面的应用极其广泛的应用。本文详细介绍了串口通讯的基本内容及其具体实现方式,读者可以根据具体情况进行选择。以上代码是实现串口通信的核心部分,经过笔者在多个数据采集系统开发中的应用,具有较强的实用价值。
  
  参考文献
  1 李朝青.pc机及单片机数据通信技术[m].北京:国防工业出版社,2002
  2 李长林.visual basic串口通信技术与典型实例[m].北京:清华大学出版社,2006
  3 [美] microsoft公司著、北京希望电脑公司译.microsoft visual basic 6.0 控件参考手册[m],1999
  4 朱友芹.新编windows api参考大全[m].电子工业出版社,2000
  5 moxa library programming guide,1998
  6 范逸之.visual basic 与rs232串行通信控制.北京:中国青年出版社,2000

上一篇:移动在线计费建设方案探讨

下一篇:小议第三代移动通信及发展趋势预测