Modbus通訊協定詳解
Modbus RTU通訊協定在資料通訊上采用主從應答的方式進行。隻能由主機(PC,HMI等)通過唯一從機位址發起請求,從機(終端裝置)根據主機請求進行響應,即半雙工通訊。該協定隻允許主機發起請求,從機進行被動響應,是以從機不會主動占用通訊線路造成資料沖突。
類似Modbus RTU協定的主從應答協定還有西門子的PPI、電表常用的DL/T645-2007等協定。
一、modbus協定格式
資訊傳輸為異步方式,使用16進制進行通訊,資訊幀格式:
位址碼 | 功能碼 | 資料區 | CRC校驗碼 |
1位元組 | 1位元組 | N位元組 | 2位元組 |
位址碼
位址碼是每個通訊資訊幀的第一個位元組,一般支援1到247,部分裝置也支援0位址,用于接收主機的廣播資料,每個從機在總線上位址必須唯一,隻有與主機發送的位址碼相符的從機才能響應傳回資料。
功能碼
功能碼是每個通訊資訊幀的第二個位元組。主機發送,通過功能碼告知從機裝置應當執行何種操作。
常見的八種功能碼:
功能碼 | 定義 | 操作 |
01H | 讀取線圈 | 讀取一個或多個連續線圈狀态 |
05H | 寫單個線圈 | 操作指定位置的線圈狀态 |
0FH | 寫多個線圈 | 操作多個連續線圈狀态 |
02H | 讀取離散量輸入 | 讀取一個或多個連續離散輸入狀态 |
04H | 讀取輸入寄存器 | 讀取一個或多個連續輸入寄存器資料 |
03H | 讀保持寄存器 | 讀取一個或多個保持寄存器資料 |
06H | 寫單個保持寄存器 | 把兩個十六進制資料寫入對應位置 |
10H | 寫多個保持寄存器 | 把4*N個十六進制資料寫入N個連續保持寄存器 |
資料區
資料區随功能碼以及資料方向的不同而不同,這些資料可以是“寄存器首位址+讀取寄存器數量”、“寄存器位址+操作資料”、“寄存器首位址+操作寄存數量+資料長度+資料”等不同的組合,在“功能碼分析”詳解不同功能碼的資料區。
Modbus CRC校驗
Modbus RTU協定常用與工業現場對資料傳輸的穩定性和正确性有較高的要求,是以通過CRC校驗保證資料傳輸的正确性和完整性。
二、錯誤回報
位址與CRC校驗錯誤并不會收到從機的資料回報,其他錯誤将向主機傳回錯誤碼。資料幀的第二位加上0X80表示請求發生錯誤(非法功能碼、非法資料值等),錯誤資料幀如下:
位址碼 | 功能碼 | 錯誤碼 | CRC校驗碼 |
1位元組 | 1位元組 | 1位元組 | 2位元組 |
常見錯誤碼如下:
值 | 名稱 | 說明 |
01H | 非法的功能碼 | 不支援該功能碼操作寄存器 |
02H | 非法的寄存器位址 | 通路裝置禁止通路的寄存器 |
03H | 非法的資料值 | 寫入不支援的參數值 |
04H | 從機故障 | 裝置工作異常 |
三、通訊資訊傳輸過程
通訊指令由主機發送從機時,與主機發送的位址碼相符的從機接收通訊指令,如果CRC校驗無誤,則執行相應的操作,然後把執行結果(資料)傳回給主機。傳回資訊中包含位址碼、功能碼、執行後的資料以及CRC校驗碼。如果位址不比對或者CRC校驗出錯就不傳回任何資訊。
四、功能碼分析
功能碼01H:讀線圈
例如:主機要讀取從機位址為01H,起始線圈位址為00H的1個線圈狀态,主機發送:
主機發送 | 發送資料(HEX) | |
位址碼 | 01 | |
功能碼 | 01 | |
起始線圈位址 | 高位元組 | 00 |
低位元組 | 00 | |
線圈數量 | 高位元組 | 00 |
低位元組 | 01 | |
CRC校驗 | 低位元組 | FD |
高位元組 | CA |
如果從機寄存器00H線圈閉合,從機傳回:
從機傳回 | 發送資料(HEX) | |
位址碼 | 01 | |
功能碼 | 01 | |
位元組數 | 01 | |
線圈狀态 | 01 | |
CRC校驗碼 | 低位元組 | 90 |
高位元組 | 48 |
仿真示範:
功能碼0FH:寫多個線圈
例如:主機要控制從機位址為01H,起始線圈位址為00H的4個線圈狀态,主機發送:
主機發送 | 發送資料(HEX) | |
位址碼 | 01 | |
功能碼 | 0F | |
起始線圈位址 | 高位元組 | 00 |
低位元組 | 00 | |
線圈數量 | 高位元組 | 00 |
低位元組 | 04 | |
寫入位元組數 | 01 | |
控制方式 | 00(全部斷開)、0F(全部閉合) | |
CRC校驗 | 低位元組 | XX |
高位元組 | XX |
功能碼0FH操作,從機傳回:
從機傳回 | 發送資料(HEX) | |
位址碼 | 01 | |
功能碼 | 0F | |
起始線圈位址 | 高位元組 | 00 |
低位元組 | 00 | |
線圈數量 | 高位元組 | 00 |
低位元組 | 04 | |
CRC校驗 | 低位元組 | 54 |
高位元組 | 08 |
仿真示範:
功能碼02H:讀離散輸入
例如:主機要讀取從機位址為01H,起始離散量位址為00H的4個輸入狀态,主機發送:
主機發送 | 發送資料(HEX) | |
位址碼 | 01 | |
功能碼 | 02 | |
起始離散量位址 | 高位元組 | 00 |
低位元組 | 00 | |
讀取數量 | 高位元組 | 00 |
低位元組 | 04 | |
CRC校驗 | 低位元組 | 79 |
高位元組 | C9 |
如果從機首位址00H開始的4離散輸入全部檢測到輸入,從機傳回:
從機傳回 | 發送資料(HEX) | |
位址碼 | 01 | |
功能碼 | 02 | |
位元組數 | 01 | |
離散輸入狀态 | 0F | |
CRC校驗碼 | 低位元組 | E1 |
高位元組 | 8C |
仿真示範:
功能碼04H:讀取輸入寄存器
例如:主機要讀取從機位址為01H,起始寄存器位址為02H的1個輸入寄存器資料,主機發送:
主機發送 | 發送資料(HEX) | |
位址碼 | 01 | |
功能碼 | 04 | |
起始寄存器位址 | 高位元組 | 00 |
低位元組 | 02 | |
寄存器數量 | 高位元組 | 00 |
低位元組 | 01 | |
CRC校驗 | 低位元組 | 90 |
高位元組 | 0A |
如果從機輸入寄存器02H的資料為3344H,從機傳回:
從機傳回 | 發送資料(HEX) | |
位址碼 | 01 | |
功能碼 | 04 | |
位元組數 | 02 | |
寄存器05H資料 | 高位元組 | 33 |
低位元組 | 44 | |
CRC校驗碼 | 低位元組 | AD |
高位元組 | F3 |
仿真示範:
功能碼03H:讀保持寄存器
例如:主機要讀取從機位址為01H,起始寄存器位址為05H的2個保持寄存器資料,主機發送:
主機發送 | 發送資料(HEX) | |
位址碼 | 01 | |
功能碼 | 03 | |
起始寄存器位址 | 高位元組 | 00 |
低位元組 | 05 | |
寄存器數量 | 高位元組 | 00 |
低位元組 | 02 | |
CRC校驗 | 低位元組 | D4 |
高位元組 | 0A |
如果從機保持寄存器05H、06H的資料為1122H、3344H,從機傳回:
從機傳回 | 發送資料(HEX) | |
位址碼 | 01 | |
功能碼 | 03 | |
位元組數 | 04 | |
寄存器05H資料 | 高位元組 | 11 |
低位元組 | 22 | |
寄存器06H資料 | 高位元組 | 33 |
低位元組 | 44 | |
CRC校驗碼 | 低位元組 | 4B |
高位元組 | C6 |
仿真示範:
功能碼06H:寫單個保持寄存器
例如:主機寫入9988H的資料給從機位址為01H,寄存器位址為0050H的寄存器,主機發送:
主機發送 | 發送資料(HEX) | |
位址碼 | 01 | |
功能碼 | 06 | |
寄存器位址 | 高位元組 | 00 |
低位元組 | 50 | |
寫入值 | 高位元組 | 99 |
低位元組 | 88 | |
CRC校驗 | 低位元組 | E3 |
高位元組 | ED |
從機傳回與主機請求相同;
功能碼10H:寫多個保持寄存器
例如:主機要把資料0005H、2233H儲存到從機位址為01H,起始寄存器位址為0020H的2個寄存器中,主機發送:
主機發送 | 發送資料(HEX) | |
位址碼 | 01 | |
功能碼 | 10 | |
起始寄存器位址 | 高位元組 | 00 |
低位元組 | 20 | |
寄存器數量 | 高位元組 | 00 |
低位元組 | 02 | |
寫入位元組數 | 04 | |
0000H 寄存器待寫入 | 高位元組 | 00 |
低位元組 | 05 | |
0001H 寄存器待寫入 | 高位元組 | 22 |
低位元組 | 33 | |
CRC校驗 | 低位元組 | B9 |
高位元組 | 03 |
功能碼10H操作,從機傳回:
從機傳回 | 發送資料(HEX) | |
位址碼 | 01 | |
功能碼 | 10 | |
起始寄存器位址 | 高位元組 | 00 |
低位元組 | 20 | |
寄存器數量 | 高位元組 | 00 |
低位元組 | 02 | |
CRC校驗 | 低位元組 | 40 |
高位元組 | 02 |