因公司软件产品需要和POS机进行通信,所以笔者研究了一下PB串口编程的实现方式。
PB是一个非常好的数据库管理系统的开发工具,但在web和计算机接口通信等方面PB就不是很好用了。幸好我们有ole和com这些很牛的技术,可以让我们非常容易的使用一些组件的功能,而不用自己去开发去关心底层的业务逻辑。使用PB进行串口编程有两种途径,一种是使用微软提供的通信控件(MScomm控件),另一种是用Win32 API函数。下面主要讲解使用MScomm控件实现串口编程的方法。
串行通信控件Mscomm32.ocx(简称MSComm)是 Microsoft公司提供的Windows下串行通信编程的32位ActiveX控件。该控件将串行通信的大部分操作都封装到控件的内部,提供了一系列通信命令的接口属性和事件,它允许建立串行口连接,可以连接到其他通信设备(如Modem)、还可以发送命令、进行数据交换以及监视和响应在通信过程中可能发生的各种错误和事件,从而可以用它创建全双工的事件驱动的通信程序。MSComm控件提供两种处理通信的方式:事件驱动方式和查询方式。查询方式通过检查CommEvent属性值来确定通讯事件和错误。事件驱动方式在串口接收到或发送完指定数量的数据时或状态发生改变时,MSComm通信控件捕获到这些事件和错误,触发OnComm事件,通过检查MSComm控件的 CommEvent属性的值来获得所发生的事件和错误代码值,从而执行相应的处理。
1、Mscomm32.ocx的注册
我们可以单独制做一个注册程序,并打包到您的应用程序中。如果需要安装的目标计算机已经有“Mscomm”控件,则不需要进行任何工作。如果没有“Mscomm”控件,则需要运行这个注册程序。
程序的PB编码如下:
RegistrySet("HKEY_CLASSES_ROOT\Licenses\4250E830-6AC2-11cf-8ADB-00AA00C00905","",RegString!,"kjljvjjjoquqmjjjvpqqkqmqykypoqjquoun")
run("regsvr32 mscomm32.ocx")
messagebox('提示','请重新启动计算机')
这只是简单的编码,并且mscomm32.ocx文件在当前运行目录,注册成功即出现系统消息。为了使界面更友好,您可以做一步修饰,例如“run("regsvr32/s mscomm32.ocx")”,这样就可以使屏幕上不出现系统消息了。
您还可以利用API函数,通过“ExitWindowsEx”函数(user32.dll)可以实现重新启动Windows系统。
2、使用Mscomm32控件进行串口通信
Mscomm32控件的常用属性如下:
CommPort:设置或返回串行端口号,缺省为1
Setting:设置或返回串行端的波特率、奇偶校验位、 数据位数、停止位。缺省值为"9600,N,8,1"。
PortOpen:设置它为True则打开端口,设置它为False则关闭端口。
InBufferSize:设置或返回接收缓冲区的大小,缺省为1024 字 节。
InBufferCount:返回接收缓冲区内的等代读取的字节个数,设属性为0清除接收缓冲区。
OutBufferSize:设置或返回发送缓冲区,缺省为512字节。
OutBufferCounter:返回发送缓冲区内等待发送的字符数,可用0来清空缓冲区。
Output:向发送缓冲区传送数据
RThreshold: 该属性确定当接收缓冲区内字节个数达或超过该值后就产生代码为ComEventReceive
的OnComm事件,设置位0,则不产生OnComm事件。
CommEvent:有通讯错误或事件发生时产生OnComm事件,CommEvent事件的值可以用来确定引
发OnComm事件的具体的错误或事件常用的有以下几种(更详细的资料可参考MSComm控件帮助文件)
ComEventbreak:接受到中断信号
ComEventFrame:硬件检测到帧错误。
ComEventRxOver:接收缓冲区溢出。
ComEventTxFull:发送缓冲区溢出。
ComEventReceive:接受到规定的字符数。
InputLen:设置或返回接收缓冲区内用Input读入的个数。若取0,则读取整个缓冲区的内容。
Input:返回并删除接受缓冲区的数据。
3、pb的实例代码
我们可以根据我们程序的需要来设置上面的属性。Mscomm控件提供下列两种处理通讯的方式:事件驱动方式和查询方式。由于笔者只需要和POS机进行简单的通信,所以我使用比较简单的查询方式。对于查询方式,我们只要使用PB操作Mscomm32的output和input两个属性就可以了。下面是示例代码:
oleobject i_ole_comm //声明ole对象,用来连接Mscomm控件
i_ole_comm=create oleobject
vresult=i_ole_comm.connecttonewobject('mscommlib.mscomm')
//下面初始化mscomm32的参数,并打开串口
if p_comport=1 then
i_ole_comm.CommPort = 1 //1代表com1口,2代表com2口
elseif p_comport=2 then
i_ole_comm.CommPort = 2
else
i_errcode=-1
i_errtext='uo_rs232ld.f_setdevice:打开串口com'+string(p_comport)+'端口出错,请确认此端口存在且没有被其他程序使用'
return i_errcode
end if
i_ole_comm.Settings="9600,n,8,1" //波特率这里设置成了9600,这个要与pos机设置的波特率一直
i_ole_comm.InputLen=0
i_ole_comm.InBufferSize=90
i_ole_comm.OutBufferSize=60
i_ole_comm.SThreshold=0
i_ole_comm.RThreshold=9
i_ole_comm.Handshaking=0
i_ole_comm.InBufferCount=0
i_ole_comm.DTREnable=true
if not i_ole_comm.PortOpen then
i_ole_comm.PortOpen=True
end if
//向串口发送报文
i_ole_comm.OutPut=“Hello world”
//接受串口报文,循环等待接收pos机上传的报文,超时则返回
Do while true
Yield()
sleep(20)
vinput +=i_ole_comm.Input //从Com端口取数据
if Pos(vinput,vend) > 0 then exit //如果存在消息结束符,则推出循环
loop