Modbus協(xié)議是OSI模型的第七層的應用層通訊協(xié)議,定義了不同類(lèi)型設備間交換信息方式,以及信息的格式。
Modbus的工作方式是請求/應答,每次通訊都是主站先發(fā)送指令,可以是廣播,或是向特定從站的單播,從站響應指令,并按要求應答,或者報告異常。當主站不發(fā)送請求時(shí),從站不會(huì )自己發(fā)出數據,從站和從站之間不能直接通訊。
Modbus協(xié)議的報文(或幀)的基本格式是:
表頭 + 功能碼 + 數據區 + 校驗碼
功能碼和數據區在不同類(lèi)型的網(wǎng)絡(luò )都是固定不變的,表頭和校驗碼則因網(wǎng)絡(luò )底層的實(shí)現方式不同而有所區別。表頭包含了從站的地址,功能碼告訴從站要執行何種功能,數據區是具體的信息。
先以串行通訊的Modbus為例(注意Modbus TCP的報文表頭和校驗碼是不一樣的),主站發(fā)送了:
09 03 00 04 00 03 XX
主站告訴從站09,我要讀取的地址偏移為4、5、6的Holding Register的數值。其中"03"是讀Holding Register的功能碼,"00 04 00 01"是數據區,"00 04"是寄存器的地址,"00 03"說(shuō)明要連續讀三個(gè)寄存器的值。"XX"代表最后的校驗位,校驗方法是LRC或CRC。
從站收到信息后,就從對應的寄存器找到數值,回復:
09 03 06 02 2B 00 01 00 64 XX
從站回答,該地址偏移為4的寄存器值為02 2B,地址偏移為5的寄存器值為00 01,地址偏移為6的寄存器值為00 64。其中"09 03"是復制了主站發(fā)來(lái)的地址和功能碼,"06"代表接下來(lái)的數據共有6個(gè)字節。
如果從站收到了一個(gè)錯誤的請求,例如發(fā)現要讀的寄存器地址是錯誤的,則回復:
09 83 02 XX
其中"83"是把功能碼"03"的最高位置1,告訴主站發(fā)生了異常,"02"是異常碼,說(shuō)明發(fā)生了無(wú)效地址的異常。
Modbus的四種數據類(lèi)型
Coil:大小只有1位,ON或OFF,可讀可寫(xiě),既可以是一個(gè)輸出量輸出點(diǎn),也可以是數字量輸入點(diǎn),有效的地址范圍是1-9999。
Input Status:大小只有1位,ON或OFF,只讀,即數字量輸出點(diǎn),有效地址范圍是10001-19999。
Input Register:16位的寄存器,只讀,可以用作模擬量或16位打包輸入點(diǎn),有效地址范圍是30001-39999。
Holding Register:16位的寄存器,可讀可寫(xiě),既可以是一個(gè)模擬量或16位打包輸入點(diǎn),也可以是模擬量或16位打包輸出點(diǎn),有效地址范圍是40001-49999。
在PLC或DCS上用點(diǎn)名標記不同的變量,在Modbus則以數據地址來(lái)標記每個(gè)點(diǎn)。以上所說(shuō)的地址都是參考地址,而不是實(shí)際的物理地址。上述的地址是在設備中的地址,按照PLC的習慣從1開(kāi)始遞增,而Modbus報文中是從0開(kāi)始遞增。例如地址偏移為4、5、6的Holding Register,其實(shí)是指參考地址是40005、40006、40007的寄存器。
Modbus TCP、Modbus RTU和Modbus ASCII的區別
對于不同類(lèi)型的網(wǎng)絡(luò ),Modbus的第7層實(shí)現是一樣的,區別在于下層的實(shí)現方式,常見(jiàn)的有TCP/IP和串行通訊兩種。
Modbus TCP基于以太網(wǎng)和TCP/IP協(xié)議,Modbus RTU和Modbus ASCII則是使用異步串行傳輸(通常是RS-232/422/485)。
對于Modbus TCP而言,主站通常稱(chēng)為Client,從站稱(chēng)為Server;而對于Modbus RTU和Modbus ASCII來(lái)說(shuō),主站是Master,從站是Slave。
如圖2所示,串行傳輸的物理層是RS-485或RS-232,數據鏈路層是Modbus的串行傳輸協(xié)議;Modbus TCP的1、2、3、4層實(shí)現和日常所見(jiàn)的以太網(wǎng)、因特網(wǎng)一樣。Modbus默認采用的TCP端口號是502。
圖3說(shuō)明了Modbus TCP的改動(dòng):
1.取消了校驗位。數據鏈路層上就進(jìn)行了CRC-32的校驗,TCP/IP是面向連接的可靠性的協(xié)議,因此沒(méi)必要再加上校驗位。
2.Slave地址換成了Unit Identifier。當網(wǎng)絡(luò )里的設備全是使用TCP/IP,這個(gè)地址是沒(méi)有意義的,因為IP就能進(jìn)行路由尋址。如果網(wǎng)絡(luò )里還有串行通訊的設備,則需要網(wǎng)關(guān)來(lái)實(shí)現Modbus TCP到Modbus RTU或ASCII之間的協(xié)議轉換,這時(shí)用Unit Identifier來(lái)標識網(wǎng)關(guān)后面的每個(gè)串行通訊設備。
3.Length是指后面的字節總數。實(shí)際上數據區的長(cháng)度是能確定的,有的功能碼就可以確定數據區的長(cháng)度,有的功能碼雖不能確定數據區長(cháng)度,但是數據區有字節計數,參見(jiàn)上文舉的從站應答的例子。表頭增加的Length是為了應對有些情況下TCP/IP協(xié)議會(huì )將應用層的數據拆包傳輸。
4.Transaction Identifier和Protocol Identifier由Client生成,Server的響應將復制這些參數。
RTU和ASCII的區別
RTU模式下,一個(gè)字節的數據,傳輸的就是一個(gè)字節。ASCII模式下,同樣一個(gè)字節數據用了兩個(gè)字節來(lái)傳輸。
例如,要傳輸數字0x5B,RTU傳輸的是0101 1011(二進(jìn)制),而ASCII傳輸的是00110101和01000010??梢?jiàn),ASCII傳輸的速率是RTU的一半。
ASCII模式采用LRC校驗,RTU模式采用16位CRC校驗。
來(lái)源:網(wǎng)絡(luò )整理