内容
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
- 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设备和通信协议的要求。