关于Modbus数据16进制转10进制问题

这两天在开发STM32的Modbus主站,就买了一个RS485总线的温湿度传感器来,温湿度传感器说明要求将传感器返回的Modbus报文数据转换为10进制后再除以10得到真实数据,以下是举例

Modbus主站发送报文:
01 04 00 01 00 01 60 0A
意思是读取从站地址01的输入寄存器1号位1位数据

SlaveID FunctionCode StartADDR Length CRC
从站ID 功能码 起始地址 寄存器数量 CRC校验
01 04 00 01 00 01 60 0A

Modbus主站接收报文:
01 04 02 01 2D 78 BD
意思是从站ID为01,功能码为04,数据有两位(一个数据是通过两位来返回),数据高位01,数据低位2D

SlaveID FunctionCode Length Data CRC
从站ID 功能码 寄存器数量 数据 CRC校验
01 04 02 01 2D 78 BD

以上是数据解析

那么问题来了,返回的01 2D怎么变成我们需要的数据
根据传感器说明书,我们需要将返回值变成10进制数据后除以10得到温度值,可以理解为以下流程

合成
转换
除以10
数据01 2D
16进制数据 12D
10进制数据301
温度30.1摄氏度

要做的就是将01 2D转化成30.1这个数字

一开始我还各种骚操作,结果最后发现就很简单,怪自己C语言基础还是有点问题

在计算机中,16进制数字表示的数值和10进制表示的数值其实是一样的,计算上并不存在进制转换问题,存在的是进位的时候是按照10进制进位还是16进制进位

例如:

一个十六进制数2D,以%x形式打印为2d,以%d打印为45
本质上是同一个数

所以在处理Modbus的数据时,设高位为NUM_H,低位为NUM_L,需要的10进制数为Data,高位进位为16的平方,即

Data=NUM_H×16×16+NUM_L

例如2F 3D
计算器转换为10进制为12093
2F代表的10进制为47,3D代表的10进制为61
所以

Data=2F×16×16+3D
	=47×16×16+61
	=12093

所以我接收到的数据01 2D根据公式换算为

Data=01×16×16+2D
	=1×16×16+45
	=301
	
温度=301/10
	=30.1°	

可知我当前室温30.1摄氏度。

所以结论就是,Modbus接收的数据不需要转换进制,只需要进位按照16进制的百位进位既可,也就是16的平方

公式就是:

Data:需要的数据
NUM_H:Modbus数据高位
NUM_L:Modbus数据低位

Data=NUM_H×16×16+NUM_L

因为我说过不给结果的博客都是耍流氓,但是这个结果不好给所以以下是我按照公式计算出来的我的室温和湿度,通过STM32串口发送出来的,当作是结果吧!哈哈哈哈
在这里插入图片描述
我看别人转进制代码都是要钱的,我这里就把公式白给了,很多小白也会遇到这个坑,希望能帮助一下和我以前有一样疑问的人

听说给我点赞评论关注三连的人写代码都不会有BUG!

你可能感兴趣的:(Modbus,STM32,modbus)