Modbus常用功能碼學習及實例
一.MODBUS寄存器種類說明雖然MODBUS支持諸多功能碼,但其中隻涉及到四種寄存器:線圈寄存器、離散輸入寄存器、保持寄存器、輸入寄存器。
隻要搞清楚寄存器的本質和功能碼的聯係,其實理解功能碼就很簡單。
寄存器種類 | 讀寫狀態 | 位操作字操作 | 適用功能碼 |
---|---|---|---|
線圈寄存器 | 讀/寫 | 位 | 01H(讀); 05H(寫單個位); 0FH(寫多個位) |
離散輸入寄存器 | 隻讀 | 位 | 02H |
保持寄存器 | 讀/寫 | 字 | 03H(讀); 06H(寫單個字節); 0FH(寫多個字節) |
輸入寄存器 | 隻讀 | 字 | 04H |
線圈寄存器:可以類比為(wei) 開關(guan) 量,每個(ge) bit都對應一個(ge) 信號的開關(guan) 狀態。所以一個(ge) 字節可以同時控製8路的信號。比如控製外部8路io的高低。 線圈寄存器支持讀也支持寫(xie) ,比如控製或者讀取電磁閥的開關(guan) 誌狀態。對應的功能碼有:0x01 0x05 0x0f
離散輸入寄存器:離散輸入寄存器相當於(yu) 線圈寄存器的隻讀模式,每個(ge) bit表示一個(ge) 開關(guan) 量,而他的開關(guan) 量隻能讀取,不能夠寫(xie) 入。隻能通過外部設定改變輸入狀態,比如我可以讀取外部按鍵的按下還是鬆開,但是控製不了按鍵。對應的功能碼有:0x02
保持寄存器:寄存器的單位不再是bit而是兩(liang) 個(ge) byte,也就是可以存放具體(ti) 的數據量的,並且是可讀寫(xie) 的。比如我不到那可以讀取傳(chuan) 感器報警上限下限,也可以設置它的大小。對應的功能碼有:0x03 0x06 0x10
輸入寄存器:輸入寄存器相當於(yu) 保持寄存器的隻讀模式,也是隻支持讀而不能寫(xie) 。一個(ge) 寄存器也是占據兩(liang) 個(ge) 字節的空間。比如通過讀取輸入寄存器獲取現在的模擬量采樣值。對應的功能碼有 0x04
二.MODBUS部分功能碼MODBUS支持很多功能碼,但是在實際應用的時候常用的也就那麽(me) 幾個(ge) 。
上麵介紹了Modbus的四個(ge) 寄存器種類:線圈寄存器、離散輸入寄存器、保持寄存器、輸入寄存器,從(cong) 寄存器角度理解了對應功能碼。下麵列出常用功能碼,具體(ti) 如下:
功能碼 | 名稱 | 數據類型 | 作用 |
---|---|---|---|
0x01 | 讀線圈寄存器 | 位 | 取得一組邏輯線圈的當前狀態(ON/OFF ) |
0x02 | 讀離散輸入寄存器 | 位 | 取得一組開關輸入的當前狀態(ON/OFF ) |
0x03 | 讀保持寄存器 | 整型、浮點型、字符型 | 在一個或多個保持寄存器中取得當前的二進製值 |
0x04 | 讀輸入寄存器 | 整型、浮點型 | 在一個或多個輸入寄存器中取得當前的二進製值 |
0x05 | 寫單個線圈寄存器 | 位 | 強置一個邏輯線圈的通斷狀態 |
0x06 | 寫單個保持寄存器 | 整型、浮點型、字符型 | 把具體二進值裝入一個保持寄存器 |
0x0f | 寫多個線圈寄存器 | 位 | 強置一串連續邏輯線圈的通斷 |
0x10 | 寫多個保持寄存器 | 整型、浮點型、字符型 | 把具體的二進製值裝入一串連續的保持寄存器 |
1.功能碼:01H 讀線圈寄存器
1)功能:讀從(cong) 站線圈寄存器,位操作,可讀單個(ge) 或者多個(ge)
2)主機發送指令:
主機發送數據包括:從(cong) 站地址+功能碼+寄存器起始地址+寄存器數量+校驗碼
假設從(cong) 站地址為(wei) 0x01,線圈寄存器開始地址0x0021,結束地址0x002c,即寄存器地址範圍為(wei) :0x0021~0x0032,總共讀取12個(ge) 連續線圈的狀態值,則主機發送指令如下圖所示:
從站地址 | 功能碼 | 寄存器起始地址高8位 | 寄存器起始地址低8位 | 寄存器數量高8位 | 寄存器數低8位 | CRC校驗低8位 | CRC校驗高8位 |
---|---|---|---|---|---|---|---|
0x01 | 0x01 | 0x00 | 0x21 | 0x00 | 0x0c | 0xXX | 0xXX |
3)從(cong) 站響應返回:
從(cong) 站響應返回數據包括:從(cong) 站地址+功能碼+返回字節數+數據值+校驗碼
其中,返回數據值的每一位對應線圈狀態,線圈狀態為(wei) ON時,其值為(wei) 1;狀態為(wei) OFF時,其值為(wei) 0;
【數據以小端的形式進行存儲(chu) ,即最低有效位存放於(yu) 內(nei) 存最低位地址(位於(yu) 二進製的右側(ce) )。每8個(ge) 位組成一個(ge) 字節,當線圈的數量不是8的倍數時,剩餘(yu) 的位數添0補位。】
從站地址 | 功能碼 | 返回字節數 | data1 | data2 | CRC校驗低8位 | CRC校驗高8位 |
---|---|---|---|---|---|---|
0x01 | 0x01 | 0x02 | 0xCB | 0x0B | 0xXX | 0xXX |
本例中讀取12個(ge) 線圈,12/8商1餘(yu) 4,因此需要2個(ge) 字節存放應答數據,返回字節數為(wei) 2。
字節1存放線圈編號21~28的數值(小端字節序,線圈28的值存放在bit7,線圈21的值存放在bit0);
字節2存放線圈編號29~32的數值,剩餘(yu) 位數添0補位;
上表中data1表示0x0021-0x0028的線圈狀態,data1的最低位代表最低地址的線圈狀態;
data1:0xCB=1100 1011,則data1線圈狀態如下表所示:
線圈地址 | 功能碼 | 0x28 | 0x27 | 0x26 | 0x25 | 0x24 | 0x23 | 0x22 | 0x21 |
---|---|---|---|---|---|---|---|---|---|
數值 | 0x01 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 1 |
data2表示地址0x0030-0x0038的線圈狀態,不夠8位,字節高位填充為(wei) 0。
data2:0x0B=0000 1011,則data2線圈狀態如下表所示:
線圈地址 | 功能碼 | 0x30 | 0x2f | 0x2e | 0x2d | 0x2c | 0x2b | 0x2a | 0x29 |
---|---|---|---|---|---|---|---|---|---|
數值 | 0x01 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 |
2.功能碼:02H 讀離散輸入寄存器
1)功能:讀離散輸入寄存器,位操作,可讀單個(ge) 或多個(ge) ,類似功能碼0X01,此處省略;
3.功能碼:03H 讀保持寄存器
1)功能:讀從(cong) 站保持寄存器,字節操作,可讀單個(ge) 或者多個(ge) ;每個(ge) 保持寄存器占2個(ge) 字節(16位);
2)主機發送指令:
主機發送數據包括:從(cong) 站地址+功能碼+寄存器起始地址+寄存器數量+校驗碼
假設從(cong) 站地址為(wei) 0x03,保持寄存器開始地址為(wei) 0x003B,結束地址0x003D,即寄存器地址範圍為(wei) :0x003B~0x003D,總共讀取3個(ge) 保持寄存器的數據,則主機發送指令如下圖所示:
從站地址 | 功能碼 | 寄存器起始地址高8位 | 寄存器起始地址低8位 | 寄存器數量高8位 | 寄存器數量低8位 | CRC校驗低8位 | CRC校驗高8位 |
---|---|---|---|---|---|---|---|
0x03 | 0x03 | 0x00 | 0x3B | 0x00 | 0x03 | 0xXX | 0xXX |
3)從(cong) 站響應返回:
從(cong) 站響應返回數據包括:從(cong) 站地址+功能碼+返回字節數+數據值+校驗碼
從站地址 | 功能碼 | 返回字節數 | data1H | data1L | data2H | data2L | data3H | data3L | CRC校驗低8位 | CRC校驗高8位 |
---|---|---|---|---|---|---|---|---|---|---|
0x03 | 0x03 | 0x06 | 0x1B | 0x0B | 0x0A | 0x01 | 0xC2 | 0xDB | 0xXX | 0xXX |
本例中讀取3個(ge) 保持寄存器,每個(ge) 保持寄存器占2個(ge) 字節,因此需要6個(ge) 字節存放應答數據,返回字節數為(wei) 6。
0x003B~0x003D保持寄存器的數值如下圖所示:
寄存器地址 | 0x003D | 0x003C | 0x003A |
---|---|---|---|
數值 | 0xC2 DB | 0x0A 01 | 0x1B 0B |
4.功能碼:04H 讀輸入寄存器
1)功能:讀輸入寄存器,字節操作,可讀單個(ge) 或多個(ge) ,類似功能碼0X03,此處省略;
5.功能碼:05H 寫單個線圈寄存器
1)功能:對單個(ge) 線圈進行寫(xie) 操作,位操作,隻能寫(xie) 一個(ge) 。寫(xie) 入0xFF00表示將線圈置為(wei) ON,寫(xie) 入0x0000表示將線圈置為(wei) OFF,其它值無效;
2)主機發送指令:
主機發送數據包括:從(cong) 站地址+功能碼+寄存器起始地址+數據值+校驗碼
假設從(cong) 站地址為(wei) 0x03,線圈寄存器起始地址為(wei) 0x0032,要將其設置為(wei) ON,則主機發送指令如下表所示:
從站地址 | 功能碼 | 寄存器起始地址高8位 | 寄存器起始地址低8位 | dataH | dataL | CRC校驗低8位 | CRC校驗高8位 |
---|---|---|---|---|---|---|---|
0x03 | 0x05 | 0x00 | 0x32 | 0xff | 0x00 | 0xXX | 0xXX |
3)從(cong) 站響應返回:
從(cong) 站應答數據包括:從(cong) 站地址+功能碼+寄存器地址+寫(xie) 入值+校驗碼
如果數據成功寫(xie) 入,則應答數據與(yu) 請求數據一樣,如下表所示:
從站地址 | 功能碼 | 寄存器起始地址高8位 | 寄存器起始地址低8位 | dataH | dataL | CRC校驗低8位 | CRC校驗高8位 |
---|---|---|---|---|---|---|---|
0x03 | 0x05 | 0x00 | 0x32 | 0xff | 0x00 | 0xXX | 0xXX |
6.功能碼:06H 寫單個保持寄存器|
1)功能:對單個(ge) 保持寄存器進行寫(xie) 操作,字節操作,隻能寫(xie) 一個(ge) 。
2)主機發送指令:
主機發送數據包括:從(cong) 站地址+功能碼+寄存器起始地址+數據值+校驗碼
假設從(cong) 站地址為(wei) 0x01,線圈寄存器起始地址為(wei) 0x0048,寫(xie) 入數值為(wei) 0x1234,則主機發送指令如下表所示:
從站地址 | 功能碼 | 寄存器起始地址高8位 | 寄存器起始地址低8位 | dataH | dataL | CRC校驗低8位 | CRC校驗高8位 |
---|---|---|---|---|---|---|---|
0x01 | 0x06 | 0x00 | 0x48 | 0x12 | 0x34 | 0xXX | 0xXX |
3)從(cong) 站響應返回:
從(cong) 站應答數據包括:從(cong) 站地址+功能碼+寄存器地址+寫(xie) 入值+校驗碼
如果數據成功寫(xie) 入,則應答數據與(yu) 請求數據一樣。