①Modbus協定是一種請求/應答的序列鏈路協定,是一種工業現場匯流排協定標準。是一項應用層報文傳輸協定,用於在通過不同型別的匯流排或網路連線的裝置之間的客戶機/伺服器通訊。
②Modbus協定是一項應用層報文傳輸協定,包括ASCII、RTU、TCP三種報文型別。
③標準的Modbus協定物理層介面有RS232、RS422、RS485和乙太網介面,採用master/slave方式通訊。
④MODBUS 是一項應用層報文傳輸協定,用於在通過不同型別的匯流排或網路連線的裝置之間的客戶機/伺服器通訊。
MODBUS 通用幀如圖:
Modbus暫存器分為四種,如表
暫存器種類 | 資料型別 | 存取型別 | 功能碼 | PLC地址 | 暫存器地址 |
---|---|---|---|---|---|
線圈暫存器 | 位 | 讀寫 | 01H 05H 0FH | 00001-09999 | 0000H-FFFFH |
離散輸入暫存器 | 位 | 只寫 | 02H | 10001-19999 | 0000H-FFFFH |
輸入暫存器 | 字 | 只寫 | 04H | 30001-39999 | 0000H-FFFFH |
保持暫存器 | 字 | 讀寫 | 03H 06H 10H | 40001-49999 | 0000H-FFFFH |
Modbus中常用功能碼有8個,可以分為位元運算和字操作兩類,如表所示:
功能碼 | 描述 | PLC地址 | 暫存器地址 | 位/字操作 | 運算元量 |
---|---|---|---|---|---|
01H | 讀線圈暫存器 | 00001-09999 | 0000H-FFFFH | 位元運算 | 單個或多個 |
02H | 讀離散輸入暫存器 | 10001-19999 | 0000H-FFFFH | 位元運算 | 單個或多個 |
03H | 讀保持暫存器 | 40001-49999 | 0000H-FFFFH | 字操作 | 單個或多個 |
04H | 讀輸入暫存器 | 30001-39999 | 0000H-FFFFH | 字操作 | 單個或多個 |
05H | 寫單個線圈暫存器 | 00001-09999 | 0000H-FFFFH | 位元運算 | 單個 |
06H | 寫單個保持暫存器 | 40001-49999 | 0000H-FFFFH | 字操作 | 單個 |
0FH | 寫多個線圈暫存器 | 00001-09999 | 0000H-FFFFH | 位元運算 | 多個 |
10H | 寫多個保持暫存器 | 40001-49999 | 0000H-FFFFH | 字操作 | 多個 |
●功能碼01H讀取Modbus從機中線圈暫存器的狀態,可以是單個暫存器,或者多個連續的暫存器。
●假設從機地址為01H,讀取的線圈暫存器的起始地址為0017H,讀取38個暫存器,指令如表所示:
傳送讀線圈暫存器指令:
從機地址 | 功能碼 | 起始地址高位 | 起始地址低位 | 暫存器數量高位 | 暫存器數量低位 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|
01 | 01 | 00 | 17 | 00 | 26 | 0D | D4 |
●響應:各線圈的狀態與資料內容的每個bit對應,1代表ON,0代表OFF。如果查詢的線圈數量不是8的倍數,則在最後一個位元組的高位補0。
讀線圈暫存器狀態響應:
從機地址 | 功能碼 | 返回位元組數 | 資料1 | 資料2 | 資料3 | 資料4 | 資料5 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|---|---|
01 | 01 | 05 | CD | 6B | B2 | 0E | 1B | 44 | EA |
●其中,第一個位元組CDH對應線圈0017H到001E的狀態,轉為二進位制是11001101,其中bit0對應0017H,bit7對應001E,如表所示:
線圈0017H到001EH的狀態:
001EH | 001DH | 001CH | 001BH | 001AH | 0019H | 0018H | 0017H |
---|---|---|---|---|---|---|---|
ON | ON | OFF | OFF | ON | ON | OFF | ON |
●最後一個位元組為1BH,對應線圈0037H到003CH的狀態,轉為二進位制是00011011,其中bit0對應0037H,bit5對應003CH,其餘兩位用0填充,如表所示:
線圈0037H到003CH的狀態:
001EH | 001DH | 001CH | 001BH | 001AH | 0019H | 0018H | 0017H |
---|---|---|---|---|---|---|---|
ON | ON | OFF | OFF | ON | ON | OFF | ON |
●功能碼02H讀取Modbus從機中離散輸入暫存器的狀態,可以是單個暫存器,或者多個連續的暫存器。
●假設從機地址為01H,讀取的離散輸入暫存器的起始地址為00C4H,讀取22個暫存器,指令如表所示:
傳送讀離散輸入暫存器指令:
從機地址 | 功能碼 | 起始地址高位 | 起始地址低位 | 暫存器數量高位 | 暫存器數量低位 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|
01 | 02 | 00 | C4 | 00 | 16 | B8 | 39 |
●響應:各個離散輸入暫存器的狀態與資料內容的每個bit對應,1代表ON,0代表OFF。如果查詢的線圈數量不是8的倍數,則在最後一個位元組的高位補0
讀離散輸入暫存器的返回結果:
從機地址 | 功能碼 | 返回位元組數 | 資料1 | 資料2 | 資料3 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|
01 | 02 | 03 | AC | DB | 35 | 22 | 88 |
●其中,第一個位元組ACH對應00C4H到00CBH暫存器的狀態,轉為二進位制是10101100,其中bit0對應00C4H,bit7對應00CB,如表所示:
暫存器00C4H到00CBH的狀態:
00CBH | 00CAH | 00C9H | 00C8H | 00C7H | 00C6H | 00C5H | 00C4H |
---|---|---|---|---|---|---|---|
1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 |
ON | OFF | ON | OFF | ON | ON | OFF | OFF |
●最後一個位元組為35H,對應暫存器00D4H到00D9H的狀態,轉為二進位制是00110101,其中bit0對應00D4H,bit5對應00D9H,其餘兩位用0填充,如表所示:
暫存器00D4H到00D9H的狀態
00DBH | 00DAH | 00D9H | 00D8H | 00D7H | 00D6H | 00D5H | 00D4H |
---|---|---|---|---|---|---|---|
0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 |
ON | OFF | ON | OFF | ON | ON | OFF | OFF |
●功能碼03H讀取Modbus從機中保持暫存器的資料,可以是單個暫存器,或者多個連續的暫存器。
●假設從機地址為01H,讀取的保持暫存器的起始地址為006BH,讀取3個暫存器,指令如表所示:
傳送讀保持暫存器指令:
從機地址 | 功能碼 | 起始地址高位 | 起始地址低位 | 暫存器數量高位 | 暫存器數量低位 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|
01 | 03 | 00 | 6B | 00 | 03 | 74 | 17 |
●響應:每個保持暫存器的長度為2個位元組。保持暫存器之間,低地址暫存器先傳輸,高地址暫存器後傳輸。單個保持暫存器,高位元組資料先傳輸,低位元組資料後傳輸。
讀保持暫存器的返回結果:
從機地址 | 功能碼 | 位元組數 | 006BH高位位元組 | 006BH低位位元組 | 006CH高位位元組 | 006CH低位位元組 | 006BH高位位元組 | 006BH低位位元組 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|---|---|---|
01 | 03 | 06 | 00 | 6B | 00 | 13 | 00 | 00 | F5 | 79 |
●功能碼04H讀取Modbus從機中輸入暫存器的資料,可以是單個暫存器,或者多個連續的暫存器。
●假設從機地址為01H,讀取的保持暫存器的起始地址為0008H,讀取2個暫存器,指令如表所示:
傳送讀輸入暫存器指令:
從機地址 | 功能碼 | 起始地址高位 | 起始地址低位 | 暫存器數量高位 | 暫存器數量低位 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|
01 | 04 | 00 | 6B | 00 | 02 | 00 | 17 |
●響應:每個輸入暫存器的長度為2個位元組。輸入暫存器之間,低地址暫存器先傳輸,高地址暫存器後傳輸。單個輸入暫存器,高位元組資料先傳輸,低位元組資料後傳輸。
讀輸入暫存器的返回結果:
從機地址 | 功能碼 | 位元組數 | 0008H高位位元組 | 0008H低位位元組 | 0009H高位位元組 | 0009H低位位元組 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|---|
01 | 04 | 04 | 00 | 0A | 00 | 0B | 9A | 41 |
●功能碼05H寫單個線圈暫存器,FF00H請求線圈處於ON狀態,0000H請求線圈處於OFF狀態。
●假設從機地址為01H,線圈暫存器的地址為00ACH,使其處於ON狀態的指令,如表所示:
傳送寫單個線圈指令:
從機地址 | 功能碼 | 起始地址高位 | 起始地址低位 | 暫存器數量高位 | 暫存器數量低位 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|
01 | 05 | 00 | AC | FF | 00 | 4C | 1B |
●響應:如果寫入成功,返回傳送的指令,即010500ACFF004C1B。
從機地址 | 功能碼 | 起始地址高位 | 起始地址低位 | 暫存器數量高位 | 暫存器數量低位 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|
01 | 05 | 00 | AC | FF | 00 | 4C | 1B |
●功能碼06H寫單個保持暫存器。
●假設從機地址為01H,保持暫存器的地址為0001H,資料位0003H,指令如表所示:
傳送寫單個保持暫存器指令:
從機地址 | 功能碼 | 起始地址高位 | 起始地址低位 | 暫存器數量高位 | 暫存器數量低位 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|
01 | 06 | 00 | 01 | 00 | 03 | 98 | 0B |
●響應:如果寫入成功,返回傳送的指令,即010600010003980B。
從機地址 | 功能碼 | 起始地址高位 | 起始地址低位 | 暫存器數量高位 | 暫存器數量低位 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|
01 | 06 | 00 | 01 | 00 | 03 | 98 | 0B |
●功能碼0FH寫多個線圈暫存器。如果對應的資料位為1,表示線圈狀態為ON;如果對應的資料位為0,表示線圈狀態為OFF。線圈暫存器之間,低地址暫存器先傳輸,高地址暫存器後傳輸。單個線圈暫存器,高位元組資料先傳輸,低位元組資料後傳輸。如果寫入的線圈暫存器的個數不是8的倍數,則在最後一個位元組的高位補0。
●假設從機地址為01H,線圈暫存器的起始地址為0013H,寫入10個暫存器,指令如表所示:
傳送寫入多個線圈暫存器指令:
從機地址 | 功能碼 | 起始地址高位 | 起始地址低位 | 暫存器數量高位 | 暫存器數量低位 | 位元組數 | 資料1 | 資料2 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|---|---|---|
01 | 0F | 00 | 13 | 00 | 0A | 02 | CD | 01 | 72 | CB |
●其中,CDH對應線圈0013H到001AH的內容,01H對應線圈001B到001CH的內容,未使用位用0填充。
線圈暫存器0013H到001CH的內容:
001AH | 0019H | 0018H | 0017H | 0016H | 0015H | 0014H | 0013H |
---|---|---|---|---|---|---|---|
1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 |
0022H | 0021H | 0020H | 001FH | 001EH | 001DH | 001CH | 001BH |
---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
●響應:如果寫入成功,返回寫入的暫存器數量,如表所示
寫多個線圈暫存器的返回結果:
從機地址 | 功能碼 | 起始地址高位 | 起始地址低位 | 暫存器數量高位 | 暫存器數量低位 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|
01 | 0F | 00 | 13 | 00 | 0A | 24 | 09 |
●功能碼10H寫多個保持暫存器,其中每個保持暫存器的長度為兩個位元組。
●假設從機地址為01H,保持暫存器的起始地址為0001H,寫入2個暫存器,指令如表所示:
傳送寫入多個保持暫存器指令:
從機地址 | 功能碼 | 起始地址高位 | 起始地址低位 | 暫存器數量高位 | 暫存器數量低位 | 位元組數 | 0001H高位 | 0001H低位 | 0002H高位 | 0002H低位 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
01 | 010 | 00 | 01 | 00 | 02 | 04 | 00 | 0A | 01 | 02 | 92 | 30 |
●響應:如果寫入成功,返回寫入的暫存器數量,如表所示:
從機地址 | 功能碼 | 起始地址高位 | 起始地址低位 | 暫存器數量高位 | 暫存器數量低位 | CRC高位 | CRC低位 |
---|---|---|---|---|---|---|---|
01 | 10 | 00 | 01 | 00 | 02 | 10 | 08 |
●功能碼詳解主要參考文獻為:
https://blog.csdn.net/lakerszhy/article/details/68927178?locationNum=4&fps=1
編碼系統:
十六進位制,ASCII 字元 0-9, A-F。報文中每個 ASCII 字元含有 1 個十六進位制字元
Bits per Byte:
1 起始位
7 資料位, 首先傳送最低有效位
1 位作為奇偶校驗
1 停止位
奇偶校驗 :
●偶校驗是要求的, 其它模式 ( 奇校驗, 無校驗 ) 也可以使用。 為了保證與其它產品的最大相容性,同時支援無校驗模式是建議的。預設校驗模式模式 必須為偶校驗。
注 : 使用無校驗要求 2 個停止位。
字序列傳送:
●每個字元或位元組均由此順序傳送(從左到右):
●最低有效位 (LSB) . . . 最高有效位 (MSB),資料傳輸如圖:
●有奇偶檢驗
●無奇偶檢驗:
Modbus ASCII 報文幀:
在 ASCII 模式, 報文用特殊的字元區分幀起始和幀結束。一個報文必須以一個‘冒號’ ( : )(ASCII 十六進位制 3A )起始,以 ‘回車-換行’ (CR LF) 對 (ASCII 十六進位制 0D 和 0A) 結束。
注 : LF 字元可以通過特定的 Modbus 應用命令 (參見 Modbus 應用協定規範) 改變。
對於所有的域,允許傳送的字元為十六進位制 0–9, A–F (ASCII 編碼)。 裝置連續的監視匯流排上的 ‘冒號’ 字元。 當收到這個字元后,每個裝置解碼後續的字元一直到幀結束。
報文幀包括:起始、地址、功能碼、資料、LRC校驗位、結束。如圖:
注:每個字元子節需要用兩個字元編碼。因此,為了確保 ASCII 模式 和 RTU 模式在 Modbus 應用級相容,ASCII
資料域最巨量資料長度為 (2x252) 是 RTU 資料域 (252) 的兩倍。
必然的, Modbus ASCII 幀的最大尺寸為 513 個字元。
ASCII 傳輸模式狀態如圖:
幀檢驗域:
①幀檢驗方式為::縱向冗餘校驗 (LRC - Longitudinal Redundancy Checking)
②LRC 域檢驗不包括起始「冒號」和結尾 CRLF 對的整個報文的內容。不管報文有無奇偶校驗,均執行此檢驗。
③LRC 域為一個子節,包含一個 8 位二進位制值。LRC 值由傳送裝置計算,然後將 LRC 附在報文後面。接收裝置在接收報文時重新計算 LRC 的值,並將計算結果於實際接收到的 LRC 值相比較。如果兩個值不相等,則為錯誤。LRC 的計算, 對報文中的所有的連續 8 位位元組相加,忽略任何進位,然後求出其二進位制二補數。執行檢驗針對不包括起始「冒號」和結尾 CRLF 對的整個 ASCII 報文域的內容。在 ASCII 模式,LRC 的結果被 ASCII 編碼為兩個位元組並放置於 ASCII 模式報文幀的結尾, CRLF 之前。
RTU模式:報文中每個 8 位位元組含有兩個 4 位十六進位制字元。這種模式的主要優點是較高的資料密度,在相同的波特率下比ASCII 模式有更高的吞吐率。每個報文必須以連續的字元流傳送。
編碼系統:
8–位二進位制報文中每個 8 位位元組含有兩個 4 位十六進位制字元(0–9, A–F)
Bits per Byte:
1 起始位
8 資料位, 首先傳送最低有效位
1 位作為奇偶校驗
1 停止位
奇偶校驗 :
●偶校驗是要求的, 其它模式 ( 奇校驗, 無校驗 ) 也可以使用。 為了保證與其它產品的最大相容性,同時支援無校驗模式是建議的。預設校驗模式模式 必須為偶校驗。
注 : 使用無校驗要求 2 個停止位。
字序列傳送:
●每個字元或位元組均由此順序傳送(從左到右):
●最低有效位 (LSB) . . . 最高有效位 (MSB),資料傳輸如圖:
●有奇偶校驗:
●無奇偶校驗:
Modbus RTU 報文幀:
RTU 報文幀描述如圖 :
注意: Modbus RTU 幀最大為 256 位元組。
●在 RTU 模式,報文幀由時長至少為 3.5 個字元時間的空閒間隔區分。在後續的部分,這個時間區間被稱作 t3.5。如果兩個字元之間的空閒間隔大於 1.5 個字元時間,則報文幀被認為不完整應該被接收節點丟棄。傳輸格式如圖:
注 :
RTU 接收驅動程式的實現,由於 t1.5 和 t3.5 的定時,隱含著大量的對中斷的管理。在高通訊速率下,這導致 CPU 負擔加重。因此,在通訊速率等於或低於 19200 Bps 時,這兩個定時必須嚴格遵守;對於波特率大於 19200 Bps 的情形,應該使用 2 個定時的固定值:建議的字元間超時時間(t1.5)為 750µs,幀間的超時時間 (t1.5) 為 1.750ms。
●下圖表示了對 RTU 傳輸模式狀態圖的描述。 「主節點」 和 「子節點」 的不同角度均在相同的圖中表示:
上面狀態圖的一些解釋:
● 從 「初始」 態到 「空閒」 態轉換需要 t3.5 定時超時: 這保證幀間延遲
● 「空閒」 態是沒有傳送和接收報文要處理的正常狀態。
●在 RTU 模式, 當沒有活動的傳輸的時間間隔達 3.5 個字元長時,通訊鏈路被認為在 「空閒」
態。
●當鏈路空閒時, 在鏈路上檢測到的任何傳輸的字元被識別為幀起始。 鏈路變為 「活動」 狀態。
然後, 當鏈路上沒有字元傳輸的時間間個達到 t3.5 後,被識別為幀結束。
● 檢測到幀結束後,完成 CRC 計算和檢驗。然後,分析地址域以確定幀是否發往此裝置,如果不是,則丟棄此幀。 為了減少接收處理時間,地址域可以在一接到就分析,而不需要等到整個幀結束。這樣,CRC 計算只需要在幀定址到該節點 (包括廣播幀) 時進行。
幀檢驗域:
①幀檢驗方式為:迴圈冗餘校驗 (CRC)
②CRC 包含由兩個 8 位位元組組成的一個 16 位值。
③CRC 域作為報文的最後的域附加在報文之後。計算後,首先附加低位元組,然後是高位元組。CRC
④高位元組為報文傳送的最後一個子節。附加在報文後面的 CRC 的值由傳送裝置計算。接收裝置在接收報文時重新計算 CRC 的值,
並將計算結果於實際接收到的 CRC 值相比較。如果兩個值不相等,則為錯誤。CRC 的計算, 開始對一個 16 位暫存器預裝全 1。 然後將報文中的連續的 8 位子節對其進行後續的計算。只有字元中的 8 個資料位參與生成 CRC 的運算,起始位,停止位和校驗位不參與 CRC計算。
⑤CRC 的生成過程中, 每個 8–位字元與暫存器中的值互斥或。然後結果向最低有效位(LSB)方向移動(Shift) 1 位,而最高有效位(MSB)位置充零。 然後提取並檢查 LSB:如果 LSB 為 1, 則暫存器中的值與一個固定的預置值互斥或;如果 LSB 為 0, 則不進行互斥或操作。
這個過程將重複直到執行完 8 次移位。完成最後一次(第 8 次)移位及相關操作後,下一個 8位元位元組與暫存器的當前值互斥或,然後又同上面描述過的一樣重複 8 次。當所有報文中子節都運算之後得到的暫存器忠的最終值,就是 CRC。
●ASCII模式,起始符是一個冒號「:」 ASCII碼為3AH H是十六進位製表示結束符是「回車換行符」 ASCII碼為0DH 0AH
●RTU 模式,起始符與結束符都是至少3.5倍字元傳輸時間的停頓間隔時間標定3.5倍字元的傳輸時間的計算方法,根據「通訊格式、傳輸方式及MODBUS協定簡介」視訊中介紹的一個字元的傳輸時間的計算方法,很容易計算出來。
2、校驗和計算不一樣;
●ASCII模式,是LRC校驗
●RTU 模式,是CRC校驗
3、傳送格式不一樣;
●ASCII模式,在訊息中的每個位元組都作為兩個ASCII字元傳送
●RTU 模式,在訊息中的每個位元組包含兩個 4Bit的十六進位制字元。
●ModbusTCP的資料框可分為兩部分:MBAP+PDU。
MBAP為報文頭,長度為7位元組,組成如下:
事務緊急處理標識 | 協定標識 | 長度 | 單元識別符號 |
---|---|---|---|
2位元組 | 2位元組 | 2位元組 | 1位元組 |
事務處理標識 : 可以理解為報文的序列號,一般每次通訊之後就要加1以區別不同的通訊資料包文。
協定識別符號 : 00 00表示ModbusTCP協定。
長度 : 表示接下來的資料長度,單位為位元組。
單元識別符號 : 可以理解為裝置地址。
PDU由功能碼+資料組成。功能碼為1位元組,資料長度不定,由具體功能決定。該處使用的url網路請求的資料。
●主站請求:功能碼+資料
●從站正常響應:請求功能碼+響應資料
●從站異常響應:異常功能碼+異常碼,其中異常功能碼即將請求功能碼的最高有效位置1,異常碼指示差錯型別
●注意:需要超時管理機制,避免無期限的等待可能不出現的應答
在linux下使用modbusTCP連線
IANA(Internet Assigned Numbers Authority,網際網路編號分配管理機構)給Modbus協定賦予TCP埠號為502,這是目前在儀表與自動化行業中唯一分配到的埠號。
通訊過程
1.connect 建立TCP連線
2.準備modbus報文
3.使用send命令傳送報文
4.在同一連線下等待應答
5.使用recv命令讀取報文,完成一次資料交換
6.通訊任務結束時,關閉TCP連線
有點累了,改天再寫。。。
如需要技術指導,小編QQ:271841502
如需要進入QQ技術交流群,電賽資料共用群:484040216
電賽資料共用群二維條碼如下: