3三种读取串口数据的方式
目前通用的串口通讯的软件实现方式有3种,本文都进行详细的介绍,它们各有自身的优缺点,读者在编程时可根据具体的情况选择合适的方式。
3.1利用Mscomm控件
VB提供的这个通信控件“隐藏”了大部分串口通信的底层运行过程,程序员只需编写少量的代码就可以完成软件的开发过程。在通信数据量不大,通信要求不是很高的情况下建议采取此方式。
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直接调用Win32API通信函数
直接调用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 Basic6.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事件过程中添加如下代码:
MSComm1.CommPort=1‘使用COM1端口
MSComm1.Setting=“9600,o,8,1”‘设置通信口参数,注意是奇校验,具体的校验方式要视具体的仪器而定
MSComm1.InputMode=comInputModeBinary‘设置接收模式为二进制形式,注意一般对于数据采集这类设备通信,都应该设置为二进制形式
MSComm1.PortOpen=True‘参数设置好后打开端口
MSComm1.HandShaking=2-comRTS‘设置为硬件流控制,可以有效避免数据丢失的情况发生
(3)程序开始后在一定情况设置Timer1.Enabled属性值为True激活Timer1_Time事件,可以在固定的时间间隔下执行Timer1_Timer过程中的代码程序,完成数据采集。在Timer1_Timer过程中添加如下代码:
MSComm1.Output="COMMUNICATE:WAIT1"+Chr(13)+Chr(10)
MSComm1.Output="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=MSComm1.Input‘将输入缓冲区数据读入给字节型数组bytinput
For i=0To UBound(bytinput)
strtem=strtem+Chr(bytinput(i))‘字节数组中的ASCII码值转换成相应Next的字符得到的strtem字符就形象的展示了电流、电压和功率值。对于WT230而言,它的数据结构是这样的,每个数据之间由逗号字符“,”
隔开,每个数据以用科学计数法表示,且每个数据以字符“E”分为前半部分和后半部分,前半部分为具体的数据(整数形式),后半部分为此数据的指数,指数的底为10。
例如得到strtem的值为“23423E-2,00241E-3,05645E-2”这就表示电压值为234.23V,电流值为0.241A,功率为56.45W。
6结论
串口通讯的硬件投资少,软件编程简单,在低速少量数据传输方面的应用极其广泛的应用。本文详细介绍了串口通讯的基本内容及其具体实现方式,读者可以根据具体情况进行选择。以上代码是实现串口通信的核心部分,经过笔者在多个数据采集系统开发中的应用,具有较强的实用价值。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。