回 帖 发 新 帖 刷新版面

主题:[原创]在Vfp9中用Mscomm.ocx控件进行串口通信的经验

近来,本讨论区中不断有人提及串口接、发的问题。现把本人多年来积累的经验贴出来。

Vfp9的Mscomm.ocx控件传递数据时需要使用二进制字符型数据。在 Visual FoxPro 中,二进制数据可以包含在字符串中。但 ActiveX 控件和 OLE 对象中的字符串 (OLE VT_BSTR 数据类型) 不能包含二进制数据。ActiveX 控件和 OLE 对象通过 VT_UI1 类型数组与 Visual FoxPro 传递二进制形式的数据。

ActiveX 控件和 OLE 对象通过 VT_UI1 类型的数组将二进制数据传递给 Visual FoxPro后。Visual FoxPro 自动将它转换为 Visual FoxPro 字符串的形式,但 Visual FoxPro 内部会把由 ActiveX 控件和 OLE 对象传递来的字符串标记为二进制字符串。当需要把数据传回 ActiveX 控件和 OLE 对象时,Visual FoxPro 再自动将它们转换为 VT_UI1 类型的数组。

如果您需要把一个 Visaul FoxPro 字符串传递给 ActiveX 控件和 OLE 对象,您必须首先使用 CRETEBINARY()函数将它转换为二进制字符串形式。


Vfp9的Mscomm.ocx控件,对Ascii码0——255的发送与接收的方法:

发送端:如发送Ascii码为167的字符,
......................
Thisform.olecontrol1.Output=Createbinary(CHR(167))
......................

接收端:
......................
cString=transform(This.Input)
?cString    && 显示167的十六进制字符“A7”

欢迎讨论!不妥处请VfpFans指正。

回复列表 (共15个回复)

沙发

感谢! 想知道更多...欢迎有经验的朋友多发。

板凳

看来,楼主的的经验积累的还是不够多,没能看出“ 新手狐友们”的问题所在!

问题出在 VFP 的 ASC( ) 和 CHR()函数的转换上,就凭CRETEBINARY()函数也是不能解决问题的,这和COM口的发送与接收无关!


foxpro帮助中说明:

asc( ) 函数返回字符在当前代码页字符表中所处的位置。每个字符都有唯一的 0-255 之间的 ANSI 值。

CHR()指定一个介于 0 和 255 之间的数值,CHR( ) 返回与之对应的 ANSI 字符。
使用 ASC( ) 可以返回一个指定字符的 ANSI 值。

新手狐友们就是轻信了这两条没“看懂”最后一条

最后一条说明
CHR( ) 根据当前代码页字符表中字符的数值位置返回其对应的字符。可用 CHR( ) 向打印机发送打印控制代码。

好了来看看TEST结果吧!

就那用你说的 CRETEBINARY()函数 试吧....

3 楼

比如:

A0='FF'

B1=Createbinary(chr(hex2dec(A0)))
B2=dec2hex(ASC(B1))

?B2  B3="FF"

*************
 
A0='A7'

B1=Createbinary(chr(hex2dec(A0)))
B3=dec2hex(ASC(B1))

?B3  B3="A7"

这两个都没错!

那当A0="00" 的时候呢?

4 楼

*********************
那当  

A0='00'

B1=Createbinary(chr(hex2dec(A0)))
B4=dec2hex(ASC(B1))

?B4  

B4是否就等于 '00'  呢?

试试看吧!我所说的“零”字符就是由此而来!COM收发时带来的结果不丢掉就是变成了"20"原因自己去想吧。。。

这也让我想起一个故事:

一个数学专家和一个幼儿园小朋友数数的故事,小朋友数得是9,可专家怎么数都是8,你知道为什么吗?我想新手狐友们的问题大概就出在这,太相信"专家"了!

5 楼

foxdb朋友,可以这样称呼你吧?
阁下在2、3、4楼的分析,本人相信其中一部分,不能全部苟同,为什么呢?请听我的分析。

本楼主在阐述中,指的是用mscomm.ocx控件进行串口通信时,对上位机(微机)处理发送、接收数据处理的方法,突出指明了0——255ascii码

字符是可以正确传送的。只是在发送前和接收后,要进行适当的数据处理。关键是函数Createbinary()和transform()的合理使用。当然,具体

问题要具体对待,如用自定义函数处理相应的数据,也可以达到自己的特殊目的。

从foxdb朋友的回贴中,本人看出几点需要继续商酌的问题:

1. 本人阐述的是在VFP下用mscomm.ocx控件进行串口通信的问题。发送前,需要写入数据缓冲区的是大二进制(Q型)数据,之后,VFp自动转

换为ascii码发送出去。这与阁下所谓的“ASC( ) 和CHR()函数的转换问题”无关。

三种数据的对照表如下:

Q型(十六进制)       ascii(十进制)     C型(十六进制)
0h00                     00                  00
0h01                     01                  01
0h02                     02                  02
.........................
0h0A                     10                  0A
0h0B                     11                  0B
.........................
0h7F                     127                 7F
.........................
0hF7                     247                 F7
.........................
0hFF                     255                 FF

Vfp发送端示例代码:
A1="00"
A2=Createbinary(CHR(EVALUATE('0x'+A1)))
?A2   && 返回值为0h00 (Q型)
Thisform.olecontrol1.Output=A2
此时,VFp发出的是ascii为00的数据(十进制)


又如:
A1="1B"
A2=Createbinary(CHR(EVALUATE('0x'+A1)))
?A2   && 返回值为0h1B (Q型)
Thisform.olecontrol1.Output=A2
此时,VFp发出的是ascii为27的数据(十进制)


再如:
A1="DB"
A2=Createbinary(CHR(EVALUATE('0x'+A1)))
?A2   && 返回值为0hDB (Q型)
Thisform.olecontrol1.Output=A2
此时,VFp发出的是ascii为219的数据(十进制)

2.VFP用mscomm.ocx控件进行串口通信,接收下位机(如单片机、打印机等)的数据(ascii码)时,Vfp通过mscomm.ocx控件自动地把ascii码

转换为Q型数据。

VFp接收端示例代码:

若下位机传送来的数据是00(ascii码)
B1=Thisform.olecontrol1.input
?B1    && 返回值为0h00 (Q型)
B2=transform(B1)
?B2    && 返回值为00(C型)

又如:若下位机传送来的数据是27(ascii码)
B3=Thisform.olecontrol1.input
?B3    && 返回值为0h1B(Q型)
B2=transform(B3)
?B2    && 返回值为1B(C型)

再如:若下位机传送来的数据是219(ascii码)
B4=Thisform.olecontrol1.input
?B4    && 返回值为0hDB(Q型)
B2=transform(B4)
?B2    && 返回值为DB(C型)

**需要进一步说明的是,用表单中的控件(文本框、编辑框等)直接显示B1,文本框显示32(0字符的ascii码),编辑框显示0(0字符);显

示B2时,文本框、编辑框显示的结果均是0(0字符),这就是接收时transform()函数的用处。

3.Foxdb朋友的hex2dec()和dec2hex()是自定义函数吧,这两个函数在这里使用是有问题的(猜测的),可能是数据类型的问题。不是asc()和

chr()的错!请阁下把两个自定义函数贴出来,让大家分析一下。

本人欢迎Vfpfans就此问题继续讨论。好了,说了这么多,很累了,休息了,明天再来。











6 楼

更正下面的文字“**需要进一步说明的是,用表单中的控件(文本框、编辑框等)直接显示B1,文本框显示32(0字符的ascii码),编辑框显示0(0字符);显

示B2时,文本框、编辑框显示的结果均是0(0字符),这就是接收时transform()函数的用处。”


更正为“**需要进一步说明的是,用表单中的控件(文本框、编辑框等)直接显示B1,文本框显示0(ascii码),编辑框不显示;显示B2时,文本框、编辑框显示的结果均是0(0字符),这就是接收时transform()函数的用处。”


7 楼

foxdb朋友,可以这样称呼你吧?
阁下在2、3、4楼的分析,本人相信其中一部分,不能全部苟同,为什么呢?请听我的分析。

本楼主在阐述中,指的是用mscomm.ocx控件进行串口通信时,对上位机(微机)处理发送、接收数据处理的方法,突出指明了0——255ascii码字符是可以正确传送的。只是在发送前和接收后,要进行适当的数据处理。关键是函数Createbinary()和transform()的
合理使用。当然,具体问题要具体对待,如用自定义函数处理相应的数据,也可以达到自己的特殊目的。

从foxdb朋友的回贴中,本人看出几点需要继续商酌的问题:

1. 本人阐述的是在VFP下用mscomm.ocx控件进行串口通信的问题。发送前,需要写入数据缓冲区的是大二进制(Q型)数据,之后,VFp自动转换为ascii码发送出去。这与阁下所谓的“ASC( ) 和CHR()函数的转换问题”无关。

三种数据的对照表如下:

Q型(十六进制)       ascii(十进制)     C型(十六进制)
0h00                     00                  00
0h01                     01                  01
0h02                     02                  02
.........................
0h0A                     10                  0A
0h0B                     11                  0B
.........................
0h7F                     127                 7F
.........................
0hF7                     247                 F7
.........................
0hFF                     255                 FF

Vfp发送端示例代码:
A1="00"
A2=Createbinary(CHR(EVALUATE('0x'+A1)))
?A2   && 返回值为0h00 (Q型)
Thisform.olecontrol1.Output=A2
此时,VFp发出的是ascii为00的数据(十进制)


又如:
A1="1B"
A2=Createbinary(CHR(EVALUATE('0x'+A1)))
?A2   && 返回值为0h1B (Q型)
Thisform.olecontrol1.Output=A2
此时,VFp发出的是ascii为27的数据(十进制)


再如:
A1="DB"
A2=Createbinary(CHR(EVALUATE('0x'+A1)))
?A2   && 返回值为0hDB (Q型)
Thisform.olecontrol1.Output=A2
此时,VFp发出的是ascii为219的数据(十进制)

2.VFP用mscomm.ocx控件进行串口通信,接收下位机(如单片机、打印机等)的数据(ascii码)时,Vfp通过mscomm.ocx控件自动地把ascii码转换为Q型数据。

VFp接收端示例代码:

若下位机传送来的数据是00(ascii码)
B1=Thisform.olecontrol1.input
?B1    && 返回值为0h00 (Q型)
B2=transform(B1)
?B2    && 返回值为00(C型)

又如:若下位机传送来的数据是27(ascii码)
B3=Thisform.olecontrol1.input
?B3    && 返回值为0h1B(Q型)
AB2=transform(B3)
?AB2    && 返回值为1B(C型)

再如:若下位机传送来的数据是219(ascii码)
B4=Thisform.olecontrol1.input
?B4    && 返回值为0hDB(Q型)
BB2=transform(B4)
?BB2    && 返回值为DB(C型)

**需要进一步说明的是,用表单中的控件(文本框、编辑框等)直接显示B1变量(值为0h00),文本框显示0(ascii的十六进制),编辑框不显示(空字符);显示B2时,文本框、编辑框显示的结果均是0(0字符);
用表单中的控件(文本框、编辑框等)直接显示B3变量(值为0h1B),文本框显示1B(ascii的十六进制),编辑框显示""(ASCII为0x1B的字符);显示AB2时,文本框、编辑框显示的结果均是1B(C型字符)。
这就是接收时transform()函数的用处。

3.Foxdb朋友的hex2dec()和dec2hex()是自定义函数吧,这两个函数在这里使用是有问题的(猜测的),可能是数据类型的问题。不是asc()和chr()的错!请阁下把两个自定义函数贴出来,让大家分析一下。

本人欢迎Vfpfans就此问题继续讨论。好了,说了这么多,很累了,休息了,明天再来。

8 楼

楼主 :

解释一下  

******************************************
*  hex2dec()                           *
*  16进制转换为10进制                    * 
*  传入16进制数可以为数值型也可以字符型  * 
*  传出10进制数                          * 
* ****************************************


**********************************
*  dec2hex()                   * 
*  十进制数转化为十六进制字符串  * 
*  传入参数十进制数或字符串      * 
*  传出十六进制字符串            * 
* ********************************

9 楼

*楼主: 
     &&既然楼主这么认真!我就以一个“狐狸新手”的视角和心态来讨论吧,希望你不介意!

*我想要的结果是  发送 A1="00"  接受到的B2也要="00"

10 楼

*可我用楼主的代码测试结果是:

*Vfp发送端示例代码:
A1="00"
A2=Createbinary(CHR(EVALUATE('0x'+A1)))
?A2   && 返回值为0h00 (Q型) *注 A 
*Thisform.olecontrol1.Output=A2
*此时,VFp发出的是ascii为00的数据(十进制)


B1=A2  &&我根据 *注 A 与 *注 B 的理解

&&我的理解是“发出的”是ascii为00的数据“接收的是”数据是00(ascii码)那么B1 A2应该相等的

*若下位机传送来的数据是00(ascii码)
*B1=Thisform.olecontrol1.input
?B1    && 返回值为0h00 (Q型) *注 A
B2=transform(B1)

?B2    && 返回值为00(C型) 可我没看到显示是 00 啊?
?A1    && 这到是可显示一看到是 00 

&&&&&  按你的方法我的问题还是没有得到解决!如果我理解有错请明示.......

我来回复

您尚未登录,请登录后再回复。点此登录或注册