Modbus是一種串行通訊協議,誕生于1979年,最初是為了解決PLC之間的通訊問題而發表的。目前Modbus是工業通訊領域的業界標準,是工控領域最常用的通訊協議之一。
2016年3月16日 - 初稿(未發布)
2020年4月24日 - 添加功能碼對應寄存器等
作者:海伏科技——小濤(轉載注明出處)
閱讀原文 - http://www.sztoxda.net/class/63
擴展閱讀
Modbus是一種串行通訊協議,誕生于1979年,最初是為了解決PLC之間的通訊問題而發表的。目前Modbus是工業通訊領域的業界標準,是工控領域最常用的通訊協議之一。相信正在看這篇文章的您已經對Modbus協議有一定的了解,下面就讓我們開始主題,聊一聊Modbus通訊協議的工作原理。
通訊即數據的交互,通訊協議規定了一種通訊的規則,類似于人類交流使用的語言。這樣的解釋可能過于抽象,讓我們舉一個具體的案例,來設計一款我們自己的通訊協議。
假設現在要設計一款智能的電燈,分析一下它的功能,最基礎的功能就是開關了,規定當我發送指令1的時候就打開、發送指令0的時候關閉。最簡單的協議就是這個樣子:
- 指令功能:開燈
發送數據幀 | 01 |
---|---|
功能含義 | 燈的開關 |
這款電燈是集中控制的,也就是說一個控制器要同時控制很多盞燈,那么我們就要為燈編碼了。0代表所有的燈;1代表第一盞;2代表第二盞等等…… 以此類推,現在協議就變成了這樣:
- 指令功能:打開第三盞燈
發送數據幀 | 03 | 01 |
---|---|---|
功能含義 | 燈的序號 | 燈的開關 |
這款電燈不僅僅有開關,還能連續的調節亮度。那么我們規定0至100分別對應0%到100%亮度,這里又遇到一個問題:如何區分一條指令是調節亮度還是調節開關呢?
為了區分還要定義這條指令的功能碼:01代表調節開關、02代表調節亮度,現在協議就變成了這樣:
- 指令功能:打開第三盞燈
發送數據幀 | 03 | 01 | 01 |
---|---|---|---|
功能含義 | 燈的序號 | 調節的功能 | 燈的開關 |
- 指令功能:將第三盞燈的亮度調節至50%
發送數據幀 | 03 | 02 | 50 |
---|---|---|---|
功能含義 | 燈的序號 | 調節的功能 | 亮度調節 |
繼續增加功能,如果這套控制系統中還有一個光照傳感器,控制器需要從中讀出現在的環境亮度,從而實現對所有燈的自動控制。這里就是一個讀的指令,區別于上面的指令新定義個功能碼:03代表讀取光照傳感器的亮度,同樣用0-100表示最小-最大量程:
- 指令功能:讀環境亮度
發送數據幀 | 05 | 03 | 00 |
---|---|---|---|
功能含義 | 照度傳感器的序號 | 讀取功能 | 要讀取值的地址 |
傳感器收到數據后將結果返回:
- 指令功能:傳感器返回
發送數據幀 | 05 | 03 | 80 |
---|---|---|---|
功能含義 | 照度傳感器的序號 | 讀取功能 | 要讀取值的亮度值 |
以上就是通訊協議的基本思路,像這樣我們自己設計的協議由于不是通用的,我們稱之為私有協議。私有協議能實現我們系統里想要的功能,只要在主站(Master)和從站(Slave)之間預先規定好通訊的規則即可進行通訊。
但是從上面可以看出,經常為了增加一個設計之初沒有想到的功能就導致整個協議發生巨大的變化,非常不利于后續升級,而且私有協議的標準不統一,導致不同廠家的產品無法進行通訊,此時我們就需要一個通用的,能實現大部分場合的通訊協議。
Modbus協議是一主多從設計,也就是說一個標準的Modbus通信網絡中只能有一個主站,采取一問一答的方式進行通信,從站不能與從站直接通信。實現更復雜的通信情況例如多主站等需要使用Modbus網關設備,其中可能運行不止一套Modbus協議,這種情況我們以后再詳細講解。
Modbus有兩種串行通訊模式,ASCII Mode 和RTU Mode,這里重點介紹最常用的RTU模式。RTU模式是將數據直接以16進制的方式以串口傳輸,一個完整的RTU數據幀包含以下內容:
數據幀格式:
開始 | 從站地址 | 功能碼 | 數據位 | CRC校驗碼 | 結束 |
---|---|---|---|---|---|
4個字符空閑 | 8bits | 8bits | n x 8bits | 16bits | 4個字符空閑 |
既然是一問一答那么就有發送幀和返回幀,返回幀和發送幀的格式是一樣的,返回幀需要重復從站地址、功能碼等信息。對于寫入類指令數據位返回操作成功、失敗的狀態,對于讀取類指令數據位返回需要讀取的數據。
既然要實現所有設備通用,就不能按功能來區分。Modbus將設備要通訊的功能抽象成了寄存器。寄存器分為四類:
控制電燈明暗程度的,由主站下發模擬量指令,叫做 保持寄存器(Holding Registers),我們稱之為 模擬量輸出寄存器簡稱AO(Analog Output)。
讀取環境光照程度的,由主站讀取模擬量指令,叫做 輸入寄存器(Input Registers),我們稱之為 模擬量輸入寄存器簡稱AI(Analog Input)。
每一類寄存器用兩個字節代表寄存器編號,0x0000-0xFFFF(十六進制表示)或0-65535(十進制表示)。
Modbus協議最主要的任務就是保證主站與從站各個寄存器的數據同步
寄存器 | 功能碼(十六進制表示) | 描述 |
---|---|---|
開關量輸出寄存器(DO) | 01 | 讀開關量輸出寄存器(單個/多個) |
開關量輸出寄存器(DO) | 05 | 寫開關量輸出寄存器(單個) |
開關量輸出寄存器(DO) | 0F | 寫開關量輸出寄存器(多個) |
開關量輸入寄存器(DI) | 02 | 讀開關量輸入寄存器(單個/多個) |
模擬量輸入寄存器(AO) | 03 | 讀模擬量輸出寄存器(單個/多個) |
模擬量輸入寄存器(AO) | 06 | 寫模擬量輸出寄存器(單個) |
模擬量輸入寄存器(AO) | 10 | 寫模擬量輸出寄存器(多個) |
模擬量輸入寄存器(AI) | 03 | 讀模擬量輸入寄存器(單個/多個) |
如何分析一幀數據的含義:
數據幀有以下幾部分組成:從站地址 、功能碼、數據位、CRC校驗碼。根據從站地址判斷是廣播幀(00)還是跟某一個從站通信的幀(01-EF)。再根據功能碼判斷是操作哪一類寄存器及執行什么動作。后面緊跟的一般是操作長度、起始地址等信息;最后兩個字節(一個字節是8bit)是校驗位。這樣就可以分析每一幀數據都在執行什么動作。
了解到這些我們結合海伏科技的高壓電源來介紹各類寄存器的用法:
海伏科技的每款支持通信的電源產品都會配備Modbus協議說明,指明了上述每一個寄存器對應的功能,操作時只需要向相應的寄存器中寫入值就可以實現對高壓電源的控制。
本文只是簡單介紹Modbus協議及學習方法,讓初學者對Modbus協議有一個框架性的認識。具體每一種功能碼對應的幀格式由于篇幅關系這里就不一一介紹了,可以查看擴展閱讀中的原版協議詳細了解。