Modbus 通過多條線在設備之間傳輸數據,其中最簡單的設置是使用串行電纜連接主機和從機。數據以 0 或 1 的字符串傳輸,一個數字就是一個比特。0代表正電壓,而1代表負電壓。比特數據傳輸速度非常快,常見的傳輸速度為9600波特(即9600 bits/s)。
信息存儲在從站的四個不同表中。兩個表存儲數字量,稱為線圈;另外兩個表存儲模擬量,稱為寄存器。對于線圈和寄存器,一個是只讀的,一個是可讀寫的。每個表可以存儲 9999 個值。線圈為一位,地址為0000~270E;寄存器為一個字(16 位,2 字節),地址也是從 0000 到 270E。
線圈/寄存器編號 | 數據地址 | 類型 | 表名 |
1-9999 | 0000 到 270E | 讀寫 | 離散輸出線圈 |
10001-19999 | 0000 到 270E | 只讀 | 離散輸入觸點 |
30001-39999 | 0000 到 270E | 只讀 | 模擬輸入寄存器 |
40001-49999 | 0000 到 270E | 讀寫 | 模擬輸出保持寄存器 |
Coil/Register 的數量可以看作是地址的名稱,它們不會出現在實際發送的消息中。數據地址在實際發送的消息中。
比如第一個Holding Register的編號是40001,它的數據地址是0000,這兩個編號的區別是因為偏移量。
在網絡中,每個從機都被分配了一個唯一的設備地址,范圍從 1 到 247。當主機請求數據時,發送的消息的第一個字節是從機地址。這樣,從機接收到第一個字節后,就知道是否需要忽略后續信息。
主機發送的第二個字節是功能碼。該功能碼告訴slave需要訪問哪個表,是往表中寫數據還是從表中讀數據。
有趣的代碼 | 行動 | 表名 |
01(01 十六進制) | 讀 | 離散輸出線圈 |
05(05 六角) | 寫單 | 離散輸出線圈 |
15(0F 十六進制) | 寫多個 | 離散輸出線圈 |
02(02 十六進制) | 讀 | 離散輸入觸點 |
04(04 六角) | 讀 | 模擬輸入寄存器 |
03(03 六角) | 讀 | 模擬輸出保持寄存器 |
06(06 六角) | 寫單 | 模擬輸出保持寄存器 |
16(10 六角) | 寫多個 | 模擬輸出保持寄存器 |
CRC代表Cyclic Redundancy check,就是在每條消息發送后增加兩個字節,以檢查發送或接收是否有錯誤。消息的每個字節都用于計算 CRC。接收器在接收數據時計算 CRC。然后,它將計算結果與發送方計算的 CRC 進行比較。如果兩者不同,則會發生錯誤。
數據地址 | 讀 | 寫單 | 寫多個 |
離散輸出線圈 0xxxx | FC01 | FC05 | FC15 |
離散輸入觸點 1xxxx | FC02 | 不適用 | 不適用 |
模擬輸入寄存器 3xxxx | FC04 | 不適用 | 不適用 |
模擬輸出保持寄存器 4xxxx | FC03 | FC06 | FC16 |
注:FC 代表功能代碼
數據請求:
11 01 0013 0025 0E84
11:從機地址(0x11 = 17)
01:功能碼01(讀取線圈狀態)
0013:線圈首地址(0x0013=19,+1偏移=#20線圈)
0025:要讀取的線圈數(0x25 = 37, 20~56)
0E84:CRC
數據響應
11 01 05 CD6BB20E1B 45E6
11:從地址(0x11 = 17)
01:功能碼01(讀取線圈狀態)
05:之后的字節數(37/8=5 字節)
CD:線圈 27-20 (1100 1101)
6B:線圈 35-28 (0110 1011)
B2:線圈 43-36 (1011 0010)
0E:線圈 51-44 (0000 1110)
1B:3個空格和線圈56-52 (0001 1011)
45E6:CRC