一、協(xié)議的基本特點(diǎn)
Modbus是施耐德電氣于1979年為使用PLC通信而發(fā)表的一種串行通信協(xié)議?,F(xiàn)在它已經(jīng)成為工業(yè)領(lǐng)域通信協(xié)議的業(yè)界標(biāo)準(zhǔn),并且是工業(yè)電子設(shè)備之間常用的連接方式。Modbus被廣泛使用的原因主要有三個:
1、公開發(fā)表并且無版權(quán)要求。(免費(fèi))
2、易于部署和維護(hù)。(簡單)
3、對供應(yīng)商來說,修改移動本地的比特或字節(jié)沒有很多限制。(修改簡單)
Modbus通信協(xié)議作用在OSI模型的物理層(1層)、數(shù)據(jù)鏈路層(2層)及應(yīng)用層(7層)。這里的OSI被稱為開放系統(tǒng)互聯(lián)參考模型,它定義了網(wǎng)絡(luò)互連的七層框架,每層框架都有其各自的通信協(xié)議。
OSI
而通信協(xié)議其實(shí)就是一種約定,一種編碼和解碼的方式。例如用莫爾斯電碼打出三短三長三短(編碼),知道協(xié)議的人,就會明白這是在表示求救信號(解碼),反之,則很難理解它的含義。Modbus也是如此,在之后的內(nèi)容中我們將更加清楚的看到這一點(diǎn)。
二、協(xié)議的報文說明
Modbus協(xié)議有三類,分別是:Modbus-RTU、Modbus-ASCII、Modbus-TCP。一般來說,一個設(shè)備只有其中的一種協(xié)議,而且Modbus規(guī)定,Modbus-RTU是設(shè)備必須支持的協(xié)議,也是默認(rèn)選項(xiàng)。所以大多數(shù)設(shè)備都采用了Modbus-RTU協(xié)議通信。那么本期視頻我們主要介紹的就是Modbus-RTU協(xié)議的有關(guān)內(nèi)容。
先來看一個簡單的Modbus-RTU報文。首先聲明一點(diǎn),我們將電腦上的串口助手當(dāng)作主站, M2101或M1002模塊作為從站。根據(jù)命令的不同,使用的從站設(shè)備也有所不同。
報文使用設(shè)備
當(dāng)主站或者說客戶機(jī)發(fā)送了請求報文:01 02 00 00 00 04 79 C9,從站(M1001)或者說服務(wù)器會返回響應(yīng)報文:01 02 01 0F E1 8C。報文中的每一小段都是由一個字節(jié)也就是兩個十六進(jìn)制碼構(gòu)成。例如0F,它的二進(jìn)制是0000 1111。
那我們要怎樣理解報文數(shù)據(jù)呢?以主站發(fā)送的報文為例,它可以分為三部分,分別是:地址域——01;協(xié)議數(shù)據(jù)單元(PDU)——02 00 00 00 04,它包含功能碼和數(shù)據(jù);差錯校驗(yàn)——79 C9。而且響應(yīng)報文與請求報文比較相似,我們將在之后的內(nèi)容中一起說明。
報文分區(qū)
首先看地址域部分。它是由一個8位字節(jié)構(gòu)成,那么理論上可以有256個不同的地址。這是否意味我們可以為主站連接256個從站設(shè)備呢?答案是否定的。因?yàn)樵谶@256個地址空間中又有以下這些區(qū)別。Modbus規(guī)定地址0保留為廣播地址,1~247為子節(jié)點(diǎn)單獨(dú)地址,248~255為保留地址。所以從機(jī)的地址范圍在1~247之間,而其他地址可以由用戶自由擴(kuò)展。這樣就可以在滿足用戶特定需求的同時盡量保持協(xié)議的兼容性。當(dāng)然,保留區(qū)也具有同樣的功能,如設(shè)置特定地址段的廣播指令等等。需要注意的是地址域只和從站有關(guān),主站是沒有地址標(biāo)識的,而且每個從站的地址都是唯一的,以便于與其它從站區(qū)別。
報文的地址域
根據(jù)地址域的不同,Modbus分為廣播與單播兩種請求模式。
在廣播模式下,所有從站必須執(zhí)行主站命令,而無需應(yīng)答返回。
廣播模式
在單播模式中,一個Modbus事務(wù)處理包含兩個報文:一個來自主節(jié)點(diǎn)(主站)的請求,一個來自子節(jié)點(diǎn)(從站)的應(yīng)答。
單播模式
它的具體過程是:主節(jié)點(diǎn)發(fā)送請求后進(jìn)入等待應(yīng)答狀態(tài),只有特定子節(jié)點(diǎn)應(yīng)答完成后,主節(jié)點(diǎn)才可以進(jìn)行下一個事務(wù)處理。而且同一時刻,主節(jié)點(diǎn)只會發(fā)起一個Modbus事務(wù)處理。當(dāng)然主節(jié)點(diǎn)在等待響應(yīng)時會同步啟動響應(yīng)超時機(jī)制,避免主節(jié)點(diǎn)永遠(yuǎn)處于等待應(yīng)答狀態(tài)。不管是何種模式,子節(jié)點(diǎn)都不會主動發(fā)送數(shù)據(jù),而且子節(jié)點(diǎn)間也不會互相通信。在報文中可以看到,無論是主站的請求還是從站的應(yīng)答,報文的起始位都是地址域。
地址域在報文首位
接下來說明報文的協(xié)議報文單元(PDU),它由功能碼和數(shù)據(jù)構(gòu)成。功能碼由一個字節(jié)表示,它可以分為三類:公共功能碼、用戶定義功能碼和保留功能碼。我們結(jié)合實(shí)例,說明公共功能碼中常用的幾個功能碼以及數(shù)據(jù)域的內(nèi)容。需要注意的是,下面的說明內(nèi)容只包含報文中的PDU部分,而省略了它的地址域和校驗(yàn)域。在介紹具體的協(xié)議功能碼前,先看看Modbus協(xié)議控制的寄存器的種類。如下圖:
寄存器種類
我們可以將寄存器分為四類,每種寄存器都有其特定的地址區(qū)域。
Modbus-RTU協(xié)議的功能有很多,這里我們將結(jié)合實(shí)例為大家說明幾個常用的功能碼。
功能碼
主站輸入報文:01 00 02 00 06,
01功能碼示例(主站)
報文的首字節(jié)是功能碼域。01功能碼是讀線圈命令,可以讀取線圈1至2000的連續(xù)狀態(tài)。線圈其實(shí)就是DO(數(shù)字輸出),它的對象類型是單個比特,1表示ON,0表示OFF。從站的線圈有很多,在執(zhí)行01命令時,從站要從那個線圈開始讀?需要讀幾個?這就要功能碼后的數(shù)據(jù)域來定義了。以輸入的00 02 00 06為例,前兩個字節(jié)表示起始地址,其中00是線圈起始地址的高位,02是線圈起始地址的低位。后兩個字節(jié)表示要讀取的線圈數(shù)量,00表示讀取數(shù)量的高位,06表示讀取數(shù)量的低位。因?yàn)閳笪亩际鞘M(jìn)制寫的,所以00 02轉(zhuǎn)換為十進(jìn)制是2,00 06轉(zhuǎn)換為十進(jìn)制是6。那么數(shù)據(jù)域就表示從第3個線圈開始讀,一直讀到第8個線圈為止。
那么從站(M1002)的響應(yīng)報文01 01 00的各個字節(jié)都有什么含義呢?
01功能碼示例
開始的第一個字節(jié)還是功能碼,表示從站執(zhí)行的是主站請求的01命令。緊接著的一個字節(jié)01,表示從站返回的字節(jié)數(shù),也就是返回1個字節(jié),其中的00表示8-3線圈的狀態(tài),它的二進(jìn)制是0000 0000從右至左依次表示3-8線圈的狀態(tài),最高兩位用0填充,這是因?yàn)閰f(xié)議必須要輸出一個完整的字節(jié)才行。
讀取的線圈狀態(tài)
讀離散量的功能碼是02,它的報文與讀線圈功能碼的報文相差無幾,就不介紹了。
寫線圈的功能碼又分為寫單個線圈05和寫多個線圈0F,我們以0F功能碼為例,說明報文的含義。0F功能碼可以強(qiáng)制線圈序列中的每個線圈為ON或OFF。發(fā)送的請求報文是:0F 00 02 00 06 01 2A。
0F功能碼示例(主站)
0F自然是功能碼域,之后的四個字節(jié)分別是起始地址位00 02,輸出數(shù)量00 06。緊接著的一個01字節(jié)表示要為線圈寫入一個字節(jié)的內(nèi)容,內(nèi)容是2A,用二進(jìn)制表示是0010 1010,對應(yīng)的線圈順序是8-3,數(shù)據(jù)字節(jié)中未使用的比特還是用零填充。
為線圈寫入的狀態(tài)
從站(M1002)的響應(yīng)報文是0F 00 02 00 06。
0F功能碼示例(從站)
0F是說明從站執(zhí)行的功能碼;之后的四個字節(jié)中,前兩個字節(jié)是起始地址位,后兩個字節(jié)是輸出數(shù)量。我們發(fā)現(xiàn),在執(zhí)行0F命令時,響應(yīng)報文和請求報文的前五個字節(jié)是完全相同的。
接著介紹04功能碼,它可以讀取1至125的連續(xù)寄存器。每個連續(xù)寄存器以兩個字節(jié)表示。發(fā)送的請求報文是:04 00 67 00 04。
04功能碼示例(主站)
04是它的功能碼,寄存器的起始地址是00 67,00 04表示要讀4個寄存器的值。所以請求報文是要讀取寄存器104-107也就是M2101模塊上的IN 3到IN 6這四個寄存器中的值。
模塊的用戶手冊(一)
這些數(shù)值是怎樣計(jì)算的呢?首先打開M2101模塊的用戶手冊。
模塊的用戶手冊(二)
在熱電偶輸入寄存器列表部分會看到各個寄存器的地址,這里的3x中的3通俗來講就是區(qū)號,用來區(qū)分各種寄存器,不參與實(shí)際的計(jì)算過程。這里的x表示十進(jìn)制,也就是說這里的數(shù)字是以十進(jìn)制的方式書寫的。如IN 3的地址是30104,其實(shí)它的地址就是十進(jìn)制的104,轉(zhuǎn)換為十六進(jìn)制就是68。但是,在地址書寫中十進(jìn)制的寄存器地址是從1開始計(jì)數(shù),而十六進(jìn)制的寄存器地址卻是從00開始計(jì)數(shù),所以當(dāng)我們要讀取IN 3的寄存器的值時,要將十進(jìn)制的地址減一,這樣就變成了輸入到報文中的67。
從站(M2101)返回的響應(yīng)報文則是:04 08 F5 55 F5 55 18 63 01 1A。
04功能碼示例(從站)
04功能字節(jié)后的08字節(jié)表示讀取了8個字節(jié)的數(shù)據(jù),其中F5是寄存器104的高八位,55是它的低八位,而F555正是模塊在無溫度數(shù)據(jù)下返回的默認(rèn)值;01是寄存器107的高八位,1A是它的低八位,011A是模塊采集的溫度數(shù)據(jù)。011A是十六進(jìn)制數(shù)據(jù),轉(zhuǎn)換為十進(jìn)制就是282,因?yàn)槟K的返回值是以0.1℃為單位的16位整形數(shù)據(jù),所以表示的實(shí)際溫度就是28.2℃。
最后介紹10功能碼,它可以寫連續(xù)寄存器塊。發(fā)送的請求報文為:10 00 67 00 02 04 00 00 00 07。
10功能碼示例(主站)
在功能碼10之后是起始地址00 67,要寫的寄存器數(shù)量00 02,需要寫入的字節(jié)數(shù)04,它們是00 00 00 07。查看模塊的用戶手冊,
模塊的用戶手冊(三)
我們明白了請求報文要將IN 3通道的熱電偶類型改變?yōu)锽型,將IN 4通道改變?yōu)镹型。
從站(M2101)的響應(yīng)報文則是10 00 67 00 02,與請求報文的前五個字節(jié)并無差別,表明從站執(zhí)行了請求命令。
10功能碼示例(從站)
我們可以在軟件上查看一下。關(guān)閉串口,打開Manager軟件,找到設(shè)備后點(diǎn)擊Function Config就可以看到通道的熱電偶類型發(fā)生了改變。
模塊測試熱電偶類型發(fā)生改變
上述的Modbus-RTU協(xié)議報文我們可以這樣理解:當(dāng)主站要發(fā)送請求報文時,首先要確定報文是發(fā)送給誰的,也就是地址域;然后說明自己要干什么,也就是功能碼;其次要確定這件事從哪里開始干,干到那里停止,也就是起始地址和輸出數(shù)量;倘若有要求的話,主站還要在報文中寫入自己的具體要求,也就是字節(jié)數(shù)和字節(jié)內(nèi)容。從站的響應(yīng)報文也可如此理解。
對于Modbus協(xié)議的其它功能碼我們便不再一一介紹。它們的詳細(xì)內(nèi)容,大家可以參考Modbus協(xié)議說明。
三、協(xié)議的錯誤說明
到現(xiàn)在為止,我們已經(jīng)說明了Modbus-RTU協(xié)議的大部分內(nèi)容,但還有兩個問題困擾著我們:如果出現(xiàn)錯誤怎么辦?畢竟意外總會發(fā)生。還有一個則是,報文最后兩字節(jié)的CRC校驗(yàn)應(yīng)該怎樣計(jì)算?下面就來解釋這兩個問題。
我們以一個實(shí)例來說明錯誤的響應(yīng)報文有什么樣的特點(diǎn)。當(dāng)然,這里給出的還是省略地址域和校驗(yàn)域的報文。當(dāng)主站發(fā)送請求報文02 00 00 00 05后,
錯誤的請求報文
從站(M1002)產(chǎn)生的響應(yīng)報文是82 03。
應(yīng)答報文
通過前面的介紹,我們可以知道主站的請求是要讀取1至5的離散量輸入(DI)狀態(tài)。但返回的響應(yīng)報文顯然是錯誤的,為什么會這樣?檢查M-1002發(fā)現(xiàn),模塊上并沒有五個離散量輸入。
M1002模塊
修改請求報文為02 00 00 00 04,
正確的請求報文
產(chǎn)生的響應(yīng)報文為02 01 0F,這是正確的回執(zhí)。
應(yīng)答報文
那異常報文82 03具有什么樣的特點(diǎn)呢?
我們將響應(yīng)報文分為功能碼域和數(shù)據(jù)碼域。因?yàn)檎m憫?yīng)的所有功能碼的最高有效位都為0,即功能碼的值都低于十六進(jìn)制的80(1000 0000)。所以異常響應(yīng)報文的功能碼出現(xiàn)的是正常功能碼加80(十六進(jìn)制)的值,也就是異常報文中顯示的82。而數(shù)據(jù)域中的異常碼03,定義了產(chǎn)生異常的從站狀態(tài)。協(xié)議中定義的異常碼如下圖所示。
異常碼定義
那么對實(shí)例中異常報文的解釋就是:從站在執(zhí)行02功能碼時發(fā)生錯誤(82),出現(xiàn)錯誤的原因是,在從站想要查詢的值中包含不可允許的值(03)。這樣我們就可以通過異常響應(yīng)報文,更輕松地找出錯誤發(fā)生的原因。
四、CRC校驗(yàn)說明
CRC校驗(yàn)也就是循環(huán)冗余校驗(yàn),它由兩個字節(jié)組成,并且會附加在報文后面發(fā)送出去,它的具體值由發(fā)送設(shè)備計(jì)算。而接收設(shè)備在接收報文時會重新計(jì)算CRC的值,并將結(jié)果和實(shí)際收到的CRC值相比較,如果兩個值不相等,則為錯誤。
CRC 校驗(yàn)流程
CRC的生成過程如下:
將一個16位寄存器裝入十六進(jìn)制FFFF(全1),將之稱作CRC寄存器。
將報文的第一個8位字節(jié)與16位CRC寄存器的低字節(jié)異或,結(jié)果置于CRC寄存器。
將CRC寄存器右移一位(向LSB方向),MSB充零,提取并檢測LSB。
如果LSB為0,重復(fù)步驟3;如果LSB為1,對CRC寄存器異或多項(xiàng)式0xA001(1010 0000 0000 0001)。
重復(fù)步驟3和4,知道完成8次位移。當(dāng)做完此操作后,將完成對8位字節(jié)的完整操作。
對報文中的下一個字節(jié)重復(fù)步驟2到5,繼續(xù)此操作直到報文處理完畢。
CRC寄存器中的最終內(nèi)容為CRC值。
當(dāng)放置CRC值與報文時,高低字節(jié)必須交換。
現(xiàn)在我們一般使用程序自動生成CRC碼。
程序自動生成CRC碼
上述程序?qū)⑺锌赡艿腃RC值都預(yù)裝在兩個數(shù)組中,當(dāng)計(jì)算報文內(nèi)容時簡單索引即可。函數(shù)的兩個參數(shù):unsigned char*puchMsg表示指向含有用于生成CRC的二進(jìn)制數(shù)據(jù)報文緩沖區(qū)的指針;unsigned short usDataLen表示報文緩沖區(qū)的字節(jié)數(shù)。
五、報文的格式
對于Modbus-RTU報文我們最后還要說明的一點(diǎn)是:在RTU傳輸模式下每個字節(jié)都有11位,當(dāng)然,我們只需要輸入編碼系統(tǒng)中的8位字節(jié)就可以了。11位字節(jié)的格式是這樣的:
有校驗(yàn)位格式
1個起始位,8個數(shù)據(jù)位,首先發(fā)送最低有效位,1個奇偶校驗(yàn)位,一個停止位。除了8個數(shù)據(jù)位需要我們自己輸入外,其它位都是由協(xié)議自動添加。同時Modbus協(xié)議也支持無校驗(yàn),不過此時它的停止位就變成兩位了。
無校驗(yàn)位格式
要注意的是:不管Modbus-RTU協(xié)議有無奇偶校驗(yàn),CRC校驗(yàn)都是必須存在的。
文章的視頻內(nèi)容大家可以點(diǎn)擊如下連接跳轉(zhuǎn)觀看,Modbus-RTU協(xié)議講解。
文中出現(xiàn)的軟件和模塊可以到Smacq官網(wǎng)查看其詳細(xì)內(nèi)容。
如果您有什么問題,可以在評論區(qū)留言告訴我們或搜索公眾號:Smacq思邁科華。
審核編輯 黃宇
-
MODBUS
+關(guān)注
關(guān)注
28文章
2289瀏覽量
81513
發(fā)布評論請先 登錄
DLT698轉(zhuǎn)Modbus RTU-TCP網(wǎng)關(guān)

Modbus RTU轉(zhuǎn)Profinet總線協(xié)議網(wǎng)關(guān)

從協(xié)議沖突到生產(chǎn)力爆發(fā):EtherCAT轉(zhuǎn)MODBUS RTU網(wǎng)關(guān)實(shí)戰(zhàn)全解

什么是Modbus RTU協(xié)議

當(dāng)ASM焊線機(jī)遇上協(xié)議翻譯官:CC\\-Link IE轉(zhuǎn)Modbus RTU的節(jié)能數(shù)據(jù)之旅
當(dāng)控制器遇上“協(xié)議外交官”:CC\\-Link IE轉(zhuǎn)Modbus RTU的能源數(shù)據(jù)握手
一觸即達(dá):CCLink IE遇見Modbus RTU,解鎖智能電表“數(shù)據(jù)超車道”
DeviceNet轉(zhuǎn)Modbus RTU協(xié)議轉(zhuǎn)換網(wǎng)關(guān)在石油開采行業(yè)的應(yīng)用
基于 DeviceNet 轉(zhuǎn) MODBUS RTU 協(xié)議的施耐德 PLC 與 ABB 電機(jī)驅(qū)動器倉儲堆垛機(jī)的定位控制優(yōu)化方案?
Modbus TCP 到 RTU:輕松轉(zhuǎn)換指南!

評論