VB接收到PLC的十六进制码如何转为10进制码? 点击:0 | 回复:24



lenny

    
  • 精华:1帖
  • 求助:0帖
  • 帖子:2帖 | 45回
  • 年度积分:0
  • 历史总积分:110
  • 注册:2003年7月29日
发表于:2003-07-31 09:57:00
楼主
大家好!本人最近使用VB6.0的MSCCOM控件与PLC通讯,PLC送过来的数据在PC端均显示为16进制数,如何把它转为十进制数呢?我前段时间也看过类似问题的贴子,现在我也遇到此问题,希望VB高手提供脚本程序?在此多谢大家了!急!!!



关公

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 72回
  • 年度积分:0
  • 历史总积分:126
  • 注册:2003年7月07日
发表于:2003-07-29 10:55:00
1楼
设s是待转换的16进制/8进制数或字串: 16进制HEX -> 10进制DEC: Val("&H" & s) 8进制OCT -> 10进制DEC: Val("&O" & s)

gongkongedit

  • 精华:1099帖
  • 求助:0帖
  • 帖子:14399帖 | 54471回
  • 年度积分:0
  • 历史总积分:579
  • 注册:2008年9月08日
发表于:2003-07-29 11:30:00
2楼
那反过来,如果我想把十进制数转换为十六进制或八进制数呢? 请问在VB中怎么做?有没有现成的函数?请教各位!

gongkongedit

  • 精华:1099帖
  • 求助:0帖
  • 帖子:14399帖 | 54471回
  • 年度积分:0
  • 历史总积分:579
  • 注册:2008年9月08日
发表于:2003-07-29 11:31:00
3楼
那反过来,如果我想把十进制数转换为十六进制或八进制数呢? 请问在VB中怎么做?有没有现成的函数?请教各位!

关公

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 72回
  • 年度积分:0
  • 历史总积分:126
  • 注册:2003年7月07日
发表于:2003-07-29 11:33:00
4楼
Hex(s)和Oct(s)

gongkongedit

  • 精华:1099帖
  • 求助:0帖
  • 帖子:14399帖 | 54471回
  • 年度积分:0
  • 历史总积分:579
  • 注册:2008年9月08日
发表于:2003-07-29 12:05:00
5楼
知道了。 谢谢你,关公!

lenny

  • 精华:1帖
  • 求助:0帖
  • 帖子:2帖 | 45回
  • 年度积分:0
  • 历史总积分:110
  • 注册:2003年7月29日
发表于:2003-07-29 19:16:00
6楼
非常感谢关公和hustsup两位先生的贴子,但我在按关公先生的方法试着搞时,又遇到问题,首先我在此交代一下,如我接收的字据是不确定的,我在脚本程序中把所有的数据(不管长度)经过转换均放在buf中,然后在TextBox控件中显示出来,显示脚本程序为:txtReceive.Text=buf,然后我可以把接收到的字数已按16进制显示出来了,如接收到的数为:C1,B0,B9,B9,B9,B8,8D;然后我按关公的提示在脚本程序中加了如下的脚本程序: txtVal=Val("&h"&buf); 然后txtReceive.Text=buf改为 txtReceive.Text=txtVal;(注此处由原来buf改为txtVal) 然后其它不变. 编译执行之后提示实时错误为:溢出,并指出错误在增加的句子处,即:txtVal=Val("&h"&buf)错误! 请问关公你所教的方法是不是只是一个单独数据可转换,太多了则会溢出,应当怎么增加脚本程序呢? 希望能得到关公大哥的指点,在此多谢了!

关公

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 72回
  • 年度积分:0
  • 历史总积分:126
  • 注册:2003年7月07日
发表于:2003-07-30 03:14:00
7楼
用Val()函数变换一个大于Long型的16进制数时会产生溢出。 如:Val("&H" & "C1B0B9B9B9B88D") 时产生溢出; 但如:Val("&H" & "C1,B0,B9,B9,B9,B8,8D") 时,由于逗点的分隔,它在遇到第一个非16进制字符时就结束,其结果只是第一个数得到变换,因此它不会溢出。 以上方法都不能把各个数据分离出来,正确的方法是用对应类型和下标量的数组,多次变换对应装入。 或仍用一个字符串变量逐个进行:数制变换->加分隔符->串接.

关公

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 72回
  • 年度积分:0
  • 历史总积分:126
  • 注册:2003年7月07日
发表于:2003-07-30 04:53:00
8楼
还请注意:FX-PLC总是返回以字节为单位的16进制字串,用它表示位元件时不会有问题,但如果它表示的是字元件的值,是成对出现且低字节在前,高字节在后的。如返回"C1B0"是D0的值的话,应理解为:D0 = B0C1h = 45249。 同理如“12345678”是某个双字元件的值时,则应理解为:78563412h。

lenny

  • 精华:1帖
  • 求助:0帖
  • 帖子:2帖 | 45回
  • 年度积分:0
  • 历史总积分:110
  • 注册:2003年7月29日
发表于:2003-07-30 09:24:00
9楼
非常感谢关大哥的贴子,我一早就上来看你的贴子,无奈小女子才疏学浅,对VB不是很熟,所以按你的方法东撞西撞还是不得要领.对了,原来我这程序是用来跟PLC通讯的,但现在是跟一个仪表通讯,所以读出来的数是长短不一的,这样好不好,我把接收的全部程序放在贴子里,烦关大哥帮忙一下如何,如修改好之后可发邮件到:LLL_Lenny@163.com给我,接收的程序如下: Private Sub Comm1_OnComm() Select Case Comm1.CommEvent Case comEvCD Case comEvCTS Case comEvDSR Case comEvRing Case comEvReceive Dim i%, Buf$ Buf = "" InByte = Comm1.Input For i = LBound(InByte) To UBound(InByte) Buf = Buf + Hex(InByte(i)) + Chr(13) & Chr(10) Next i txtReceive.Text = Buf Case comEvSend End Select End Sub 我是利用了MSCOMM控件的OnComm事件之CommEvent属性来触发接收,其中InByte在前面有局部声明:Dim InByte() As Byte 请关大哥帮忙修改如何?小女子在此多谢了.

关公

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 72回
  • 年度积分:0
  • 历史总积分:126
  • 注册:2003年7月07日
发表于:2003-07-30 10:33:00
10楼
我不知道你与这个仪表通讯的数据格式,文本型?/二进制型? 串行通讯数据包中通常含有:起始符-数据-结束-校验等部分.你接收后就忙于把它的全部作转换和串接,这是不妥的,因为上述的各部分信息未必全是二进制单字节的表达,更不能10进制变16进制的Hex()函数作其转换的通式. 如果不知道Comm1.Input里的内容,可先试将接收格式设置为文本,把它全部直接在txtReceive.Text里显示出来,看那些是你要的数据部分,它们以什么形式出现在txtReceive.Text里,然后再决定表示它们的方式. 建议你先用Execl电子表格的VBA编程,它每张工作表都可看作是一个视窗控件,每个单元都可是一个Variant类,既可容纳任意类型的数据,多个单元又可以作数组,保存时又可包括你的源程序和已在表格中的数据...

lenny

  • 精华:1帖
  • 求助:0帖
  • 帖子:2帖 | 45回
  • 年度积分:0
  • 历史总积分:110
  • 注册:2003年7月29日
发表于:2003-07-30 14:34:00
11楼
谢谢关大哥的贴子,如果我只是简单地直接用:txtReceive.Text=comm1.Input,那么读过来的数据是:????1,显然这样做是不行的,前面还必须设置成什么格式对不? 可能我还是没有说清楚目前的情况,我把我自己目前的进展情况说一下吧,我用WINDOWS 2000的超级终端读写数据时完全没有问题,如我起动超级终端后,键盘输入请求读出当前测量值的大写"A"(协议确定"A"是申请读出测量值),则返回"A09998",而此时仪表上的显示的测量值是:9.998,说明是可以的;当我用前面给你的VB程序读取时,则显示为"C1B0B9B9B9B88D",很显然这表明也正确读出来了,比较仪表及用超级终端读出来的结果是一致的,把"C1"和"8D"这前后两个去掉,再把每个数前面的"B"去掉就是想要的结果"09998",我开始进也搞混了,实际可以说读出的并不是十六进制数,对不? 但如何把不要的去掉呢?我的确搞不了. 关大哥,你说用Excel表格方法,我更不知如何用了,如果可以的话,我可否把协议发到你邮箱去,你看一下怎么搞好!多谢.如果你同意的话,我就把协议发给你.

关公

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 72回
  • 年度积分:0
  • 历史总积分:126
  • 注册:2003年7月07日
发表于:2003-07-30 14:48:00
12楼
我的EMAIL:qing59050@vip.sina.com

lenny

  • 精华:1帖
  • 求助:0帖
  • 帖子:2帖 | 45回
  • 年度积分:0
  • 历史总积分:110
  • 注册:2003年7月29日
发表于:2003-07-30 15:28:00
13楼
关大哥,我这就给你发过去.多谢!

求学路

  • 精华:0帖
  • 求助:0帖
  • 帖子:2帖 | 12回
  • 年度积分:0
  • 历史总积分:18
  • 注册:2003年7月24日
发表于:2003-07-30 15:57:00
14楼
关公: 能不能把解决方案也给小弟一分,小弟也想学。 蔡蔡。

lenny

  • 精华:1帖
  • 求助:0帖
  • 帖子:2帖 | 45回
  • 年度积分:0
  • 历史总积分:110
  • 注册:2003年7月29日
发表于:2003-07-30 16:10:00
15楼
关大哥,我已把脚本程序和协议发给你了,俺就看你的了,先谢你啦!

CQSZL

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 1回
  • 年度积分:0
  • 历史总积分:1
  • 注册:2003年9月04日
发表于:2003-07-31 05:42:00
16楼
既然知道了数据的规律,就直接用字符串截取函数取出要的,舍去不要的就行了吧。

lenny

  • 精华:1帖
  • 求助:0帖
  • 帖子:2帖 | 45回
  • 年度积分:0
  • 历史总积分:110
  • 注册:2003年7月29日
发表于:2003-07-31 09:31:00
17楼
关大哥,早上好!真是很感谢你,按你的方法,终于搞掂了,你真是太高明了,以后一定多多向你讨教.在此我还要一并感谢所有关注此问题的同行朋友,谢谢你们,再次谢谢关大哥.

关公

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 72回
  • 年度积分:0
  • 历史总积分:126
  • 注册:2003年7月07日
发表于:2003-07-31 09:48:00
18楼
to lenny: "C1,B0,B9,B9,B9,B8,8D" 与 "A09998<CR>",正好存在一个等差80h,这不是数制转换的问题,是通讯口参数未设置好,使得每个ASCII字符的最高位(位7)都是1。 那个MSComm1.Settings = ? ,是对硬件的设置,必须与对话设备完全一致。

lenny

  • 精华:1帖
  • 求助:0帖
  • 帖子:2帖 | 45回
  • 年度积分:0
  • 历史总积分:110
  • 注册:2003年7月29日
发表于:2003-07-31 09:51:00
19楼
CQSZL:你好!你提出的方法我也想试一试,是不是利用Mid?可是我还是有疑问,为什么呢?因为我说过所传的数据长度不一样时,怎么适用各种变化的情况?即使长度一致,用Mid去掉头和尾,但夹在中间的还有很多如何去掉?就拿我上面所说的"C1B09B9B9B9B88D",可用Mid("C1B0B9B9B9B88D",4,9),得到"0B9B9B9B8",再用什么办法把中间的"B"去掉并最终得到"09998",虽然仍可以用Mid进行多次取出,但仍要多次排列对不对?也许我的方法好笨,不知道你有什么办法?还有就是如何对负长度不一样的情况出现?请易教

lenny

  • 精华:1帖
  • 求助:0帖
  • 帖子:2帖 | 45回
  • 年度积分:0
  • 历史总积分:110
  • 注册:2003年7月29日
发表于:2003-07-31 09:57:00
20楼
关大哥,你说得对极了,就是设数据位为7即好了.

相关主题

官方公众号

智造工程师
首页 上一页 1 2 下一页 尾页