ModBus協議報文格式解析說明

什麼是Modbus?

       Modbus協議是一個master/slave架構的協議。有一個節點是master節點,其他使用Modbus協議參與通信的節點是slave節點。每一個slave設備都有一個唯一的地址。在串行和MB+網絡中,只有被指定爲主節點的節點可以啓動一個命令(在以太網上,任何一個設備都能發送一個Modbus命令,但是通常也只有一個主節點設備啓動指令)。

       一個ModBus命令包含了打算執行的設備的Modbus地址。所有設備都會收到命令,但只有指定位置的設備會執行及迴應指令(地址0例外,指定地址0的指令是廣播指令,所有收到指令的設備都會運行,不過不迴應指令)。所有的Modbus命令包含了檢查碼,以確定到達的命令沒有被破壞。基本的ModBus命令能指令一個RTU改變它的寄存器的某個值,控制或者讀取一個I/O端口,以及指揮設備回送一個或者多個其寄存器中的數據。

      以上都是參考百度百科的解釋說明,還是沒有看明白的同學可以先不用管,至少現在我們需要有一個概念,modbus通信中會有兩個設備,一個是主機poll端和從機salve端,接下來看下面的進一步說明。

Modbus TCP/IP協議格式

  • 主機poll端發送讀寫報文樣例如下,該報文對應的功能碼選擇的04。

07 9B 00 00 00 06 01 04 00 00 00 0A

數據

含義

07 9B

主機發出的檢驗信息,從機slave將這個兩個字節放在響應報文中

00 00

表示協議標識符,00 00爲modbus的TCP/IP協議

00 06

數據長度,用來指示接下來數據的長度,單位字

01

設備地址,用以標識連接在串行線或者網絡上的遠程服務端的地址。

04

功能碼,此時代碼04爲讀取InputRegisters寄存器數據

00 00

讀取寄存器起始地址

00 0A

讀取寄存器長度,16進制

以上報文中前6個字節稱作爲modbus的頭字節,後面爲查詢命令數據段PDU。主機需要查詢從機寄存器從0開始後面10個寄存器的值,根據該命令從機返回的報文如下。

  • 從機slave端返回對應04功能碼查詢的數據報文樣例

07 9B 00 00 00 17 01 04 14 41 D0 FB E7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

數據

含義

07 9B

此次通信事務處理標識符,應答報文要求與先前對應的請求保持一致

00 00

協議標識符,與先前對應的請求保持一致

00 17

數據長度,用來指示接下來數據的長度,單位字節

01

設備地址,應答報文要求與先前對應的請求保持一致

04

功能碼,正常情況下應答報文要求與先前對應的請求保持一致,如果出錯則返回0x80+先前的功能碼(讀取錯誤碼83)

14

接下來的數據的字節長度,注意是十六進制

41 D0 FB E7....

被讀取的保持寄存器中的數據值

這裏從機返回十個寄存器的值,每兩個字節爲一個int整型(如果是float或double類型則是四個字節),即 41 D0是int整型數據,查看的話需要轉化爲int整型,這裏就不在贅述了,這裏提供一個Java的方法轉換,可以直接調用。

// String類型爲 41D0 的16進制類型的字符串
// 41D0 轉化爲10進製爲16848
public int CovertTo(String str){
    return Integer.parseInt(str, 16);
}
  • 主機poll端發送位寄存器查詢報文格式如下,對應查詢功能碼爲01。

04 E2 00 00 00 06 01 01 00 00 00 0A 

數據

含義

04 E2

此次通信事務處理標識符,一般每次通信之後將被要求加1以區別不同的通信數據報文

00 00

表示協議標識符,00 00爲modbus的TCP/IP協議

00 06

數據長度,用來指示接下來數據的長度,單位字

01

設備地址,用以標識連接在串行線或者網絡上的遠程服務端的地址

01

功能碼,此時代碼01爲讀取Coils寄存器數據

00 00

起始地址

00 0A

寄存器數量,十六進制

這段報文讀取從機位寄存器Coils的0到9地址的值,但是從機返回還是16進制數據,不能按照二進制進行傳輸,需要將從機的位進制寄存器排列起來並按一定規則進行組合成16進制數,規定兩個字節算一個最小單位,即 00 是modbus報文最小傳輸單位,兩個字節等於8位,數據不夠的話自動補零,所以主機查詢從機0到9的寄存器地址值,最後返回的是0到15的寄存器的值,長度必須是8的倍數,比如查長度爲10返回長度16,查17返回的是長度24。這裏可以參考一個例子說明,從機的前8位設置值如下。

0 1 2 3 4 5 6 7
0 0 1 1 0 1 0 1

slave模擬器設置如下:

  • 從機slave端返回對應01功能碼查詢的數據報文樣例

04 E2 00 00 00 05 01 01 02 AC 00

數據

含義

04 E2

此次通信事務處理標識符,應答報文要求與先前對應的請求保持一致

00 00

協議標識符,與先前對應的請求保持一致

00 05

數據長度,用來指示接下來數據的長度,單位字節

01

設備地址,應答報文要求與先前對應的請求保持一致

01

功能碼,正常情況下應答報文要求與先前對應的請求保持一致,如果出錯則返回0x80+先前的功能碼(讀取錯誤碼83)

02

接下來的數據的字節長度,注意是十六進制

AC 00

被讀取的保持寄存器中的數據值

從機返回的報文數據只有兩個字節,但是它包含了16位Coils寄存器的值,AC 02 需要轉化爲二進制。

從機的寄存器位值按順序應該是 00110101 00000000,編碼機制是每8位算作一個單位,並且高位與低位相反,通俗點將就是每8位將數據翻轉過來,所以轉化爲編碼爲 10101100 0000000, 再轉化爲16進制則爲 AC 00。

  • Modbus寫報文請求和響應報文格式

主機的寫報文請求格式則與從機的數據查詢響應報文格式類似,都是頭字節加上數據段,這裏就不要舉例了。

從機的寫報文響應則與主機讀報文的請求格式類似。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章