modbus协议通信时浮点数如何发送和接收处理的解决办法

您所在的位置:网站首页 威纶触摸屏1wv是什么意思 modbus协议通信时浮点数如何发送和接收处理的解决办法

modbus协议通信时浮点数如何发送和接收处理的解决办法

2024-02-22 10:41| 来源: 网络整理| 查看: 265

modbus协议通信时浮点数如何发送和接收处理的解决办法

  在本次做项目的时候,发现需要威纶通屏幕与stm32芯片采用modbus通信,很多时候需要处理float小数。最开始一直在纠结大小端的问题,坑了一天,理出了下面的解决办法。   注意:主机发送给从机的小数是以32位的形式发送的,所以会占用2个保持寄存器。并且本次项目的威纶通屏幕作为主机时,在发送IEEE754格式的小数时,第一个保持寄存器存放的是小数的低16位,第二个保持寄存器存放的是小数的高16位。

小数转换步骤: 1、威纶通屏幕作为主机在发送浮点数时,是以IEEE754格式发送数据,需要用到2个保持寄存器,第一个保持寄存器存放小数的低16位,第二个保持寄存器存放小数的高16位 2、在从机保持寄存器接收到小数后,需要将数据按小端格式放入一个4字节的空间中,即低地址存放低字节,高地址存放高字节 3、获取小数的4个字节空间的首地址,得到小数值

一、如何将保持寄存器中存放的IEEE754格式的小数转换成float类型

一、方法1.0 此方法是采用1个4字节的u8类型的数组,去转换主机发给从机的小数。在stm32中小数存储方式是以小端模式存放:低地址存放低字节,高地址存放高字节。

/* 函数功能:将从机保持寄存器的值转换成对应小数 函数参数: HoldAddr ----从机保持寄存器接收到的小数存放的起始地址*/ float DataConvertFloat(u16 HoldAddr) { u8 str[4]; float temp; str[0] = (u8 )(usSRegHoldBuf[HoldAddr]&0xff);//得到保持寄存器HoldAddr的低8位,也就是小数的0~7位 str[1] = (u8 )(usSRegHoldBuf[HoldAddr]>>8); //得到保持寄存器HoldAddr的高8位,也就是小数的8~15位 str[2] = (u8 )(usSRegHoldBuf[HoldAddr+1]&0xff);//得到保持寄存器(HoldAddr+1)的低8位,也就是小数的16~23位 str[3]= (u8 )(usSRegHoldBuf[HoldAddr+1]>>8);//得到保持寄存(HoldAddr+1)的高8位,也就是小数的24`31位 temp = *((float *)str);//得到小数, return temp; } /*此处有用到保持寄存器的数组usSRegHoldBuf,这个我项目由于要多次使用到,我已经把 这个保持寄存器定义为了全局变量*/ #define S_REG_HOLDING_NREGS 500 //保持寄存器数量 USHORT usSRegHoldBuf[S_REG_HOLDING_NREGS] ;//保持寄存器

二、方法1.1 定义一个内联类型的变量,此内联类型比较特殊

/*浮点数与IEEE754格式转换*/ typedef union { float ul_Temp; u8 uc_Buf[4];//小数转换成IEEE754格式的数组 u16 us_Buf[2];//用于modbus协议小数转换的数组 }un_DtformConver; //此方式和1.0其实差不多,不过这个方式可以运用到的别的小数转换成IEEE754的场合 float DataConvertFloat(u16 HoldAddr) { un_DtformConver Data; float temp; Data.uc_Buf[0] = (u8 )(usSRegHoldBuf[HoldAddr]&0xff);//得到保持寄存器HoldAddr的低8位 Data.uc_Buf[1] = (u8 )(usSRegHoldBuf[HoldAddr]>>8);//得到保持寄存器HoldAddr的高8位 Data.uc_Buf[2] = (u8 )(usSRegHoldBuf[HoldAddr+1]&0xff);//保持寄存器(HoldAddr+1)的低8位 Data.uc_Buf[3]= (u8 )(usSRegHoldBuf[HoldAddr+1]>>8);//保持寄存器(HoldAddr+1)的高8位 temp = Data.ul_Temp;//得到小数 return temp; }

三、方法1.3

float DataConvertFloat(u16 HoldAddr) { un_DtformConver Data; float temp; Data.us_Buf[0] = usSRegHoldBuf[HoldAddr];//获取从机接收到的小数的低16位 Data.us_Buf[1] = usSRegHoldBuf[HoldAddr+1];//获取从机接收到的小数的高16位 temp = Data.ul_Temp;//得到小数 return temp; }

四、方法1.4

float DataConvertFloat(u16 HoldAddr) { float temp; temp = *((float *)&usSRegHoldBuf[HoldAddr]);//直接获取地址转换就可以了,因为usSRegHoldBuf[HoldAddr+1]存放的正好是小数的高16位,满足stm32的小端模式 return temp; }

二、如何将float类型的小数转换成IEEE754格式放入到从机的保持寄存器中

/* 函数功能:将小数转换成IEEE754数据类型,用于modbus协议传输数据 函数参数:value 小数值 Holdaddr 从机保持寄存器地址 */ //方式1.0 void Float_To_U32(float value, u16 Holdaddr) { un_DtformConver Data; Data.ul_Temp = value;//获取小数值 usSRegHoldBuf[Holdaddr] = Data.us_Buf[0];//获取低16位 usSRegHoldBuf[Holdaddr+1] = Data.us_Buf[1];//获取高16位 } //方式1.1 void Float_To_U32(float value, u16 Holdaddr) { un_DtformConver Data; u16 us_temp = 0; Data.ul_Temp = value;//获取小数值 usSRegHoldBuf[Holdaddr] = Data.uc_Buf[0]; //获取最低8位 us_temp = Data.uc_Buf[1];//获取8~15位 usSRegHoldBuf[Holdaddr] |= us_temp


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3