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