PB下从串口通信获取程控交换机计费数据的API调用

我是通过调用API实现的: 如你用的是二进制的,请把缓冲区改成BLOB型的。
首先定义外部函数: 

Function
 Boolean CloseHandle(ulong hObject ) Library "kernel32.dll" 

FUNCTION
 boolean ReadFile(ulong fhand, 

&
 ref string lpbuffer, 

&
 ulong numbyte, 

&
 ref ulong bytesread, 

&
 ulong lpover) LIBRARY "kernel32.dll" 

FUNCTION
 ulong CreateFileA(ref string fname, 

&
 ulong f_access, 

&
 ulong f_share, 

&
 ulong f_sec, 

&
 ulong f_create, 

&
 ulong f_flag, 

&
 ulong f_attrib) LIBRARY "kernel32.dll" 

Function
 Boolean WriteFile(uLong handle,

&
 ref string lpbuffer, 

&
 ulong numbytes, 

&
 ref ulong bytesread, 

&
 ulong lpOverLaped) Library "Kernel32.dll" 

Function
 Boolean GetCommProperties(ulong hFile,

&
 ref COMMPROP lpCommProp ) Library "Kernel32.dll" 

Function
 Boolean BuildCommDCBA(ref string lpDef,

&
 ref DCB lpDCB ) Library "Kernel32.dll" 

Function
 Boolean SetCommState(ulong hCommDev,

&
 ref DCB lpdcb ) Library "Kernel32.dll" 

Function
 Boolean GetCommState(ulong hCommDev,

&
 ref DCB lpdcb ) Library "Kernel32.dll" 

Function
 ulong GetLastError() Library "Kernel32.dll" 

Function
 Boolean SetCommTimeouts(ulong hCommDev,

&
 ref COMMTIMEOUTS lpctmo ) Library "Kernel32.dll"

Function
 Boolean PurgeComm(ulong hCommDev, 

&
 ulong fdwAction ) Library "Kernel32.dll" 
实例变量定义: 
ulong iu_file 
string is_buffer
//
数据缓冲 
string is_valid_num 
=
 "
123
" 
//
有效数据
第二是初始设置 
string ls_com,ls_commset 
dcb lst_dcb 
ls_com 
=
 "COM1" 
//

ib_reading 
=
 true 
//
打开串口 
iu_file 
=
 CreateFileA(ls_com,
3221225472
,
0
,
0
,
3
,
128
,
0
) 

if
 (iu_file 
<
 
0
) 
then
 
messagebox("错误","无法打开" 
+
 ls_com 
+
 " #" 
+
 string(getlasterror ( )),StopSign!) 

end
 
if
 
//
初始化DCB 
ls_commset 
=
 "
4800
,N,
8
,
1
" 

if
 (
Not
 BuildCommDcbA ( ls_commset, lst_dcb )) 
then
 
messagebox("错误","无法创建DCB" 
+
 " #" 
+
 string(getlasterror ( )),StopSign!) 

end
 
if
 

//
设置串口 

if
 (
Not
 setcommstate ( iu_file, lst_dcb )) 
then
 
messagebox("错误","无法设置串口"
+
 ls_com 
+
 " #" 
+
 string(getlasterror ( )),StopSign!) 


end
 
if


//
设置超时 
commtimeouts lst_to lst_to.readintervaltimeout 
=
 
4294967295
 
//
MAXDWORD 
//

lst_to.readtotaltimeoutconstant 
=
 
60000
 
//

lst_to.readtotaltimeoutmultiplier 
=
 
10
 
SetCommTimeouts(iu_file, lst_to)
第三步:读或写(例子中的是读,写可用writefile) 
ulong lu_bytesread, lu_numbytes 
string ls_buff 
ulong lstr_locstruct 
//
注意!这是ULONG 而不是STRUCT 
ls_buff 
=
 
space
(
100
) 
setnull(lstr_locstruct) 
lu_numbytes 
=
 
100
 

if
 (
not
 readfile ( iu_file, ls_buff, lu_numbytes, 
&
 lu_bytesread, lstr_locstruct)) 

then
 
messagebox("错误","无法读取 #" 
+
 string(getlasterror ( )),StopSign!) 
timer(
0
) 

else


if
( lu_bytesread 
>
 
0
) 
then
 
is_buffer 
+=
 trim(ls_buff) mle_1.
text
 
+=
 trim(ls_buff) 
//
处理数据 
this.wf_is_valid_receieve ( ) 
//
检验函数 

end
 
if
 

end
 
if

第四步:完成后释放端口 
closehandle ( iu_file )


设计串口通讯程序 
 
  PB是一种面向对象的、具有可视图形界面的、快速的交互式开发工具,它通过不同数据库采用各自的专用接口或通过ODBC接口,同时支持多种关系数据库系统、支持多文档界面(MDI)、对象嵌入与链接(OLE)、动态数据交换(DDE)。利用其独特的数据窗口对象,无须编写SQL语句,便可直接对数据库进行查询、修改、插入、删除、浏览、打印,以多种文件格式打开和存储数据,因此深受广大用户的欢迎。在实际应用过程中经常遇到PowerBuilder与其它设备通过串口进行通讯的程序设计如IC卡应用系统中需通过串口与IC卡读写器进行通讯;在控制系统中,需通过串口与下位机进行通讯。下面介绍PowerBuilder5.0中常用的两种串口通讯设计方法。 

一、调用Windows SDK函数进行串口通讯

1
、Windows SDK函数介绍 
OpenComm

int
 OpenComm(LpszDevControl,
CbInQueue,cbOutQueue)
LPCSTR lpszdevcontro
l 设备控制信息的地址
UINT CbInQueue
接受队列的大小(以字节为单位)
UINT cbOutQueue
发送队列的大小
返回:如调用成功,返回值标示此打开的设备否则其返回值小于0
·CloseComm

Int
 CloseComm(idComDev)

Int
 idComDey 要关闭的设备
返回值:调用成功返回0,否则返回负值
·WriteComm

int
 WriteComm(idComDev,lpvBuf,cbWrite)

int
 idComDev 通讯设备标示符
const void FAR 
*
 lpvBuf 数据缓存区地址

int
 ,cbWrite 要写的长度
返回值:如果成功返回所写的字节数,否则返回值小于0
·ReadComm

Int
 ReadComm(idComDev,lpvBuf,cbRead)

int
 idComDev 通讯设备标示符
const void FAR 
*
 lpvBuf 数据缓存区地址

int
 cbRead 要读的字节数
返回值:如果成功返回所读的字节数,否则返回值小于0
·FlushComm

Int
 FluseComm(idComDev,fnQueue)

Int
 idComDev 通讯设备标示符

Int
 fnQueue 要刷新的队列
返回值:成功时返回0,否则返回为负


2
、示例: 
  图一(略)为一人事管理系统中的查询窗口。如果想与被查询人拨打电话,可输入该人姓名,在输入过程中,数据窗口会显示满足要求的所有人姓名,双击该行即将该人电话号码显示于单行编辑窗内,然后按“拨号”按钮即可。 

程序设计如下: 
在窗口设计菜单中选取:Declare菜单?
Declare
 External 
Function
 输入: 

Function
 
int
 OpenComm(String Comm,
Uint Inqueue,Uint Outqueue)Library
“
USER
.EXE”

Function
 
int
 CloseComm(
int
 lpt)Library
“
USER
.EXE”

Function
 
int
 WriteComm(
int
 lpt,String
buf,
int
 Size) Library “
USER
.EXE”

Function
 
int
 FlushComm(
int
 lpt,

int
 no_que)Library “
USER
.EXE”

“拨号”按钮的”Clicked” 事件编程如下:

int
 ret
String port_2,ph_code
port_2
=
”Com2”

//
取单行编辑框内容,并用atdt拨号
ph_code
=
”atdt”
+
sle_code
+

~
r
~
n”

//
打开串口
ret
=
OpenComm(port_2,
128
,
128
)

//
拨号开始
FlushComm(ret,
0
)
FlushComm(ret,
1
)
WriteComm(ret,ph_code,
len
(ph_code))
WriteComm(ret,”
~
r
~
n”,
2
)
CloseComm(ret)

二、 利用Microsoft公司提供的通讯控件
  利用Microsoft公司提供的通讯控件(Mscomm.vbx,用于16位通讯程序、Mscomm32.ocx用于开发32位通讯程序)可方便实现串口通讯。

1
、常用属性 
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:返回并删除接受缓冲区的数据。 


2
、 示例: 
  下面举一接收程序示例:制作一通讯接收窗口,选择菜单Controls→OLE→
Insert
 Control→Microsoft Communications Control,在窗口中出现通信控件图标单击鼠标右键,选择OCX Properties设置常用属性,也可在程序中进行设置窗口的Open事件程序如下
ole_1.object.CommPort
=
2

ole_1.object.Settings
=
"
9600
,N,
8
,
1
"
ole_1.object.PortOpen
=
ture
ole_1.object.Rthreshold
=
10

ole_1.object..Inputlen
=
0

.
.
通信控件的oncomm事件的程序如下
choose 
case
 ole_1.object.CommEvent

case
 comEventBreak 
//
接收到中断信号

case
 comEventCDTO 
//
处理CD超时
.
.
.

case
 comEvReceive
sle_1.
text
=
ole_1.object.Input
.
.

end
 choose

以上是一个基本的例子,在实际应用过程中应根据不同的情况进行不同的设计,如波特率、帧格式等。 


 

 

 

你可能感兴趣的:(编程,Microsoft,F#,嵌入式,PowerBuilder)