PowerBuilder中串行通信编程技术研究

摘要:介绍了在PowerBuilder 中调用Win32 API函数、使用Mscomm32.ocx通信控件、利用VCL通信组件和调用DLL(动态链接库)中的函数来实现串行通信的方法,分析总结了各种方法的优缺点。
关键词:串行通信;事件驱动;应用程序接口;动态链接库

0 引言
在自动控制中,用PC机对工程实现实时监控,通常要求PC机能在用户界面上具有数据采集、数据处理以及控制信号的产生与传输等功能。在这种情况下,PC机 要与过程控制的信号相联系,就要求能实现对PC机的串行端口直接操作。串行通信具有传输距离长、连接简单、使用灵活方便、数据传输可靠性高等特点,在工业监控、数据采集和实时控制系统中得到了广泛应用。
PowerBuilder
(简称PB)是一种可视化的、面向对象的快速交互式应用开发工具。PB 以其简洁高效的集成开发环境、强大的数据窗口技术、便捷的报表生成及打印功能,越来越受到广大开发人员的青睐。在各种开发软件中,PB对于数据库的上层编 程支持是名列前茅的,但是,PB对计算机的底层支持略显薄弱,没有提供串行通信的命令、函数或控件,与其它设备之间进行数据通信较为困难,笔者根据自己在 PB编程中积累的经验,介绍了几种在PB中实现串行通信的方法。

1 串行数据通信
1.1
工作原理

Windows
是一个事件驱动的与设备无关的多用户操作系统,它禁止应用程序直接和硬件交互,程序员只能通过Windows提供的各类驱动程序来管理硬 件。Windows系统函数包含了通信支持中断功能,Windows系统为每个通信设备开辟了用户定义的输入输出缓冲区(即读写缓冲区),数据进出通信口均由系统后台来完成。应用程序只需完成对输入输出缓冲区操作就可以了。实际过程是每接收一个数据就产生一个低级硬件中断,Windows系统中的串行驱动程序就取得了控制权,并将接收到的数据放入输入数据缓冲区,然后将控制权返还正在运行的应用程序。如果缓冲区数据已满,串行驱动程序用当前定义的流控制机制通知发送方停止发送数据。队列中的数据按先进先出的次序处理。
1.2
通信方式
串行通信的数据是一位接一位顺序地传送下去,通信方式有以下几种:
1)异步通信方式
异步通信方式中,数据是一帧一帧(包括一个字符或一字节数据)传送的,每一串行帧的数据由起始位、数据位、奇偶校验位和停止位组成。
2)同步通信方式
同步通信方式中,数据开始传送前用同步字符来指示(常约定1-2个),并由时钟来实现发送端和接收端同步,即检测到规定的同步字符后,就连续按顺序传送数据,直到通信告一段落。
3)查询方式
查询方式是定时地查询串口的接收缓冲区,如果接收缓冲区有数据,就读取数据;若缓冲区中没有数据,继续执行,因此会占用大量的CPU时间,它实际上是同步方式的一种派生。
4)事件驱动方式
事件驱动方式通过设置事件通知,当所希望的事件发生时,Windows发出通知,这与DOS环境下的中断方式很相似。
采用异步方式可以提高系统的整体性能,在对系统强壮性要求较高的场合,建议采用这种方式。查询方式是一种最直接的读串口方式,但定时查询存在一个致命的弱点,即查询是定时发生的,可能发生得过早或过晚。在数据变化较快的情况下,特别是主控计算机的串口通过扩展板扩展到多个时,需定时地对所有串口轮流查询,此时容易发生数据的丢失。虽然定时间隔越小,数据的实时性越高,但系统的资源也被占去越多。事件驱动方式是一种高效的串口读方式,这种方式的实时性较高,特别是对于扩展了多个串口的情况,只有当设定的事件发生时,应用程序得到消息后,才进行相应的处理,避免了数据丢失。事件驱动方式能够更好地处理串行端口通信交互,其优点是程序响应及时,可靠性高。在实时性要求较高的场合建议采用事件驱动方式。
1.3
实现步骤
利用PC机的串口实现串行通信的一般步骤如下:
(1)
打开并配置串口
在应用程序中要使用串口进行通信,必须在使用前向操作系统提出资源申请,要求打开串口,为了保证串口通信数据传输的可靠性,串口打开时一般都设置为非共享模式,串口一旦被打开,其他的应用程序将无法打开或使用它。
在使用串口进行数据通信前必须对其进行配置,串口配置主要包括波特率、数据位数、停止位数、奇偶校验、发送缓冲区大小、接收缓冲区大小等。
(2)
数据读写和超时设置
串口打开并配置好后即可对其进行读写操作了,对串口的读写操作可采用查询、同步、异步和事件驱动等方式。
在串口通信时如果数据传输突然中断,对串口的读写操作可能会进入无限期的等待状态,为避免这种情况发生,必须设置串口读写操作的等待时间,等待时间超过后,串口的读写操作将被主动放弃,这样即使数据传输突然中断,程序也不会被挂起或阻塞。
(3)
关闭串口
在串口使用完后应将其关闭,否则如果没有关闭串口,该串口将始终处于打开状态,其他的应用程序就无法打开或使用它。

2 PowerBuilder编程中实现串行通信的方法
利用PowerBuilder实现串行通信常用的方法主要有四种:一是使用通信控件,如MSComm控件;二是调用Win32 API函数;三是利用串行通信组件;四是调用DLL(动态连接库)实现串行通信编程,下面就四种方法分别加以讨论。
2.1
使用MSComm通信控件实现串行通信编程
2.1.1 MSComm
控件

PowerBuilder中可采用Mscomm32.ocx控件实现串行通信编程。串行通信控件Mscomm32.ocx(简称MSComm)是 Microsoft公司提供的Windows下串行通信编程的32ActiveX控件。该控件将串行通信的大部分操作都封装到控件的内部,提供了一系列通信命令的接口属性和事件,它允许建立串行口连接,可以连接到其他通信设备(如Modem)、还可以发送命令、进行数据交换以及监视和响应在通信过程中可能发生的各种错误和事件,从而可以用它创建全双工的事件驱动的通信程序。
MSComm
控件提供两种处理通信的方式:事件驱动方式和查询方式。查询方式通过检查CommEvent属性值来确定通讯事件和错误。事件驱动方式在串口接收到或发送完指定数量的数据时或状态发生改变时,MSComm通信控件捕获到这些事件和错误,触发OnComm事件,通过检查MSComm控件的 CommEvent属性的值来获得所发生的事件和错误代码值,从而执行相应的处理。
2.1.2 MSComm
控件主要属性和事件
CommPort:设置并返回通信端口号,选COM1时值为1
Setting
:以字符串的形式设置并返回串口通信参数,格式为波特率、奇偶校验、数据位、停止位
PortOpen
:设置并返回通信端口的状态,属性为True打开串口,为False关闭串口并清除接收和传输缓冲区。
InputMode
:设置从缓冲区读取数据的格式,0文本形式,1二进制形式;
Input
:从接收缓冲区读取数据;
Output
:向发送缓冲区写入数据;
InBufferCount
:设置接收缓冲区中的字节数;
OutBufferCount
:设置发送缓冲区中的字节数;
InputLen
:设置并返回Input属性从接收缓冲区读取的字节数;
Rthreshold
:当CommEvent 属性为ComEvReceive并产生OnComm之前设置并返回要接收的字符数
CommEvent
:返回最近的通信事件或错误;
OnComm
事件:无论何时当 CommEvent 属性的值变化时,就产生 OnComm 事件,标志发生了一个通信事件或一个错误。

2.2 调用Win32 API函数实现串行通信编程
Windows
操作系统对系统底层操作采取了屏蔽的策略,禁止应用程序直接访问计算机I/O端口,而由设备驱动程序统一管理,Windows封装了 Windows的通信机制,这种方式称为通信应用程序接口API(Application Programming Interfaces)Windows 9x/NT/2000提供的API一般都支持32位的操作,又称为Win32 API,程序员可以利用Win32 API的通信函数进行编程,不用对硬件直接进行操作,使得应用程序的编制更加方便。
2.2.1 Win32 API
常用通信函数
在进行串口通信时,经常需要用到下列一些API函数:
CreateFile()
:用于打开一个文件访问串口;
GetCommState()
:获取串口的当前配置,放入设备控制块DCB中;
SetCommState():
根据DCB重新配置串口参数;
SetCommTimeouts()
:设置串口读写操作的溢出时间;
ReadFile()
:从串口的输入缓冲区读取数据;
WriteFile()
:向串口的输出缓冲区写入数据;
SetCommMask()
:监视指定通信资源上的事件;
WaitCommEvent()
:等待通信事件发生;
CloseHandle()
:关闭由CreateFile函数打开的串口。
以上这些函数的原形可在参考文献[1]中找到。
2.2.2 API
函数在PowerBuilder中的声明
PB支持对Win32 API函数的调用,在PB中使用Win32 API函数时,首先要将它们声明为外部全局函数,然后在脚本中调用。在PB中声明外部函数的语法为:
{Access} FUNCTION ReturnDataType FunctionName( {REF} {DataType1 Arg1,…,DataTypeN ArgN}) LIBRARY LibraryName
其中各参数的含义是:
Access
:访问级别,可以是PublicPrivateProtected,缺省为Public
ReturnDataType
:返回函数类型;
FunctionName
:函数名,存储在DLL中的函数名。
DataType
:参数的数据类型;
Arg
:参数名;
LibraryName
:动态连接库名。
PB中声明时数据类型必须换成PB中相应的数据类型,而在声明或者调用到的结构类型(如DCB结构)和一些常量也应在PB中创建或声明。ReadFile()函数在PB下的声明为:
FUNCTION ulong ReadFile(ulong hFile,ref Any lpBuffer,ulong nNumberOfBytesToRead,ref ulong lpNumberOfBytesRead,ref OVERLAPPED lpOverlapped) LIBRARY "kernel32.dll"
2.2.3
调用Win32 API函数实现串行通信主要步骤
PB中将Win32 API函数申明为外部函数之后,就可以像调用PB自身的函数一样调用它们。在PB编程中调用Win32 API函数实现串行通信主要步骤如下:
1)打开串口
调用CreateFile()函数打开并初始化串口,以确定本应用程序对此串口的占有权并封锁其他应用程序对此串口的操作。成功打开串口后,函数返回标志该串口资源的句柄,以后对串口的读写操作都是通过该句柄实现的。
2)配置串口
Windows
的串口和串行通信驱动程序是通过一个被称为设备控制块(DCB)的数据结构进行配置的,Windows为获取通信端口的状态提供了重要的 GetCommState()函数。使用GetCommState()函数获取串口的当前配置,即获得当前的设备控制块DCB结构,更改DCB结构中的参 数,再调用SetCommState()函数重新设置串口的波特率、数据位、检验位与停止位来配置串口。通过SetComm()函数设置串行通信端口的输入和输出缓冲区的大小,通过SetCommTimeouts()函数设置串口读写操作的溢出时间。如果不对串行口资源进行设置,将使用系统的缺省配置。
3)对串口进行读写操作
当采用事件驱动I/O设备时,用SetCommMask()来监视指定通信资源上的事件,用WaitCommEvent()来等待通信事件发生。在此基础上就可以在相应的串口上作数据的传输。通过ReadFile()函数或ReadFileEx()函数对串口进行读操作,通过WriteFile()WriteFileEx()函数对串口进行写操作。
4)关闭串口
串行通信结束时调用CloseHandle函数关闭由CreateFile函数打开的串口,释放串口资源。
2.3
利用通信组件实现串行通信编程
2.3.1
利用SPComm组件实现串行通信编程

串行口VCL组件SPComm封装有丰富的与串口通信密切相关的属性和事件,是目前功能比较完善的串行通信组件,提供有完整的源代码。
1SPComm的主要属性
CommName
:填写所要打开的串口名字,如“COM1”
RaudRate
:设定实际的串行通信波特率。
ParityCheek
:奇偶校验。
ByteSize
:设定字节长度。
Parity
:奇偶校验位。
StopBits
:停止位。
SendDataEmpty
:布尔属性,为True时表示发送缓存为空,或者发送队列里没有信息;为False时表示发送缓存不为空,或者发送队列里有信息。
2SPComm的主要方法和事件
StartComm()
过程用于打开串口,当操作失败时通常会报错,错误主要有7种:串口已经打开;打开串口错误;文件句柄不是通讯句柄;不能安装通讯缓存;不能产生事件;不能产生读进程;不能产生写进程。
StopComm()
过程用于关闭串口,没有返回值。
WriteCommData()
函数把要发送的字符串写入发送缓冲区,发送成功返回True,发送失败返回False。执行此函数将立即得到返回值,发送 操作随后执行。此函数有两个参数:pDataToWrite是要发送的字符串;dwSixeofDataToWrite是发送数据帧的长度。
OnReceiveData(Tobject * Sender, Pointer Buffer, WORD BufferLength)
事件的功能是当输入缓存有数据时将触发该事件,可在该事件中对从串口收到的数据进行处理。参数Buffer是接收到的数据,BufferLength是接 收到的数据长度。
OnReceiveError(Tobject * Sender,DWORD EventMask)
事件功能是当接收数据时出现错误将触发该事件,EventMask是错误事件的代码。
OnSendDataEmpty(Tobject * Sender)
事件的功能是当发交通安全数据完成时将触发该事件。
SPComm
组件的应用与MSComm控件相似,基本编程时只要给组件的相关属性正确赋值就可配置串行通信参数,通过组件的方法打开/关闭串口和发送数据,在组件相应的通信事件处理函数中接收数据和处理通信事件。与MSComm ActiveX控件不同的是,SPComm组件是标准的VCL组件,提供多线程编程的支持,能够更可靠地进行串行数据通信。
2.3.2
利用其它第三方组件实现串行通信编程
某些公司根据实际的需要为Windows环境提供了不同的开发工具。如TurboPower公司出品的Async Professional VCL组件包,功能更具体和完善,完全支持COM端口控制和WinSock协议,支持与ISDN ModemRS485等硬件接口交互等功能,程序员可以选用其VCL组件进行串行通信程序开发。
2.4
利用DLL实现串行通信编程
MOXA
AdvantechNI等公司在提供串行通信接口硬件板卡产品的同时,提供了相应的DLLDynamic Link Libraries动态链接库)文件,程序员可以根据实际情况选用对应的DLL文件进行串行通信程序的二次开发;另外,程序员也可先用VC或其他高级编程 语言将通信程序编写成DLL文件,然后在PB中调用此DLL中的函数实现串行通信。编程中应特别注意要对DLL文件中的函数进行声明。

 

 

3 串行通信编程实例
通过PC机的串行口与单片机系统进行通信,完成对单片机系统的控制和数据的接收处理。PC机通信程序采用PB8.0MSComm通信控件编写。
在通信窗口中插入MSCOMM32.OCX通信控件,控件名为Ole_MSC,添加读数据按钮,名为cb_read。通信控件用于访问串口、发送和接收数据,数据传输采用二进制方式。
1)打开并配置串口
在通信窗口的Open()事件中编程,完成对串口的打开和配置,程序如下:
Ole_MSC.object.CommPort=1 //
设置通讯端口号为COM1
Ole_MSC.object.Settings = "4800,n,8,1" //
波特率4800 bps,无奇偶校验,8位数据位,1位停止位。
Ole_MSC.object.InBufferSize =600 //
设置接收缓冲区的字节数
Ole_MSC.object.OutBufferSize =600 //
设置发送缓冲区的字节数
If Ole_MSC.object.PortOpen <> True Then
Ole_MSC.object.PortOpen = True //
打开串口
End If
Ole_MSC.object.InputMode =1 //
二进制方式读取数据
Ole_MSC.object.SThreshold = 0 //
数据传输事件不产生 OnComm 事件
Ole_MSC.object.RThreshold = 400 //
400个字节的数据到缓冲区都触发OnComm 事件。
2)数据的发送
通过Output属性向传输缓冲区发送读数据命令“ReadData”。数据的传输采用二进制方式,PB中发送和接收二进制数据,采用blob类型的变量。cb_readclick()事件程序如下:
blob bufferout
Ole_MSC.object.OutBufferCount=0 //
清空发送缓冲区
Ole_MSC.object.InBufferCount=0 //
清空接收缓冲区
bufferout=blob("ReadData")
Ole_MSC.object.Output =bufferout //
向传输缓冲区发送读数据命令
3)数据的接收处理
当单片机接收到读数据的通信命令后,向缓冲区发送数据,进入通信状态。数据的传输采用定长的二进制方式,单片机向缓冲区发送400个字节长的数据,当 400个字节的数据到缓冲区则触发Ole_MSCOnComm()事件。通信控件Ole_MSCOnComm事件程序如下(数据处理程序略):
blob buffer
choose Case ole_1.object.CommEvent
Case 2 // CommEvent
属性为ComEvReceive
ole_1.object.InputLen =0 //
读入整个缓冲区中的数据
buffer=ole_1.object.Input //
从接收缓冲区读取全部数据
……
end choose
4)关闭串口
在串口使用完后应将其关闭,释放串口资源。
If Ole_ MSC.object.PortOpen <> False Then
Ole_ MSC.object.PortOpen = False //
关闭串口
End If
4
结束语
比较以上实现串行通信的方法可知,使用MSComm控件或SPComm组件编程比较简单,对硬件掌握的程度要求不高,容易掌握,开发周期短,更适合于快速开发串口通信程序,MSComm控件通信的实时性不高,高速通信时准确性和处理速度一般,只能应用于相对比较简单的小型控制系统和通信系统,SPComm 组件支持多线程,通信的实时性和可靠性均可得到保证。调用Win32 API函数来实现串行通信,程序编写较为复杂,需要掌握大量通信知识,其优点是可实现的功能更强大,应用面更广泛,更适合于面向具体要求编写灵活多变的底层通信程序,常应用于响应要求严格、数据量大的系统中。在不同的应用中要视串口通信任务的要求,采用不同的方法开发通信程序,才能取得较好的效果。文中所给程序在PB8.0环境中运行通过。

发布了51 篇原创文章 · 获赞 5 · 访问量 11万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章