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

  • Post author:
  • Post category:其他


1 串口通信的通信机理

PC串行通信是指直接对串行端口的UART(PC机的通用异步收发器,也叫异步通信适配器,是PC机用于异步通信的接口)进行编程实现的通信

一般说来,PC机都有一个或多个串行端口,它们依次为Com1、Com2……。这些串口提供了外部设备与PC进行数据传输和通信的通道,在CPU和外设之间充当了解释器的角色。当字符数据从CPU发送给外设时,这些字符数据将被转换成串行比特流数据;而当接受数据时,从外界进来的比特流数据被转换成字符数据传递给CPU进行处理。在操作系统方面,Windows用通信驱动程序(COMM.DRV)调用API函数发送和接受数据。当用通信控件或声明调用API函数时,它们由COMM.DRV解释并传递给设备驱动程序。

作为一个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采取不平衡传输方式,即所谓的单端通讯。

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电路之间进行电平和逻辑关系的变换。

3 三种读取串口数据的方式

目前通用的串口通讯的软件实现方式有3种,本文都进行详细的介绍,它们各有自身的优缺点,读者在编程时可根据具体的情况选择合适的方式。


3.1利用Mscomm控件

VB提供的这个通信控件“隐藏”了大部分串口通信的底层运行过程,程序员只需编写少量的代码就可以完成软件的开发过程。在通信数据量不大,通信要求不是很高的情况下建议采取此方式。

利用Mscomm控件实现通信最需要掌握的就是它的几个主要属性,下面选取其中重要的进行介绍,其余的可以参考相关资料。

(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通信函数 (实例见mac文件夹,读取串口设备)

直接调用Windows API函数,可以清楚地理解串口通信的机制,根据需要灵活地配置串口的各种参数和属性,而且直接调用低层API函数,通信效率比较高,但付出的代价就是程序较复杂,编程周期长,适合于大型通信程序及通讯质量要求较高的场合。

在32位的Windows系统中,串口通信是作为文件处理的,串口操作一般为打开、关闭、读取、写入等操作,相应的Windows API函数如下:

(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函数库) (实例见Interview)

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中主要的函数介绍如下。

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属性值,去执行不同的处理程序。

除了以上所述的通讯错误外,在串口通信时,如果数据传输突然中断,对串口的读写操作可能会进入无限期的等待状态, 为避免这种情况发生, 必须设置串口读写操作的等待时间, 等待超时后,串口的读写操作将被主动放弃,这样即使数据传输突然中断程序也不会被挂起或阻塞。可以根据具体要求规定串口读写操作的最长时间值,即串口读写必须在这段时间内完成,否则提示串口操作失败。