主题:[原创]在Vfp9中用Mscomm.ocx控件进行串口通信的经验
zfh630528
[专家分:130] 发布于 2009-05-11 22:33:00
近来,本讨论区中不断有人提及串口接、发的问题。现把本人多年来积累的经验贴出来。
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个回复)
沙发
琅拿度 [专家分:2820] 发布于 2009-05-12 09:47:00
感谢! 想知道更多...欢迎有经验的朋友多发。
板凳
foxdb [专家分:1830] 发布于 2009-05-14 08:27:00
看来,楼主的的经验积累的还是不够多,没能看出“ 新手狐友们”的问题所在!
问题出在 VFP 的 ASC( ) 和 CHR()函数的转换上,就凭CRETEBINARY()函数也是不能解决问题的,这和COM口的发送与接收无关!
foxpro帮助中说明:
asc( ) 函数返回字符在当前代码页字符表中所处的位置。每个字符都有唯一的 0-255 之间的 ANSI 值。
CHR()指定一个介于 0 和 255 之间的数值,CHR( ) 返回与之对应的 ANSI 字符。
使用 ASC( ) 可以返回一个指定字符的 ANSI 值。
新手狐友们就是轻信了这两条没“看懂”最后一条
最后一条说明
CHR( ) 根据当前代码页字符表中字符的数值位置返回其对应的字符。可用 CHR( ) 向打印机发送打印控制代码。
好了来看看TEST结果吧!
就那用你说的 CRETEBINARY()函数 试吧....
3 楼
foxdb [专家分:1830] 发布于 2009-05-14 09:15:00
比如:
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 楼
foxdb [专家分:1830] 发布于 2009-05-14 09:16:00
*********************
那当
A0='00'
B1=Createbinary(chr(hex2dec(A0)))
B4=dec2hex(ASC(B1))
?B4
B4是否就等于 '00' 呢?
试试看吧!我所说的“零”字符就是由此而来!COM收发时带来的结果不丢掉就是变成了"20"原因自己去想吧。。。
这也让我想起一个故事:
一个数学专家和一个幼儿园小朋友数数的故事,小朋友数得是9,可专家怎么数都是8,你知道为什么吗?我想新手狐友们的问题大概就出在这,太相信"专家"了!
5 楼
zfh630528 [专家分:130] 发布于 2009-05-14 23:23:00
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 楼
zfh630528 [专家分:130] 发布于 2009-05-14 23:50:00
更正下面的文字“**需要进一步说明的是,用表单中的控件(文本框、编辑框等)直接显示B1,文本框显示32(0字符的ascii码),编辑框显示0(0字符);显
示B2时,文本框、编辑框显示的结果均是0(0字符),这就是接收时transform()函数的用处。”
更正为“**需要进一步说明的是,用表单中的控件(文本框、编辑框等)直接显示B1,文本框显示0(ascii码),编辑框不显示;显示B2时,文本框、编辑框显示的结果均是0(0字符),这就是接收时transform()函数的用处。”
7 楼
zfh630528 [专家分:130] 发布于 2009-05-15 00:16:00
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 楼
foxdb [专家分:1830] 发布于 2009-05-15 06:43:00
楼主 :
解释一下
******************************************
* hex2dec() *
* 16进制转换为10进制 *
* 传入16进制数可以为数值型也可以字符型 *
* 传出10进制数 *
* ****************************************
**********************************
* dec2hex() *
* 十进制数转化为十六进制字符串 *
* 传入参数十进制数或字符串 *
* 传出十六进制字符串 *
* ********************************
9 楼
foxdb [专家分:1830] 发布于 2009-05-15 06:55:00
*楼主:
&&既然楼主这么认真!我就以一个“狐狸新手”的视角和心态来讨论吧,希望你不介意!
*我想要的结果是 发送 A1="00" 接受到的B2也要="00"
10 楼
foxdb [专家分:1830] 发布于 2009-05-15 07:26:00
*可我用楼主的代码测试结果是:
*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
&&&&& 按你的方法我的问题还是没有得到解决!如果我理解有错请明示.......
我来回复