内容 SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM

这里S 代表符号位,1是负,0是正
E 偏移127的幂,二进制阶码=(EEEEEEEE)-127。
M 24位的尾数保存在23位中,只存储23位,最高位固定为1。此方法用最较少的位数实现了较高的有效位数,提高了精度。
零是一个特定值,幂是0 尾数也是0。

浮点数-12.5作为一个十六进制数0xC1480000保存在存储区中,这个值如下:
地址 +0 +1 +2 +3
内容0xC1 0x48 0x00 0x00
浮点数和十六进制等效保存值之间的转换相当简单。下面的例子说明上面的值-12.5如何转换。
浮点保存值不是一个直接的格式,要转换为一个浮点数,位必须按上面的浮点数保存格式表所列的那样分开,例如:

地址 +0 +1 +2 +3
格式 SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
二进制 11000001 01001000 00000000 00000000
十六进制 C1 48 00 00

从这个例子可以得到下面的信息:
符号位是1 表示一个负数
幂是二进制10000010或十进制130,130减去127是3,就是实际的幂。
尾数是后面的二进制数10010000000000000000000

在尾数的左边有一个省略的小数点和1,这个1在浮点数的保存中经常省略,加上一个1和小数点到尾数的开头,得到尾数值如下:
1.10010000000000000000000

接着,根据指数调整尾数.一个负的指数向左移动小数点.一个正的指数向右移动小数点.
因为指数是3,尾数调整如下:
1100.10000000000000000000

结果是一个二进制浮点数,小数点左边的二进制数代表所处位置的2的幂,例如:1100表示
(123)+(1*22)+(021)+(0*20)=12。
小数点的右边也代表所处位置的2的幂,只是幂是负的。例如:.100…表示
(12^(-1))+ (02(-2))+(0*2(-2))…=0.5。
这些值的和是12.5。因为设置的符号位表示这数是负的,因此十六进制值0xC1480000表示-12.5。

浮点数:43020000

地址 +0 +1 +2 +3
内容 SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
     0100 0011 0000  0010   0000  0000   0000  00000

这里S 代表符号位,1是负,0是正
E 偏移127的幂,二进制阶码=(EEEEEEEE)-127。
M 24位的尾数保存在23位中,只存储23位,最高位固定为1。此方法用最较少的位数实现
(100 0011 0)=134-127=7

  1. 000 0010 0000 0000 0000 00000
    1 000 0010. 0000 0000 0000 00000=130

从modbus接收到的数据,转为浮点数:

float f = GetFloat(registerBuffer[0], registerBuffer[1]);
public static float GetFloat(ushort P1, ushort P2)
            int intSign, intSignRest, intExponent, intExponentRest;
            float faResult, faDigit;
            intSign = P1 / 32768;
            intSignRest = P1 % 32768;
            intExponent = intSignRest / 128;
            intExponentRest = intSignRest % 128;
            faDigit = (float)(intExponentRest * 65536 + P2) / 8388608;
            faResult = (float)Math.Pow(-1, intSign) * (float)Math.Pow(2, intExponent - 127) * (faDigit + 1);
            return faResult;

将浮点数转为modbus需要的无符号短整数:

float fff = float.Parse(floattxt.Text);
            string d = BitConverter.ToString(BitConverter.GetBytes(fff).Reverse().ToArray()).Replace("-", "");
            Console.WriteLine(d);
            ushort ss1 = Convert.ToUInt16(d.Substring(0,4),16);
            ushort ss2 = Convert.ToUInt16(d.Substring(3, 4), 16);
                    浮点数保存的字节格式如下:地址 +0 +1 +2 +3内容 SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM这里S 代表符号位,1是负,0是正E 偏移127的幂,二进制阶码=(EEEEEEEE)-127。M 24位的尾数保存在23位中,只存储23位,最高位固定为1。此方法用最较少的位数实现了较高的有效位数,提高了精度。零是一个特定值,幂是0 尾数也是0。...
				
modbus协议通信时浮点数如何发送和接收处理的解决办法   在本次做项目的时候,发现要威纶通屏幕与stm32芯片采用modbus通信,很多时候要处理float小数。最开始一直在纠结大小端的问题,坑了一天,理出了下面的解决办法。   注意:主机发送给从机的小数是以32位的形式发送的,所以会占用2个保持寄存器。并且本次项目的威纶通屏幕作为主机时,是以小端形式发送数据,与stm32f103芯片一致,此处大小端问题我不在详细说明(主要是自己太菜了,太懒了,画图来说明很耽误时间) 一、如何将保持寄存器存放的
上一篇介绍了modbus协议的基本概念,这一篇主要介绍最近做的一个小项目:STM3210ZET6与昆仑屏(TPC)的通信。在该项目最关键的技术就是下位机modbus协议的解析。     首先介绍下昆仑屏(TPC),项目用到的触摸屏采用的RS232接口,modbus协议。     采用的驱动是:莫迪康 ModbusRTU;本驱动支持 01、02、03、04、05、06、15、16 常用功能
在使用Modbus RTU协议时常常会遇到要传输32位浮点型数据的情况。本文讨论如何解决传输浮点数的问题。 点对点的Modbus协议RTU通信的常用选择。协议本身控制Modbus网络上每个设备的交互,设备如何建立已知地址,每个设备如何识别其消息以及如何从数据提取基本信息。从本质上讲,该协议是整个Modbus网络的基础。 然而,这种便利并非没有一些复杂...
这款软件适合刚接触VB软件开发MODBUS协议的通信软件的初学者,使用vb的的mscomm进行通信,里面涉及到了数据发送、数据接收已经数据接收后的数据处理,含32位字节转浮点数的处理程序。 这款程序我是用在与多功能数显电力仪表进行数据交换的。
VB6自行编写的源代码,实现ModbusRTU协议四个字节整形 转换成浮点数据,也可以浮点数据转换为4字节整形,bas形式,用户可以直接在自己程序调用。 Public Function MODBUSLongtoFloat32(input1 As String) As Double ‘输入格式16进制:33 46 5E 3F字符串格式 '如果是10进制数 可以调用 hex(dex1) & " " & hex(dex2) & " " & hex(dex3) & " " & hex(dex4) Public Function MODBUSFloattoLong32(inputS As Single) As String 'IEEE754标准 浮点格式转换 我看网上介绍要把整数部分和小数部分分开转成二进制,太复杂了,其实有非常简单的方法,看程序就知道了。相互学习。
Modbus 协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器经由网络(例如以太网)和其它设备之间可以通信。Modbus协议定义了一个控制器能认识使用的消息结构,而不管它们是经过何种网络进行通信的。它描述了一控制器请求访问其它设备的过程,如果回应来自其它设备的请求,以及怎样侦测错误并记录。它制定了消息域格局和内容的公共格式。 Modbus 是一个请求/应答协... //ModbusRTU格式的2个32位整数转浮点数 public float parseInt2Float(int x1, int x2) { int f, fRest, exponent, exponentRest; flo...
Modbus RTU是一种常用的串行通信协议,用于连接不同设备之间的通信。在Modbus RTU协议寄存器存储数据的地方。 32位浮点数存储要使用4个字节(32位),而64位浮点数存储要使用8个字节(64位)。所以,如果要将32位浮点数读取到64位浮点寄存器,就要注意数据的扩展问题。 一种常用的方法是通过进行填充来实现32位到64位的扩展。即使用两个连续的32位寄存器存储64位浮点数,其高位和低位分别表示64位浮点数的整数部分和小数部分。在读取数据时,先读取高位寄存器的数据,再读取低位寄存器的数据,并将它们合并为一个64位的浮点数。 另一种方法是在读取时进行数据类型转换。即读取时将32位浮点数转换为64位浮点数,然后再进行存储。这要通过对数据进行位运算和转换来实现。 无论采用哪种方法,关键是要注意数据的字节顺序(Endianness)问题,即确定是先传输高位字节还是低位字节。在Modbus RTU,通常采用Big Endian字节顺序。 综上所述,要将32位浮点数读取到64位浮点寄存器,可以通过填充或数据类型转换的方式实现,并要注意字节顺序的问题。具体的实现取决于所使用的Modbus RTU设备和通信协议的要求。