Modbus 協議簡易入門教程
大家好,我是小麥,以前寫過一篇文章是關於modbus
協議的,只是簡單地做了一下介紹,這次對於modbus RTU
協議進行了深入的學習。
背景
介紹modbus rtu
之前,我們可以瞭解到,Modbus
是施耐德電氣公司,於 1979 年發明的,是全球第一個真正用於工業現場的總線協議。四十多年過去了,現在仍然被廣泛使用在各個工業控制領域。除了這個協議很穩定的原因之外:
-
免費;
-
方便部署和維護;
-
對供應商來說,修改移動本地的比特或字節沒有很多限制;
modbus
是OSI
模型第七層上的應用層報文傳輸協議,OSI
定義了開放系統的層次結構、層次之間的相互關係以及各層所包括的可能的任務,作爲一個框架來協調和組織各層所提供的服務。
OSI
參考模型並沒有提供一個可以實現的方法,而是描述了一些概念,用來協調進程間通信標準的制定。即OSI
參考模型並不是一個標準,而是一個在制定標準時所使用的概念性框架。
modbus
在OSI
模型中,可以描述爲下圖;
modbus osi 模型中的位置
EIA485
/TIA485
就是RS485
,隨着技術不斷髮展,485 標準目前是電信行業協會(TIA)維護,所以名稱爲 TIA-485,當然工程師及應用指南仍繼續用 RS-485 來稱呼也是沒問題的;
下面我們來介紹一些串行鏈路協議。
Modbus 串行鏈路協議
Modbus
串行鏈路協議是一個主從模式(主機和從機),半雙工的數據傳輸協議,485 標準通常需要兩條線,在某一個確定時刻,有一個主機和從機進行通訊。
-
主從模式:通常總線上有一個主機和多個從機,每個從機有唯一的 ID,主機通過 ID 進行尋址從機,然後進行數據傳輸;
-
半雙工傳輸:相對應半雙工的是全雙工,全雙工運行發送數據和接收數據同時發生,所以半雙工就不難理解了,同一時刻只能進行發送數據,或者只能接收數據;
整體的結構圖如下所示;
一個 485 總線的主從模式
這裏我們還要明確幾點:
- 從機無法主動向從機發送數據,只有在主機發送數據給從機(發送請求),然後從機接收到主機發送的數據之後,再回傳數據給主機;具體如下所示;
主從模式
正如前面所提到的,modbus
是半雙工傳輸的,即主機發送數據的時候,是不能接收數據的,所以這裏總共分爲兩步來進行。
-
主機發送數據的方式有兩種,一個是 1 對 1,一個是 1 對多,也就是我們常說的廣播形式,所有從機都可以收到主機發送的數據;
1 對 1 只需要發送數據給特定地址的從機即可,廣播只需要把發送地址設置爲 0 即可,所以廣播地址爲 0;
這裏我們已經大致瞭解了主機和從機之間的數據傳輸的情況,下面我們就再來介紹一下數據傳輸的具體格式;
傳輸模式
先來說說 Modbus 有兩種傳輸模式,RTU 傳輸模式和 ASCII 傳輸模式;
-
RTU 傳輸:
Remote Terminal Unit
模式在 Modbus 中消息由十六進制組成,數據密度高,吞吐率高; -
ASCII 傳輸:消息由 ASCII 字符發送效率不及 RTU 模式,無法使用 RTU 模式的定時管理時,使用 ASCII 模式;
比如:
0x12
會被整合成兩個字符發送:0x31
和0x32
發送,因爲
0x31
等於字符 1;0x32
等於字符 2
下面我們會主要介紹modbus RTU
。
幀格式
在講幀格式之前,首先我們想象一下,人與人之間的對話,最基本單元是漢字,然後相互交流就用漢字組成的句子,比如下面的對話;
-
老闆問:中午喫什麼?
-
小樟說:喫飯吧!
所以機器之間的通信也是類似的,我們可以把字節當作最基本的數據單元,然後由字節組成句子,也就是通信幀;
但是現在情況出現了變化,對話的人裏,除了小樟,還有一個小紅,這時候,爲了明確和誰說話,就需要在對話前面加上名字:
-
老闆:小樟,中午吃麪嗎?
-
小樟:老闆,喫飯去吧。
-
小紅,沒有叫他,語言柚子;
所以我們繼續回到modbus
的數據幀格式,這裏的協議定義了一個基礎通信層的簡單協議數據單元(PDU
),具體如下圖所示;
所以這裏基本分爲四個部分,地址域,功能碼,數據,差錯校驗(CRC/LRC),統稱爲 ADU (Application Data Unit
),基本上進行傳輸的數據都要滿足這個格式,作爲一個完整的幀,對照前面老闆的對話內容,我們這裏可以簡單的理解一下:
-
地址域:可以理解成 具體和誰說話;
-
功能碼:可以理解成 具體動作,比如 去做,來拿,去喫 等等;
-
數據:可以理解成 具體內容,比如 面,飯 等等,也可以是其他,這裏配合上下文,所以是喫的東西;
-
差錯校驗:可以理解成,說出來的話必須可以讓人理解,不然別人聽不懂啊;實際上在協議中通常使用 CRC 或 LRC 保證傳輸的數據沒有錯誤;
下面我們再深入分析一下;
PDU
Modbus PDU(protocol data unit
) 格式被定義爲一個功能代碼,後面跟着一組關聯的數據。
該數據的大小和內容由功能代碼定義,整個 PDU(功能代碼和數據)的大小不能超過 253 個字節。
每個功能代碼都有一個特定的行爲,從設備可以根據所需的應用程序行爲靈活地實現這些行爲。
PDU 規範定義了數據訪問和操作的核心概念;但是,從設備可能會以規範中未明確定義的方式處理數據。
地址域
地址域佔用一個字節,所以一般來說尋址範圍是0~255
,一般在系統中用1~147
,其他地址暫時保留,另外,同一個總線上的從機,每個地址必須唯一。
其中0
是廣播地址;
下面是 Freemodbus 的一個從機初始化代碼,0x02
就是這個從機的地址,
eMBInit(MB_RTU, 0x02, 3, 115200, MB_PAR_NONE);
功能碼
功能碼佔一個字節,所以範圍是 0~255
,協議中規定了功能碼分爲三類:公共功能碼,用戶自定義功能碼,保留功能碼。整體如下所示;
image-20211224223246059
公共功能碼必須保證它的唯一性,這是由 Modbus 組織已經規定好,並且具有一致性測試的功能碼,所以在一定程度上,它保證了協議的可複用性。
由上表可知,公共功能碼分爲四種,分別是:
-
離散量輸入:只讀類型,單位:
bit
; -
線圈:讀寫類型,單位:
bit
; -
輸入寄存器:只讀類型,單位:字節;
-
保持寄存器:讀寫類型,單位:字節;
下面是移植 Freemodbus 協議,從機上需要對這四個公共功能碼處理的回調函數:
//輸入寄存器量
eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
eMBErrorCode eStatus = MB_ENOERR;
return eStatus;
}
//保持寄存器量
eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs,
eMBRegisterMode eMode )
{
eMBErrorCode eStatus = MB_ENOERR;
return eStatus;
}
//線圈數量
eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils,
eMBRegisterMode eMode )
{
eMBErrorCode eStatus = MB_ENOERR;
return eStatus;
}
//離散輸入數量
eMBErrorCode
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{
eMBErrorCode eStatus = MB_ENOERR;
return eStatus;
}
底層如何傳輸
我們先看一下最底層 modbus 數據是如何發送的,沒錯,看到 RS485 和 232,那我們自然想到了串口。
所以最根本的數據格式可以參考一下串口數據的定義,也就是我們說的起始位,數據位,校驗位,數據位;具體如下所示;
所以這裏我們可以規定一下:
起始位 + 數據位 + 校驗位(可選)+ 停止位 等於一個字符;因此這裏可以通過串口的波特率去計算出單個字符所需要的時間。
然後我們再看一下,modbus 幀是如何發送的?
在RTU
模式中,幀之間的間隔至少爲 3.5 個字符的空閒時間間隔,以便於表示幀的開始和幀的結束,所以如果想自己整一個modbus rtu
就需要一個定時器去結算空閒時間的長度。
3.5 字符時間
整個數據必須以連續的字符流進行發送,如果兩個字符之間的長度等於 1.5 個字符時間,則認爲幀消息不完整,則認爲設備不該接收該消息,具體如下所示;
1.5 字符時間
這裏需要注意的是 RTU 需要定時器中斷的參與,所以,1.5 字符時間和 3.5 字符時間的檢測,在串口通訊速率很高的時候,需要高頻率得進入中斷,這就會增加系統開銷。
所以通常在波特率低於19200
的時候,可以嚴格遵守 1.5 和 3.5 字符時間的規定。
如果波特率大於19200
的時候,需要滿足兩個固定時間即可:
-
1.5 字符時間:750 us;
-
3.5 字符時間:1.75ms;
總結
本文簡單介紹了modbus rtu
協議,包括串行鏈路通信,幀格式以及硬件鏈路層的消息格式,能力有限,本文難免存在錯誤和紕漏,請不吝賜教。篇幅有限本文先到這裏,下一篇介紹一下如何移植 Freemodbus 協議以及調試協議的過程。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/dVMLf04_6n-_HfANp7QQUA