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

Modbus網(wǎng)關(guān)如何實(shí)現(xiàn)Modbus RTU與Modbus TCP協(xié)議的數(shù)據(jù)采集?
Modbus RTU協(xié)議與Modbus TCP/IP協(xié)議的區(qū)別
Profibus PA轉(zhuǎn)Modbus RTU協(xié)議網(wǎng)關(guān)

Modbus RTU轉(zhuǎn)CC-link協(xié)議網(wǎng)關(guān)(Modbus RTU轉(zhuǎn)CC-link)

Profibus-PA轉(zhuǎn)Modbus-RTU協(xié)議網(wǎng)關(guān)(Profibus-PA轉(zhuǎn)Modbus-RTU)

CC-Link IEFB主站轉(zhuǎn)Modbus RTU協(xié)議網(wǎng)關(guān)(YC-CCLKIEM-RTU)

Modbus RTU轉(zhuǎn)CC-Link協(xié)議網(wǎng)關(guān)(CC-Link轉(zhuǎn)Modbus RTU)

EtherCAT轉(zhuǎn)Modbus RTU協(xié)議網(wǎng)關(guān)(YC-ECT-RTU)

Modbus網(wǎng)關(guān)實(shí)現(xiàn)Modbus RTU和Modbus TCP協(xié)議相互轉(zhuǎn)換

評(píng)論