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

Modbus網關如何實現Modbus RTU與Modbus TCP協議的數據采集?
Modbus RTU協議與Modbus TCP/IP協議的區別
Modbus RTU轉CC-link協議網關(Modbus RTU轉CC-link)

Profibus-PA轉Modbus-RTU協議網關(Profibus-PA轉Modbus-RTU)

CC-Link IEFB主站轉Modbus RTU協議網關(YC-CCLKIEM-RTU)

Modbus RTU轉CC-Link協議網關(CC-Link轉Modbus RTU)

EtherCAT轉Modbus RTU協議網關(YC-ECT-RTU)

說明白了,Modbus RTU通信協議解析-成都電路板單片機開發
ProfiNet轉RS485/Modbus Rtu協議網關

評論