找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2795|回復(fù): 5
打印 上一主題 下一主題
收起左側(cè)

說(shuō)明白了,Modbus RTU通信協(xié)議解析

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:63113 發(fā)表于 2024-6-30 22:36 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
Modbus協(xié)議在工業(yè)控制、電氣、電子領(lǐng)域是個(gè)很常見(jiàn)的一種通信協(xié)議,很多遇見(jiàn)的傳感器、控制器、變頻器、驅(qū)動(dòng)器之類(lèi)的基本都支持該協(xié)議,常見(jiàn)到什么程度呢,就是你看到的一個(gè)設(shè)備如果支持串口通信的,那么基本很多都內(nèi)置了Modbus協(xié)議。
作為一個(gè)開(kāi)發(fā)者,在做單片機(jī)、PLC、電路板、控制器/箱、儀器儀表、機(jī)電設(shè)備或系統(tǒng)、自動(dòng)化、工控、傳感、數(shù)據(jù)采集、自控系統(tǒng)、控制系統(tǒng)、物聯(lián)網(wǎng)、電子產(chǎn)品、軟件、APP項(xiàng)目過(guò)程中也經(jīng)常會(huì)使用到Modbus協(xié)議,所以不把此協(xié)議搞懂真就沒(méi)法混。
本文介紹Modbus 協(xié)議中的Modbus RTU協(xié)議的相關(guān)知識(shí),包括理論和案例,該協(xié)議常用于串口通信。

一、 Modbus RTU是什么?
Modbus是一種串行通信協(xié)議,是Modicon公司(現(xiàn)在的施耐德電氣 Schneider Electric)于1979年為使用可編程邏輯控制器(PLC)通信而發(fā)表。Modbus已經(jīng)成為工業(yè)領(lǐng)域通信協(xié)議的業(yè)界標(biāo)準(zhǔn)(De facto),并且現(xiàn)在是工業(yè)電子設(shè)備之間常用的連接方式。
此協(xié)議定義了一個(gè)控制器能認(rèn)識(shí)使用的消息結(jié)構(gòu),而不管它們是經(jīng)過(guò)何種網(wǎng)絡(luò)進(jìn)行通信的。它描述了一控制器請(qǐng)求訪問(wèn)其它設(shè)備的過(guò)程,如果回應(yīng)來(lái)自其它設(shè)備的請(qǐng)求,以及怎樣偵測(cè)錯(cuò)誤并記錄。它制定了消息域格局和內(nèi)容的公共格式。
其實(shí),Modbus協(xié)議包含Modbus TCP,Modbus ASCII,Modbus RTU。Modbus TCP和Modbus ASCII本文不作深入描述,本文主要講Modbus RTU。
概括地說(shuō),Modbus RTU是一種串行通信協(xié)議, 它關(guān)注于通信數(shù)據(jù)層面,主要是規(guī)定通信雙方或者多方的每個(gè)數(shù)據(jù)幀發(fā)送和接收用什么樣的數(shù)據(jù)格式。
一般來(lái)說(shuō),串行通信中傳輸?shù)臄?shù)據(jù)是一位一位(二進(jìn)制位)地按照一定速率進(jìn)行傳輸?shù)摹?位數(shù)據(jù)組成一個(gè)字節(jié),Modbus RTU是以字節(jié)為最小基本單元定義數(shù)據(jù)格式的。若干個(gè)字節(jié)的數(shù)據(jù)組成數(shù)據(jù)幀,Modbus RTU協(xié)議就關(guān)注于這個(gè)數(shù)據(jù)幀里每個(gè)字節(jié)的數(shù)據(jù)該是怎樣的。

二、 Modbus RTU協(xié)議與RS485、RS232、TTL等串口協(xié)議的關(guān)系是怎樣

它們是不同的概念,側(cè)重于不同方面。
先來(lái)看看RS485、RS232、TTL:RS485、RS232、TTL串口是串口通信中關(guān)于電氣協(xié)議的通信協(xié)議,例如,包括用什么樣的電壓表示1、用什么樣的電壓表示0,起始位、停止位、波特率等是怎樣的。具體如下:
TTL電平:全雙工(邏輯1: 2.4V--5V 邏輯0: 0V--0.5V);
RS-232電平:全雙工(邏輯1:-15V~-3V 邏輯0:+3V~+15V);
RS-485:半雙工(邏輯1:+2V~+6V 邏輯0: -6V~-2V)這里的電平指AB 兩線間的電壓差。485由于是差分信號(hào),具有數(shù)據(jù)傳輸遠(yuǎn)、抗干擾能力強(qiáng)、支持多機(jī)通信(由于是半雙工)的優(yōu)點(diǎn)。


再看Modbus RTU:Modbus RTU是軟件層面的通信協(xié)議,它定義通信中的數(shù)據(jù)幀該是怎么樣的格式,它關(guān)注于數(shù)據(jù),也就是一個(gè)數(shù)據(jù)幀中每個(gè)字節(jié)該是怎樣的數(shù)據(jù)。
概括地說(shuō),Modbus RTU和串口RS485、RS232、TTL是不同的概念,但是也有聯(lián)系。Modbus RTU是數(shù)據(jù)層面的,規(guī)定通信的數(shù)據(jù)格式,RS485、RS232、TTL是物理層面的,它們規(guī)定了傳輸?shù)碾姎鈪f(xié)議,Modbus RTU協(xié)議需要運(yùn)行在一定的通信載體(即電氣協(xié)議,如RS485、RS232、TTL等)上。Modbus RTU在RS485、RS232、TTL串口上都能運(yùn)行,常見(jiàn)的是在RS485上走M(jìn)odbus RTU協(xié)議。

三、 Modbus RTU協(xié)議具體是怎樣

Modbus RTU是主從通信模式,需要一個(gè)主機(jī),一個(gè)或若干個(gè)從機(jī)。
Modbus RTU的數(shù)據(jù)幀一般包含:地址碼、功能碼、若干個(gè)數(shù)據(jù)碼、校驗(yàn)碼。幀與幀之間的時(shí)間間隔為3.5個(gè)字符,即假如兩個(gè)數(shù)據(jù)傳輸位之間的時(shí)間間隔大于3.5個(gè)字符的時(shí)間,就會(huì)被認(rèn)為新的一幀開(kāi)始。一個(gè)Modbus RTU數(shù)據(jù)幀的組成如下:


3.1 Modbus RTU的地址碼
地址碼,用于定義和識(shí)別設(shè)備的地址,地址碼存儲(chǔ)空間為1個(gè)字節(jié),所以其范圍為0-255,其中0表示廣播.
3.2 Modbus RTU的功能碼和寄存器分區(qū)
表 2 Modbus RTU功能碼
功能碼        名稱(chēng)        寄存器地址        位/字操作        操作數(shù)量
01        讀線圈狀態(tài)        00001~09999        位操作        單個(gè)或多個(gè)
02        讀離散輸入狀態(tài)        10001~19999        位操作        單個(gè)或多個(gè)
03        讀保持寄存器        40001~49999        字操作        單個(gè)或多個(gè)
04        讀輸入寄存器        30001~39999        字操作        單個(gè)或多個(gè)
05        寫(xiě)單個(gè)線圈        00001~09999        位操作        單個(gè)
06        寫(xiě)單個(gè)保持寄存器        40001~49999        字操作        單個(gè)
15        寫(xiě)多個(gè)線圈        00001~09999        位操作        多個(gè)
16        寫(xiě)多個(gè)保持寄存器        40001~49999        字操作        多個(gè)
常見(jiàn)的功能碼有01、02、03、04、05、06、15、16等,分別表示著讀線圈狀態(tài)、讀離散輸入狀態(tài)、讀保持寄存器、讀輸入寄存器、寫(xiě)單個(gè)線圈、寫(xiě)單個(gè)保持寄存器、寫(xiě)多個(gè)線圈、寫(xiě)多個(gè)保持寄存器的功能。
寄存器分區(qū):
線圈,可以看作是一個(gè)可讀可寫(xiě)的位變量,Modbus RTU支持對(duì)其的讀寫(xiě)操作。允許多位操作。
離散輸入寄存器,可以看作是一個(gè)只讀的位變量,Modbus RTU支持對(duì)其的讀操作。
保持寄存器,可以看作是一個(gè)可讀可寫(xiě)的字節(jié)變量,Modbus RTU支持對(duì)其的讀寫(xiě)操作。允許多字節(jié)操作。一個(gè)保持寄存器為2個(gè)字節(jié)。
輸入寄存器,可以看作是一個(gè)只讀的字節(jié)變量,Modbus RTU支持對(duì)其的讀操作。一個(gè)輸入寄存器為2個(gè)字節(jié)。
寄存器地址:Modbus RTU的寄存器地址有00001~09999(0區(qū),表示線圈寄存器)、10001~19999(1區(qū),表示離散輸入寄存器)、30001~39999(3區(qū),表示輸入寄存器)、40001~49999(4區(qū),表示保持寄存器),其中3區(qū)和4區(qū),每個(gè)寄存器由2個(gè)字節(jié)組成。
注意:在Modbus二進(jìn)制數(shù)據(jù)指令里,表示寄存器地址的指令數(shù)據(jù)是從0開(kāi)始的,Modbus RTU的寄存器地址是從1開(kāi)始,注意對(duì)應(yīng)關(guān)系。
用功能碼是可以識(shí)別到Modbus寄存器分區(qū)的,所以在Modbus二進(jìn)制數(shù)據(jù)指令里,是不填寫(xiě)分區(qū)代碼的,這在第四、節(jié)的案例里可以看出對(duì)應(yīng)關(guān)系。
3.3 Modbus RTU的數(shù)據(jù)位
Modbus RTU的數(shù)據(jù)位根據(jù)不同的功能碼有不同的長(zhǎng)度。
3.4 Modbus RTU的數(shù)據(jù)校驗(yàn)
Modbus RTU采用CRC-16校驗(yàn),對(duì)一個(gè)數(shù)據(jù)幀里校驗(yàn)數(shù)據(jù)前面所有的數(shù)據(jù)進(jìn)行CRC校驗(yàn),得出的校驗(yàn)結(jié)果為2個(gè)字節(jié),低字節(jié)在前(先發(fā)),高字節(jié)在后(后發(fā))。
一個(gè)參考的單片機(jī)CRC計(jì)算C程序如下:
#include "crc16.h"
unsigned short modbus_crc_16(unsigned char *adata,unsigned int asize)        //CRC計(jì)算:計(jì)算結(jié)果為16位數(shù)據(jù),CRC低字節(jié)在左,高字節(jié)在右
{
unsigned short crc_out=0xffff;
unsigned int i,j;
unsigned char crc_low,crc_high;
for(i=0;i<asize;i++)
        {
        crc_out^=adata[ i];
        for(j=0;j<8;j++)
                {
                if ((crc_out&0x01)==0x01)
                        {
                        crc_out>>=1;
                        crc_out^=0xa001;
                        }
                else
                        {
                        crc_out>>=1;
                        }
                }
        }
//exchange high and low 8 bits
crc_low=(unsigned char)crc_out;
crc_high=(unsigned char)(crc_out>>8);
crc_out=(unsigned int)((crc_low<<8)+crc_high);
return crc_out;
}

四、 不理解嗎?來(lái)點(diǎn)例子,Modbus RTU數(shù)據(jù)幀案例詳解(重點(diǎn))

為了更清晰地理解,本節(jié)介紹Modbus RTU的通信例子。本章節(jié)大部分內(nèi)容引用自網(wǎng)絡(luò)文獻(xiàn)。
4.1 讀取輸出線圈狀態(tài)
01功能碼的作用是讀取從站里輸出線圈的狀態(tài),主站發(fā)送指令后從站響應(yīng)并返回?cái)?shù)據(jù),返回的線圈數(shù)據(jù)由低位線圈到高位線圈,注意這里的線圈數(shù)量是表示有多少個(gè)二進(jìn)制位。


關(guān)于CRC:
上圖中從站返回的除了校驗(yàn)碼的數(shù)據(jù)是0x11 0x 01 0x 04 0x cd 0x 6b 0x b2 0x 05,那么計(jì)算出來(lái)的CRC結(jié)果為0x 11 0x C3,其中0x 11是低字節(jié),0x C3是高字節(jié),那么完整的數(shù)據(jù)幀是:0x11 0x 01 0x 04 0x cd 0x 6b 0x b2 0x 05 0x 11 0x C3。CRC可以通過(guò)3.4節(jié)中的程序計(jì)算,或者使用網(wǎng)絡(luò)上的CRC在線計(jì)算工具。
4.2 讀取離散輸入狀態(tài)
    02功能碼的作用是讀取從站輸入線圈的狀態(tài),主站發(fā)送指令后從站響應(yīng)并返回?cái)?shù)據(jù),返回的線圈數(shù)據(jù)由低位線圈到高位線圈,注意這里的線圈數(shù)量也是表示有多少個(gè)二進(jìn)制位。


4.3 讀取保持寄存器
     03功能碼的作用是讀取從站保持寄存器的狀態(tài),主站發(fā)送指令后從站響應(yīng)并返回?cái)?shù)據(jù),返回的寄存器數(shù)據(jù)由低位寄存器到高位寄存器,注意這里的每個(gè)寄存器有2個(gè)字節(jié)組成,寄存器先發(fā)低的再發(fā)高的,每個(gè)寄存器先發(fā)高字節(jié),再發(fā)低字節(jié)。


4.4 讀取輸入寄存器
    04功能碼的作用是讀取從站輸入寄存器的狀態(tài),主站發(fā)送指令后從站響應(yīng)并返回?cái)?shù)據(jù),返回的寄存器數(shù)據(jù)由低位寄存器到高位寄存器,注意這里的每個(gè)寄存器有2個(gè)字節(jié)組成,寄存器先發(fā)低的再發(fā)高的,每個(gè)寄存器先發(fā)高字節(jié),再發(fā)低字節(jié)。


4.5 強(qiáng)制單個(gè)線圈
05功能碼的作用是設(shè)置從站的單個(gè)線圈值,主站發(fā)送指令后從站響應(yīng)并返回?cái)?shù)據(jù)。


4.6 強(qiáng)制多個(gè)線圈
0F功能碼的作用是設(shè)置從站的多個(gè)線圈值,主站發(fā)送指令后從站響應(yīng)并返回?cái)?shù)據(jù)。


4.7 預(yù)置單個(gè)寄存器
06功能碼的作用是設(shè)置從站的單個(gè)寄存器值,主站發(fā)送指令后從站響應(yīng)并返回?cái)?shù)據(jù)。


4.8 預(yù)置多個(gè)寄存器
10功能碼的作用是設(shè)置從站的多個(gè)寄存器值,主站發(fā)送指令后從站響應(yīng)并返回?cái)?shù)據(jù)。


編程時(shí),可以把Modbus RTU的線圈看作為位變量,寄存器看作為雙字節(jié)變量(一個(gè)寄存器為2個(gè)字節(jié),16位)。
可以看出,Modbus RTU是主從模式,是主站發(fā)出指令,從站響應(yīng),從站不能直接主動(dòng)地向主站發(fā)出指令。
Modbus RTU基本可以在所有串行通信里面使用,但是Modbus RTU一般在RS485通信里使用得較多一些。
后續(xù)大可能會(huì)寫(xiě)單片機(jī)與昆侖通態(tài)觸摸屏通信的實(shí)操,如有興趣可以關(guān)注避免失誤。
如有錯(cuò)誤,感謝指正。本文有一部分資料來(lái)自網(wǎng)絡(luò)資源,感謝其他大牛的分享,綠水青山,后會(huì)有期,全文暫時(shí)完。
沙鷗 成都 2024-6

評(píng)分

參與人數(shù) 1黑幣 +15 收起 理由
lkc8210 + 15 很給力!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏10 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:226055 發(fā)表于 2024-7-3 17:08 | 只看該作者
寫(xiě)得太好了
回復(fù)

使用道具 舉報(bào)

板凳
ID:1104568 發(fā)表于 2024-7-23 20:55 | 只看該作者
對(duì)初學(xué)者很明了
回復(fù)

使用道具 舉報(bào)

地板
ID:221178 發(fā)表于 2024-7-25 12:16 | 只看該作者
寫(xiě)的很好,學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

5#
ID:1117489 發(fā)表于 2024-7-26 09:43 | 只看該作者
對(duì)初學(xué)RS485的,真是太好了
回復(fù)

使用道具 舉報(bào)

6#
無(wú)效樓層,該帖已經(jīng)被刪除
7#
ID:118488 發(fā)表于 2025-5-18 08:41 | 只看該作者
對(duì)初學(xué)RS485的,真是太好了
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表