Modbus功能碼詳解
Modbus功能碼是Modbus消息幀(報文)的重要組成部分,是Modubs協議中通信事務處理的基礎,代表消息將要執行的動作。
功能碼概要
簡而言之,Modbus功能碼占用一個(ge) 字節,取值範圍是1127,之所以127以上不能使用,是因為(wei) Modbus規定出現異常時,功能碼+0x80(十進製128)代替異常狀態,因此129(1+128)255(127+128)的取值代表異常碼。
Modbus標準協議中規定了由3類Modbus功能碼,分別是:
-
公共功能碼
- 被明確定義的功能碼
- 保證唯一性
- 由Modbus協會確認,並提供公開的文檔;
- 可進行一致性測試
- 包括協議定義的功能碼和保留將來使用的功能碼
-
用戶自定義(yi) 功能碼
- 有兩個用戶自定義功能碼區域,分別是6572和100110;
- 用戶自定義,不保證唯一性。
-
保留功能碼
保留功能碼是因為(wei) 曆史遺留原因,某些公司的傳(chuan) 統產(chan) 品上現行使用的功能碼不作為(wei) 公共使用。
Modbus部分功能碼如下:
代碼 | 名稱 | 寄存器PLC地址 | 位/字操作 | 操作數量 |
---|---|---|---|---|
01 | 讀線圈狀態 | 00001~09999 | 位操作 | 單個或多個 |
02 | 讀離散輸入狀態 | 10001~19999 | 位操作 | 單個或多個 |
03 | 讀保持寄存器 | 40001~49999 | 字操作 | 單個或多個 |
04 | 讀輸入寄存器 | 30001~39999 | 字操作 | 單個或多個 |
05 | 寫單個線圈 | 00001~09999 | 位操作 | 單個 |
06 | 寫單個保持寄存器 | 40001~49999 | 字操作 | 單個 |
15 | 寫多個線圈 | 00001~09999 | 位操作 | 多個 |
16 | 寫多個保持寄存器 | 40001~49999 | 字操作 | 多個 |
功能碼可分為(wei) 位操作和字操作兩(liang) 類。位操作的最小單位為(wei) 一位(bit),字操作的最小單位為(wei) 兩(liang) 個(ge) 字節。
- 位操作指令:讀線圈狀態功能碼01,讀(離散)輸入狀態功能碼02,寫單個線圈功能碼06和寫多個線圈功能碼15.
- 字操作指令:讀保持寄存器功能碼03,讀輸入寄存器功能碼04,寫單個保持寄存器功能碼06,寫多個保持寄存器功能碼16.
01(0x01)讀取線圈/離散量輸出狀態
功能說明讀取從(cong) 設備的線圈或離散量輸出的狀態,即各DO的ON/OFF狀態。消息幀中指定了需讀取的線圈起始地址和線圈數目。需要注意的一點是,在Modbus協議規定的PDU中,規定所有線圈或寄存器地址從(cong) 0開始計算。
查詢報文查詢幀的消息裏,定義(yi) 了從(cong) 設備地址為(wei) 3,並讀取從(cong) 設備的Modbus地址0001900055(線圈地址0002000056)共計37個(ge) 狀態值。起始線圈地址為(wei) 0x13(即十進製00019),因為(wei) 線圈地址從(cong) 0開始計數。
Modbus協議規定,起始地址由2個(ge) 字節構成,取值範圍為(wei) 0x00000xFFFF;線圈數量由2個(ge) 字節構成,取值範圍為(wei) 0x00010x07D0(即十進製1~2000).
ASCII模式中直接按每4個(ge) 位拆分為(wei) 對應的字符表示。
響應報文響應報文的數據字段中,每一個(ge) 線圈占用1個(ge) 位(bit),狀態被表示為(wei) 1=ON和0=OFF兩(liang) 種類型。第1個(ge) 數據字節的LSB(最低有效位)標識查詢報文中的起始地址線圈的狀態值,其他線圈依次類推,一直到這個(ge) 字節的MSB(最高有效位)位置,並在後續字節中按照同樣的方式(由低到高)排列。
一個(ge) 字節可以表示8個(ge) 線圈的狀態,如果最後的數據字節中不能填滿8個(ge) 線圈的狀態,則由0填充。對應於(yu) 查詢報文中需要讀取37個(ge) 線圈的狀態,則共需要5個(ge) 字節保存狀態值。
02(0x02)讀取離散量輸入值
功能說明該功能碼用於(yu) 讀取從(cong) 設備的離散輸入即DI的ON/OFF狀態。消息幀中製定了需讀取的離散輸入寄存器起始地址和數目,可讀取1~2000個(ge) 連續的離散量輸入狀態。如果從(cong) 設備接受主設備的請求則回複功能碼02,並返回離散量輸入各離散量的當前狀態。如果返回的離散輸入數量的個(ge) 數不是8的整數倍,將用0填充最後數據字節的剩餘(yu) 位。
03(0x03)讀取保持寄存器值
功能說明用於(yu) 讀取從(cong) 設備保持寄存器的內(nei) 容,不支持廣播模式。消息幀中指定了需讀取的保持寄存器的起始地址和數目。而保持寄存器中各地址的具體(ti) 內(nei) 容和意義(yi) ,則由設備開發者自行規定。
查詢報文在查詢報文中,必須指定保持寄存器的開始地址和需讀取的寄存器數量。起始位置由2個(ge) 字節構成,取值範圍為(wei) 0x00000xFFFF;寄存器數量由2個(ge) 字節構成,取值範圍為(wei) 0x00010x007D(即十進製1~255),即最多可以連續讀取125個(ge) 寄存器。
有一點特別需要注意,Modbus的保持寄存器和輸入寄存器是以字(Word)為(wei) 基本單位的(1Word=2byte),所以,如果讀取保持寄存器地址為(wei) 40001開始的一個(ge) 16位(bit)的無符號數,那麽(me) 返回2個(ge) 字節(byte),並可以從(cong) 40002開始讀取下一個(ge) 16位的無符號數。如果需讀取寄存器地址40001開始的是一個(ge) 32位浮點數,則需要返回4個(ge) 字節,即必須連續讀取40001和40002的內(nei) 容,而且下一個(ge) 32位浮點數必須從(cong) 40003開始讀取。對於(yu) 浮點數(或者32位的整數)而言,連續讀取的兩(liang) 個(ge) 寄存器之間存在字節序和大小端的問題,這一點在開發時必須引起注意。
04(0x04)讀取輸入寄存器值
功能說明同功能碼03類似,該功能碼用於(yu) 讀取從(cong) 設備輸入寄存器的內(nei) 容,不支持廣播模式。消息幀中指定了需讀取的輸入寄存器的起始地址和數目。而輸入寄存器中各地址的具體(ti) 內(nei) 容和意義(yi) ,則由設備開發者自行規定。
查詢報文在查詢報文中,必須指定輸入寄存器的起始地址和需讀取的寄存器數量。
本功能碼中,起始地址由2個(ge) 字節構成,取值範圍為(wei) 0x00000xFFFF;寄存器數量由2個(ge) 字節構成,取值範圍為(wei) 0x00010x007D(即十進製1~125),即最多可以連續讀取125個(ge) 寄存器。
同樣有一點需要注意,Modbus的保持寄存器和輸入寄存器是以字為(wei) 基本單位的。所以對於(yu) 浮點數(或32為(wei) 的整數)而言,連續讀取的兩(liang) 個(ge) 寄存器之間存在字節序和大小端的問題。
05(0x05)寫單個線圈或單個離散輸出
功能說明用於(yu) 將單個(ge) 線圈寄存器(或離散輸入)設置為(wei) ON或OFF,該功能碼支持廣播模式,在廣播模式下,所有從(cong) 站設備的同一地址的值將被統一修改,查詢報文中的ON或OFF狀態由報文數據字段的常熟指定,0xFF00表示ON狀態,0x0000表示OFF狀態。其他所有值均是非法的,並且對寄存器不起作用,將會(hui) 返回異常相應。
查詢報文本功能碼中,起始地址由2個(ge) 字節構成,取值範圍為(wei) 0x0000~0xFFFF;變更目標數據由2個(ge) 字節構成,取值隻能為(wei) 0xFF00或0x0000.
響應報文對於(yu) 從(cong) 設備,在線圈或離散輸出寄存器正常變更的情況下,則返回於(yu) 查詢報文一樣的響應報文。如果修改失敗,則返回一個(ge) 異常響應。
06(0x06)寫單個保持寄存器
用於(yu) 更新從(cong) 設備的單個(ge) 保存寄存器的值。該功能嗎支持廣播模式,在廣播模式下,所有設備的同一地址的值將被統一修改。
查詢報文查詢報文中需要指定從(cong) 設備地址以及需要變更的保持寄存器地址和設定的值。同樣需要注意的是,查詢報文中,寄存器地址從(cong) 地址0開始技術。
本功能碼中,起始地址由2個(ge) 字符構成,取值範圍為(wei) 0x00000xFFFF;變更目標數據由2個(ge) 字節構成,取值範圍為(wei) 0x00000xFFFF。
響應報文對於(yu) 從(cong) 設備,在保持寄存器正常變更的情況下,則返回於(yu) 查詢報文一樣的響應報文。如果修改失敗,則返回一個(ge) 異常返回。
08(0x08)診斷功能
功能說明該功能碼僅(jin) 用於(yu) 串行鏈路,主要用於(yu) 檢測主設備和從(cong) 設備之間的通信故障,或檢測從(cong) 設備的各種內(nei) 部故障,該功能碼不支持廣播。為(wei) 了區別各診斷類型,查詢報文中提供了2各字節的子功能碼字段。
通常在正常的響應報文中,從(cong) 設備將鴛鴦回複功能碼和子功能碼。
查詢報文查詢報文中需要指定從(cong) 設備地址、功能碼以及子功能碼。
例如,表4-15中表示了子功能碼“原樣返回查詢數據”的診斷功能,其中子功能碼為(wei) 0(0x0000)。在子功能碼0x0000的情況下,數據字段可以為(wei) 任意值。
本功能碼中,子功能碼由2個(ge) 字節構成,取值則根據意義(yi) 不同;數據字段由2個(ge) 字節構成,其取值由子功能碼確定。
響應報文對於(yu) 從(cong) 設備,在保持寄存器正常變更的情況下,則返回與(yu) 查詢報文一樣的響應報文。如果修改失敗,則返回一個(ge) 異常響應。
診斷子功能碼
各常用診斷子功能碼定義(yi) 如下:
- Return Query Data(00)
診斷內容 | 原樣返回查詢報文 |
---|---|
子功能碼 | 0x00,0x00 |
查詢報文數據字段 | 任意16位數據 |
響應報文數據字段 | 同查詢報文 |
- Restart Communications Option(01)
診斷內容 | 重啟通信選項 用於初始化並重新啟動從站設備,清除所有通信事件計數器。 如果端口處於Listen Only Mode下,不返回響應;否則在重啟之前返回響應 |
---|---|
子功能碼 | 0x00,0x01 |
查詢報文數據字段 | 0x00,0x00 保持事件記錄 |
0xFF,0x00 清除事件記錄 | |
響應報文數據字段 | 同查詢報文 |
- Return Diagnostics Register(02)
診斷內容 | 返回診斷寄存器 |
---|---|
子功能碼 | 0x00,0x02 |
查詢報文數據字段 | 0x00,0x00 |
響應報文數據字段 | 診斷寄存器的內容 |
- Force Listen Only Mode(04)
診斷內容 | 強製隻聽模式 強製被尋址的從站設備進入隻聽模式,使得此設備與網絡中的其他設備斷開,不返回響應 |
---|---|
子功能碼 | 0x00,0x0A |
查詢報文數據字段 | 0x00,0x00 |
響應 |
- Clear Counters and Diagnostic Register(10,0x0A)
診斷內容 | 清除計數器和診斷寄存器 |
---|---|
子功能碼 | 0x00,0x0A |
查詢報文數據字段 | 0x00,0x00 |
響應報文數據字段 | 同查詢報文 |
- Return Bus Message Count(11,0x0B)
診斷內容 | 返回總線報文計數 |
---|---|
子功能碼 | 0x00,0x0B |
查詢報文數據字段 | 0x00,0x00 |
響應報文數據字段 | 返回報文的計數值 |
- Return Bus Communication Error Count(12,0x0C)
診斷內容 | 返回總線通信CRC差錯計數 |
---|---|
子功能碼 | 0x00,0x0C |
查詢報文數據字段 | 0x00,0x00 |
響應報文數據字段 | 返回報文的CRC出錯總數 |
- Return Bus Exception Error Count(13,0x0D)
診斷內容 | 返回總線異常差錯計數 |
---|---|
子功能碼 | 0x00,0x0D |
查詢報文數據字段 | 0x00,0x00 |
響應報文數據字段 | 返回異常響應的總數 |
- Return Slave Message Count(14,0x0E)
診斷內容 | 返回從站設備報文總數 |
---|---|
子功能碼 | 0x00,0x0E |
查詢報文數據字段 | 0x00,0x00 |
響應報文數據字段 | 返回從站設備接收報文總數 |
- Return Slave No Response Count(15,0x0F)
診斷內容 | 返回從站設備無響應計數 |
---|---|
子功能碼 | 0x00,0x0F |
查詢報文數據字段 | 0x00,0x00 |
響應報文數據字段 | 返回加電後沒有返回響應的報文數量 |
- Return Slave Busy Count(17,0x11)
診斷內容 | 返回從站設備忙計數 |
---|---|
子功能碼 | 0x00,0x11 |
查詢報文數據字段 | 0x00,0x00 |
響應報文數據字段 | 返回加電後異常響應忙的報文數量 |
- Return Bus Character Overrun Count(18,0x12)
診斷內容 | 返回總線字符超限的計數 |
---|---|
子功能碼 | 0x00,0x12 |
查詢報文數據字段 | 0x00,0x00 |
響應報文數據字段 | 返回超限的報文數量 |
11(0x0B)獲取通信事件計數器
功能說明該功能碼主要用於(yu) 獲取從(cong) 設備通信計數器中的狀態字和事件計數的值,本功能不支持廣播模式。通過在通信報文之前和之後讀取通信事件計數值,可以確定從(cong) 設備是否正常處理報文。
對於(yu) 正常完成報文處理和傳(chuan) 輸的場合,事件計數器增加1;而對於(yu) 異常響應、輪詢命令或讀取事件計數器(即0x0B功能碼)的場合,則計數器不變。通過【0x08】診斷功能中的子功能碼【Restart Communiaction Option (0x01)】和【Clear Counters and Diagnostic Register(0x00A)】,可以複位事件寄存器。
響應報文對於(yu) 從(cong) 設備,在正常情況下,響應報文返回2個(ge) 字節的狀態字和2個(ge) 字節的事件計數。其中,如果從(cong) 站設備處於(yu) 忙狀態,那麽(me) 狀態字將為(wei) 0xFFFF,否則狀態字將為(wei) 0x0000.
12(0x0C)獲取通信事件記錄
功能說明該功能碼主要用於(yu) 從(cong) 從(cong) 設備獲取轉狀態字、事件計數、報文計數以及事件字節字段。其中狀態字和事件計數與(yu) 功能碼11(0x0B)獲取的值一致。
響應報文對於(yu) 從(cong) 站設備,在正常情況下響應報文包括一個(ge) 2字節狀態字字段、一個(ge) 2字節事件計數字段、一個(ge) 2字節消息計數字段以及0~64個(ge) 字節的事件字段。因為(wei) 事件字段是變長的,所以增加了一個(ge) 1字節的數據長度字段,以方便讀取響應數據。
15(0x0F)寫多個線圈
功能說明該功能碼,用於(yu) 將連續的多個(ge) 線圈或離散輸出設置為(wei) ON/OFF狀態,支持廣播模式,在廣播模式下,所有從(cong) 站設備的同一地址被統一修改。本功能碼中,起始地址字段由2個(ge) 字節構成,取值範圍為(wei) 0x00000xFFFF;而寄存器數量字段由2個(ge) 字節構成,取值範圍為(wei) 0x00010x07B0.
查詢報文查詢報文中,包含了請求數據字段,用於(yu) 定義(yi) ON/OFF狀態。數據字段中為(wei) 邏輯1的位對應ON;邏輯0的位對應OFF。其中,ON/OFF與(yu) 數據字段的對應關(guan) 係可參考“01(0x01)讀取線圈/離散量輸出狀態”中的內(nei) 容
響應報文對於(yu) 從(cong) 設備,在正常情況下響應報文包括功能碼、起始地址以及寫(xie) 入的線圈數量。
16(0x10)寫多個保持寄存器
功能說明該功能碼用於(yu) 設置或寫(xie) 入從(cong) 設備保持寄存器的多個(ge) 連續的地址塊(1123個(ge) 寄存器),支持廣播模式,在廣播模式下,所有從(cong) 站設備的同一地址的值將被統一修改。本功能碼中,起始地址字段由2個(ge) 字節構成,取值範圍為(wei) 0x00000xFFFF;而寄存器數量字段由2個(ge) 字節構成,取值範圍為(wei) 0x0001~0x007B。
查詢報文查詢報文中,包含了請求數據字段。數據字段保存需寫(xie) 入的數值,各數據按每個(ge) 寄存器2個(ge) 字節存放。
響應報文對於(yu) 從(cong) 設備,在正常情況下響應報文包括功能碼、起始地址以及寫(xie) 入的寄存器數量。
在實際開發過程中,功能碼“16(0x10)寫(xie) 多個(ge) 寄存器”常常用於(yu) 方便用戶寫(xie) 入多字節類型的數據。
17(0x11)報告從站ID(僅用於串行鏈路)
功能說明該功能碼用於(yu) 讀取從(cong) 站設備的ID、類型描述、當前狀態以及其他信息,不支持廣播模式。響應消息的構成依賴於(yu) 設備而不同。
響應報文對於(yu) 從(cong) 設備,在正常情況下響應報文包括從(cong) 站ID、運行狀態以及其他附加信息。響應報文的組成由開發者決(jue) 定。
Modbus異常響應
以上介紹了一些常見的公共功能碼的報文(消息幀)構成,對於(yu) 廣播模式以外的查詢報文,都希望能夠獲取一個(ge) 正常的響應報文。在通常的情況下,從(cong) 站設備將返回一個(ge) 正常響應報文,但是,在某些特殊情況下,將返回異常響應報文。對於(yu) 查詢報文,存在以下4中處理反饋:
- 正常接收,正常處理,返回正常響應報文;
- 因為通信錯誤等原因,造成從站設備沒有接收到查詢報文,主站設備將按超時處理;
- 從站設備接收到的查詢報文存在通信錯誤(例如LRC、CRC錯誤等),此時從站設備將丟棄報文不響應,主站設備將按超時處理;
- 從站設備接收到正確的報文,但是超過處理範圍(例如,不存在的功能碼或者寄存器等),此時從站設備將返回包括異常碼(Exception Code)的響應報文。
異常響應報文由從(cong) 站地址、功能碼以及異常碼構成。其中,功能碼與(yu) 正常響應報文不同,在異常響應報文中,功能碼最高位(即MSB)被設置為(wei) 1.因為(wei) Modbus協議中功能碼占用一個(ge) 字節,故用表達式描述為(wei) :異常功能碼=正常功能碼+0x80.
常見的異常碼說明
異常碼 名稱 說明 01 非法功能碼 從站設備不支持此功能碼 02 非法數據地址 指定的數據地址在從站設備中不存在 03 非法數據值 指定的數據超過範圍或者不允許使用 04 從站設備故障 從站設備處理響應的過程中,出現未知錯誤等