技术论坛

如何将某个字节VB**的最低7位和最高位分别读出,并分别转换成另外两个字节??

作者 主题
游民

经验值: 129
发帖数: 19
精华帖: 0
主题:【求助】如何将某个字节VB**的最低7位和最高位分别读出,并分别转换成另外两个字节??


只看楼主 楼主 2021-01-18 12:46:27

如何将某个字节VB**的最低7位和最高位分别读出,并分别转换成另外两个字节??

现在连接485仪表信号时,需要将某个字节的位拆分转换,但不清楚改用什么编程指令。该仪表485协议部分如下:

1、 读当前电流和状态标志命令:起始地址为:0Xa000。响应的寄存器值0Xyyxx。

xx:最低7位为电流大小(单位0.1A最大12A),取值范围0~120。

122~127表示电源故障。

122:散热片超温报警。123:预留。124:无负载报警。125:过载报警。126:扫描报警。

xx:最高位为超声状态标致,0表示关超声、1表示开超声。

yy:0-3BIT为功率级别,4BIT表示追频开关,6BIT表示扫频开关,7BIT表示恒流开关。

请大侠指点,在PLC程序中modbus读指令中的Addr是不是应为440961?如何将读到的VB值取出最低七位和最高位?

谢谢!!



不怕没有,只要自己有心,没有也可变为有!
以下网友喜欢您的帖子:

  
重要声明:

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

帖子链接:https://www.ad.siemens.com.cn/club/bbs/post.aspx?a_id=1670756&b_id=64&s_id=0&num=8

至圣

经验值: 67546
发帖数: 14783
精华帖: 100
回复:如何将某个字节VB**的最低7位和最高位分别读出,并分别转换成另外两个字节??


只看楼主 1楼 2021-01-18 12:55:50

字与指令就是你想要的。去了解一下。

先了解一下再问。


 
以下网友喜欢您的帖子:

  
至圣

经验值: 12573
发帖数: 2503
精华帖: 31
回复:如何将某个字节VB**的最低7位和最高位分别读出,并分别转换成另外两个字节??


只看楼主 2楼 2021-01-18 13:15:59

0xA000这种Modbus通讯地址是输出线圈,也就是位变量,你确定厂家的资料没错?用位变量来传输8个位的内容?

3xA000 、4xA000这些才是字存储的寄存器。


如果读取的是线圈,则读取地址是 40960(A000),如果读取的是输入寄存器则是340960,如果读取的是保持寄存器则是440960。还有国内很多厂家都不按标准Modbus地址编号的,所以实际的地址有可能是40959?40960?40961。这种乱七八糟的情况我在用第三方Modbus外设就都碰到过,不稀奇。


至于拆分寄存器的高低字节?可以直接取就可以了,不用特意转换。比如读取的内容放在VW100,那么VB100就是高字节、VB101就是低字节。如果VW100=16#1234,那么VB100=16#12、VB101=16#34。

最位也可以直接用V100.7获取。


 
以下网友喜欢您的帖子:

  
游民

经验值: 129
发帖数: 19
精华帖: 0
回复:如何将某个字节VB**的最低7位和最高位分别读出,并分别转换成另外两个字节??


只看楼主 楼主 3楼 2021-01-18 13:34:42
以下是引用Zaxife在2021-01-18 13:15:59的发言 >2楼

0xA000这种Modbus通讯地址是输出线圈,也就是位变量,你确定厂家的资料没错?用位变量来传输8个位的内容?

3xA000 、4xA000这些才是字存储的寄存器。


如果读取的是线圈,则读取地址是 40960(A000),如果读取的是输入寄存器则是340960,如果读取的是保持寄存器则是440960。还有国内很多厂家都不按标准Modbus地址编号的,所以实际的地址有可能是40959?40960?40961。这种乱七八糟的情况我在用第三方Modbus外设就都碰到过,不稀奇。


至于拆分寄存器的高低字节?可以直接取就可以了,不用特意转换。比如读取的内容放在VW100,那么VB100就是高字节、VB101就是低字节。如果VW100=16#1234,那么VB100=16#12、VB101=16#34。

最位也可以直接用V100.7获取。

仪表厂家提供的部分协议内容:

微信图片_20210118132656.png

微信图片_20210118132704.png

微信图片_20210118132704.png

微信图片_20210118132700.png

微信图片_20210118132651.png

用MODSCN32软件测试,读取协议中起始地址为:0Xa006的指令时,可以读出实际数值:

微信图片_20210118132759.jpg

根据上面的测试结果,读指令应该是是不是从“440961"开始?

另外,我知道单独取字节中的位值,但用什么指令可以将低位的七个位取出,再转换成另外一个数?

衷心感谢您的指点,比其他高手模棱两可的说教实用多了!!!


不怕没有,只要自己有心,没有也可变为有!
以下网友喜欢您的帖子:

  
游民

经验值: 129
发帖数: 19
精华帖: 0
回复:如何将某个字节VB**的最低7位和最高位分别读出,并分别转换成另外两个字节??


只看楼主 楼主 4楼 2021-01-18 13:48:19
以下是引用Zaxife在2021-01-18 13:15:59的发言 >2楼

0xA000这种Modbus通讯地址是输出线圈,也就是位变量,你确定厂家的资料没错?用位变量来传输8个位的内容?

3xA000 、4xA000这些才是字存储的寄存器。


如果读取的是线圈,则读取地址是 40960(A000),如果读取的是输入寄存器则是340960,如果读取的是保持寄存器则是440960。还有国内很多厂家都不按标准Modbus地址编号的,所以实际的地址有可能是40959?40960?40961。这种乱七八糟的情况我在用第三方Modbus外设就都碰到过,不稀奇。


至于拆分寄存器的高低字节?可以直接取就可以了,不用特意转换。比如读取的内容放在VW100,那么VB100就是高字节、VB101就是低字节。如果VW100=16#1234,那么VB100=16#12、VB101=16#34。

最位也可以直接用V100.7获取。

谢谢大侠的指点!

是不是根据该协议,写寄存器从”340960“开始,读保持寄存器从”40960“开始,还需要偏移1吗?

如果VB中取低位7位转换成另外一个数值,是不是直接左移7位,然后得数除以10即可?


不怕没有,只要自己有心,没有也可变为有!
以下网友喜欢您的帖子:

  
至圣

经验值: 67546
发帖数: 14783
精华帖: 100
回复:如何将某个字节VB**的最低7位和最高位分别读出,并分别转换成另外两个字节??


只看楼主 5楼 2021-01-18 14:11:31

读是440961开始,写是40001开始。

WAND_B与字节  指令。

一个字节中的8位你要的是表示电流的7个位,你就把这8个位跟2#1111111做与字节,结果就是7位的电流了。愿意听就解决问题,不愿意听就模棱两可。


 
以下网友喜欢您的帖子:

  
至圣

经验值: 12573
发帖数: 2503
精华帖: 31
回复:如何将某个字节VB**的最低7位和最高位分别读出,并分别转换成另外两个字节??


只看楼主 6楼 2021-01-21 14:47:11
以下是引用sdzcl在2021-01-18 13:34:42的发言 >3楼

仪表厂家提供的部分协议内容:

微信图片_20210118132656.png

微信图片_20210118132704.png

微信图片_20210118132704.png

微信图片_20210118132700.png

微信图片_20210118132651.png

用MODSCN32软件测试,读取协议中起始地址为:0Xa006的指令时,可以读出实际数值:

微信图片_20210118132759.jpg

根据上面的测试结果,读指令应该是是不是从“440961"开始?

另外,我知道单独取字节中的位值,但用什么指令可以将低位的七个位取出,再转换成另外一个数?

衷心感谢您的指点,比其他高手模棱两可的说教实用多了!!!

以下是引用Zaxife在2021-01-18 13:15:59的发言 >2楼:0xA000这种Modbus...

引用2楼详细内容:

0xA000这种Modbus通讯地址是输出线圈,也就是位变量,你确定厂家的资料没错?用位变量来传输8个位的内容?

3xA000 、4xA000这些才是字存储的寄存器。


如果读取的是线圈,则读取地址是 40960(A000),如果读取的是输入寄存器则是340960,如果读取的是保持寄存器则是440960。还有国内很多厂家都不按标准Modbus地址编号的,所以实际的地址有可能是40959?40960?40961。这种乱七八糟的情况我在用第三方Modbus外设就都碰到过,不稀奇。


至于拆分寄存器的高低字节?可以直接取就可以了,不用特意转换。比如读取的内容放在VW100,那么VB100就是高字节、VB101就是低字节。如果VW100=16#1234,那么VB100=16#12、VB101=16#34。

最位也可以直接用V100.7获取。

Modbus中规定3开头的是输入寄存器,只能读取不能写的,否则Modbus指令会报错吧?

既然你测试出来读取是440961,写也是440961,只有0和4开头的寄存器可以读、写操作。

取一个VB单元的低7位内容,可以用WAND_B指令与16#80得到的值就是了。或者也可以直接把字节的最高位清零。比如取 VB0的低七位内容到VB2,用指令与运算或者最高位清零都可以。




 
以下网友喜欢您的帖子:

  
侠客

经验值: 727
发帖数: 10
精华帖: 0
回复:如何将某个字节VB**的最低7位和最高位分别读出,并分别转换成另外两个字节??


只看楼主 7楼 2021-07-04 16:27:34

左移右移不就行了?SHL&SHR


2021新年新“西”望!!!
以下网友喜欢您的帖子:

  
版主

经验值: 25997
发帖数: 11809
精华帖: 43
回复:如何将某个字节VB**的最低7位和最高位分别读出,并分别转换成另外两个字节??


只看楼主 8楼 2021-07-05 15:14:05

这个协议,我看了一下,没什么问题的。

它具有两种数据读取方式,一种是集合式读取,把多个数据组装在一起,楼主问的就是这种读取方式。

显然,还有不组装在一起的数据读取方式,只是楼主没有贴出来。


 
以下网友喜欢您的帖子:

  
  • 上一页
  • 1
  • 下一页
收起
如何将某个字节VB**的最低7位和最高位分别读出,并分别转换成另外两个字节??
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。