python将二进制转换为32位浮点数float/两个16位整数(高位字/低位字)Uint16转换为32位浮点数float

背景:工业数采,采集Siemens西门子S7-1200数据,其中一个32位浮点数无法直接读取,分为了两个16位字去读

DB27.DBD116--->DB27.DBW116 DBD27.DBW118

目标:通过python边缘计算,将两个字Uint16合为32位浮点数float

Los geht's!

目录

了解S7-1200寻址

了解S7-1200浮点数使用标准

编写python算法


了解S7-1200寻址

从以下回答可以总结:

字节,字和双字的起始地址,最高有效字节和最低有效字节,例题求解-SIMATIC S7-200-找答案-西门子中国 (siemens.com.cn)https://www.ad.siemens.com.cn/service/answer/solved_226956_1028.html

WORD类型的结构问题-SIMATIC S7-300(F)/S7-400(F/H/FH)-找答案-西门子中国 (siemens.com.cn)https://www.ad.siemens.com.cn/service/answer/solved_40622_1029.html

需要读取的DBD116分成了DBW116和DBW118,DBW118存储低字节,DBW116存储高字节

读取的数据如下:

DBW116 = 17981(十进制)= 01000110 00111101(二进制)

DBW118 = 52892(十进制)= 11001110 10011100(二进制)

十进制转二进制/二进制转十进制

十进制与二进制在线转换工具,在线计算,在线计算器,计算器在线计算 (osgeo.cn)https://www.osgeo.cn/app/s3090

需要合并为DBD116 =12147.6523 (十进制,浮点数)

=01000110 00111101 11001110 10011100(二进制)

十进制/十六进制转浮点数

浮点数-Float-Double转二进制 - ToolTT在线工具箱https://tooltt.com/floatconverter/

了解S7-1200浮点数使用标准

使用IEEE 754标准

参考:

SIMATIC S7-1500 自动化系统, ET 200MP 自动化系统 (siemens.com)https://cache.industry.siemens.com/dl/files/384/86140384/att_1093122/v1/s71500_et200mp_manual_collection_zh-CH.pdfpython将二进制转换为32位浮点数float/两个16位整数(高位字/低位字)Uint16转换为32位浮点数float_第1张图片

 分为三部分:

S-符号位  E-阶数 M-尾数

公式为:(-1)^{S}*2^{E-127}*1.M

这里的M不能简单理解为十进制,而是二进制

以我上面提到的需要化为浮点数的二进制为例

0 100 0110 0 011 1101 1100 1110 1001 1100
DBW116 DBW118
S E M

S = 0 正数                                                       (-1)的0次方 = 1

E = 10001100 = 140 阶数                               3的(140-127=13)次方

M = 01111011100111010011100 = 4050588   1.M=1.01111011100111010011100

         = 1*2^{0}+0*2^{-1}+1*2^{-2}+1*2^{-3}+1*2^{-4}+1*2^{-5}+0*2^{-6}+1*2^{-7}+1*2^{-8}+1*2^{-9}+0*2^{-10}+0*2^{-11}+1*2^{-12}+1*2^{-13}+1*2^{-14}+0*2^{-15}+1*2^{-16}+0*2^{-17}+0*2^{-18}+1*2^{-19}+1*2^{-20}+1*2^{-21}+0*2^{-22}+0*2^{-23}

         =1.4828677177429199

import math

a = 0.0

a = 1+pow(2,-2)+pow(2,-3)+pow(2,-4)+pow(2,-5)+pow(2,-7)+pow(2,-8)+pow(2,-9)+pow(2,-12)+pow(2,-13)+pow(2,-14)+pow(2,-16)+pow(2,-19)+pow(2,-20)+pow(2,-21)

print(a)

三者相乘 = 12147.65234375

import math

a = 0.0

a = (1+pow(2,-2)+pow(2,-3)+pow(2,-4)+pow(2,-5)+pow(2,-7)+pow(2,-8)+pow(2,-9)+pow(2,-12)+pow(2,-13)+pow(2,-14)+pow(2,-16)+pow(2,-19)+pow(2,-20)+pow(2,-21))*(2**13)*((-1)**(0))

print(a)

参考计算方法,这个写的很好,很详细,看上面不理解可以看这个:

用二进制如何表示浮点型数值_思维态度行动的博客-CSDN博客_二进制转浮点数

编写python算法

首先明确中间变量的类型

python将二进制转换为32位浮点数float/两个16位整数(高位字/低位字)Uint16转换为32位浮点数float_第2张图片

注意num的变量类型一定为无符号32位Int,被坑了一把,若仅在电脑VS运行则无需在意

先在电脑上面用VS调试

VS添加python可以参考:

VS Code配置Python环境 - 暄踽 - 博客园VSCode配置Python环境,步骤详细,适合新手小白。https://www.cnblogs.com/kint216/p/16004937.html使用Jupyter Notebooks

python将二进制转换为32位浮点数float/两个16位整数(高位字/低位字)Uint16转换为32位浮点数float_第3张图片

import math

#调试时,Low和High作为模拟数采输入值
#Low为DBW118 High为DBW116
#若作为正式的边缘计算算法,Low和High为数采得到的数据,应删掉下面两行

Low = 52892
High = 17981

num = 0
MM = 0.0
MM1 = 0.0
count = 1

S = int(High >> 15)  #获取符号位

E = int((High >> 7) & 255) #获取阶数

M = int(Low |((High & 127) << 16) ) #获取尾数取高位低七位和低位

num = (M<<9) & 0xffffffff #将尾数的有效位都移到最左边,num为无符号32位整型!!

while num>0:
    if (num & 0x80000000) == 0x80000000:  #获取尾数M的最高位(最左边)
        MM1 = float(0.5**count)           #count为1时,2的(-1)次幂 = (0.5)的1次幂
    else:
        MM1 = 0.0
    MM = MM+ MM1                          #循环累加结果
    count = count + 1                     #幂数加一
    num = (num & 0x7FFFFFFF) << 1         #迭代,将尾数M的次高位(左边第二位)变为最高位,便于下次运算
    if count > 23 :                       #尾数M的位数为23,当大于23即24时,退出循环
        break

Result = pow(-1,S)*pow(2,E-127)*(1.0 + MM) #得到最后的结果

print(Result)  #调试时才需要添加这一句,显示结果

 得到结果,是正确的

python将二进制转换为32位浮点数float/两个16位整数(高位字/低位字)Uint16转换为32位浮点数float_第4张图片

你可能感兴趣的:(PLC,python,python,PLC)