最近又遇到个问题,PLC和PLC通信,需要用到Real变量,还需要高低字节转换,该怎么正确传输呢?下面由我一步一步解决这个问题。一次性彻底解决Real数据结构问题。

第一步:硬件配置

倍福PLC为主站,西门子模块为从站,通过Profibus通信传输数据,但硬件配置只能配置Byte,如下图定义了64字节输入,64字节输出。

plc数据的寻址(PLC里Real数据结构和高低字节详解)(1)

第二步:问题描述

我需要西门子PLC给我发一个real类型的数据,一个real类型为4个byte,我就在程序里定义5-8Byte这4个byte为一个Real(如下图蓝色显示,图中为64个byte的16进制显示,两个数字00代表一个byte)。

plc数据的寻址(PLC里Real数据结构和高低字节详解)(2)

倍福里Real的16进制数据CD 4C 03 43,此时在程序里的显示为131.3;但是西门子发过来的不是131.3。

这又是什么问题呢?

此刻想到有高低字节转换,所以认为是高低字节问题导致的(我的上一篇文章详细讲解了高低字节转换机理)。于是我打算在程序里通过高低字节转换看看结果是不是一致的。也就是上图中real的16进制数据变成了43 03 4C CD。结果显示还是不正确,这就纳闷了。。

头大中……………

怎么办呢?

只能一步一步分析数据结构了。

第三步:技术原理分析

倍福侧显示的Real:131.3的数据结构如图所示

plc数据的寻址(PLC里Real数据结构和高低字节详解)(3)

西门子侧由于有高低字转换问题,实际西门子侧需做个高低字节转换后,要给我发以下数据结构:

plc数据的寻址(PLC里Real数据结构和高低字节详解)(4)

这样数据结构才能全部对应上,如果西门子不经过高低字节转换,直接发131.3数据给倍福,那么因为存在高低字节互换问题,倍福收到的完全是反的字节,即1100 1101 0100 1100 0000 0011 0100 0011,这就需要倍福侧再次做高低字节转换。才能得到实际的结果131.3;

卧槽!

经过推理可以经过高低字节转换就得到正确结果了呀!!

在验证一遍,西门子发个real,倍福经过高低字节转换,确实可以得到正确结果,之前我的程序写错了,程序里定义的是DWORD,不是Real!!!

研究到现在白研究了,高低字节转换就可以实现了!!!

但是既然已经研究到这了,就干脆把Real的换算机制搞清楚吧!!!!!

第四步:Real 换算机制

32位real的结构如下图:

高地址<------------>低地址

| 符号位 | 指数 | 尾数 |

| 1 bit | 8 bit | 23 bit |

*符号位1代表负数,0代表正数。

*指数就是公式里的指数。

*尾数就是小数点后面的部分。

举例说明:Real值 131.1

plc数据的寻址(PLC里Real数据结构和高低字节详解)(5)

二进制表示位0100 0011 0000 0011 0100 1100 1100 1101

机器运算需要转为补码运算,正数补码和反码一致。

即131.3的补码和上面一样,0100 0011 0000 0011 0100 1100 1100 1101

**0代表正数;

**后面8位1000 0110为指数,转换为十进制是 指数=134。

**尾数部分为000 0011 0100 1100 1100 1101,根据公式加1;

为1. 000 0011 0100 1100 1100 1101;

Real转换公式为 REAL=1*1.(尾数部分)*2^(指数-127)

以上数据代入,十进制real即为=1.00000110100110011001101*2^(134-127)

=1.00000110100110011001101*2^7

以上由于是二进制乘法,所以每次乘以2,小数点前移1位,2^7就是前移7位,数据表示为

=10000011.0100110011001101

抓换成10进制无限接近 =131.3

到此转换完成,Lreal是64位结构也是相同的机制,只是指数和尾数变多了。

问题解决了,还收获Real数据的知识,挺充实!!

,