這兩天在開發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得到溫度值,可以理解爲以下流程
要做的就是將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!