MODBUS協議軟件開發(fā)(modbus協議實現)
1、相關話題:第四次工業(yè)革命
我國提出了中國制造2025計劃,同樣,德國也提出了工業(yè)4.0計劃,無疑,這是當前最熱門的技術方向之一,甚至有很多人將之稱為“第四次工業(yè)革命”。
到現在為止,人類歷史上共出現四次工業(yè)革命:
第一次工業(yè)革命:以蒸汽機的發(fā)明為標志,發(fā)源地是英國;第一次工業(yè)革命使得英國成為全球第一強國;
第二次工業(yè)革命:以內燃機的發(fā)明為標志,發(fā)源地是德國;第二次工業(yè)革命使得德國一躍成為全球強國,美國也緊緊抓住第二次工業(yè)革命的機遇,成為全球第一強國;
第三次工業(yè)革命:以計算機技術為標志,發(fā)源地是美國;第三次工業(yè)革命讓美國保持了數十年全球霸主的地位。
目前全球各國關注的第四次工業(yè)革命,普遍的觀點是以“AI 制造”為標志,從目前的發(fā)展態(tài)勢來看,最可能取得第四次工業(yè)革命成功的國家是中國或美國。
第四次工業(yè)革命方興未艾,使得制造業(yè)的提升成為全球關注的中心,大量從事軟件開發(fā)的工程師,也將目光投向工業(yè)制造,因此PLC與MODBUS也越來越熱。
2、可編程邏輯控制器PLC
PLC,Programmable Logic Controller,可編程邏輯控制器。
PLC可以被看成用在工業(yè)控制的微處理器,PLC包含CPU、內存、I/O、數模轉換單元。
PLC具有穩(wěn)定性高、可擴展性強,因而在工業(yè)控制領域得到廣泛應用。
與此同時,PLC為工程技術人員提供圖形化編程接口,學習起來非常容易,不需要計算機專業(yè)知識也能進行工業(yè)控制的程序編寫,因此深受工程技術人員的喜愛。
3、MODBUS協議
PLC的應用,使得工業(yè)制造的數字化提升了一大步。如何利用收集的數據,進行分析,然后對工業(yè)制造過程進行優(yōu)化,是工業(yè)制造能力提升的關鍵。
MODBUS協議1979年由德國施耐德電氣公司(準確講是施耐德公司的前身Modicon公司)發(fā)表,隨即得到廣泛的關注與應用。
MODBUS協議的提出,是為了讓擁有PLC能力的自動化設備,進一步擁有通信能力。
MODBUS協議得到廣泛應用的原因有:
(1)免費;
(2)易于使用;
(3)應用的可擴展能力強。
4、MODBUS協議
MODBUS協議很容易獲得,進入modbus官網,即可下載協議文檔。
當前最新的版本是《Modbus_Application_Protocol_V1_1b3》,僅有50頁,感興趣的讀者可以自行下載和閱讀。
5、MODBUS協議的層次
MODBUS雖然應用于工業(yè)制造領域,但是協議對網絡承載層的適應性很強。
從網絡分層的角度來看,我們可以把MODBUS看成應用層協議。這兩年來,我接觸過下面類型MODBUS協議:
MODBUS on TCP
MODBUS on UDP
MODBUS on RS-232
MODBUS on RS-422
MODBUS on RS-485
上述各種MODBUS協議實現,很容易實現互聯互通。
下圖是MODBUS的網絡分層圖:
6、MODBUS協議定義
MODBUS協議有兩種模式:MODBUS RTU和MODBUS ASCII,前者為二進制格式,后者為ASCII格式??紤]到MODBUS RTU格式更緊湊,處理起來速度更快,實際使用中,主要采用MODBUS RTU。
MODBUS協議定義了兩個名詞:
ADU,Application Data Unit,應用數據單元;
PDU,Protocol Data Unit,協議數據單元;
考慮到MODBUS數據報文幀僅僅由四部分組成,非常緊湊,實際使用中,大多數開發(fā)人員并不關心ADU和PDU這兩個名詞。
MODBUS數據報文幀的格式如下:
MODBUS數據報文幀四個部分的含義:
Additional addres:附加地址,用于標識終端設施的地址;使用附加地址,MODBUS支持對多個終端通過總線收集數據、設置參數;
Function code:功能碼,標識對終端進行的操作;
Data:報文幀包含的數據(可以為空);
Error check:CRC16校驗碼。
7、MODBUS協議軟件的開發(fā)
由于MODBUS協議實在太簡單,并且由于MODBUS與承載層沒有相關性,導致MODBUS的軟件開發(fā)特別容易,接到一個從未做過的新任務,往往不到一天就可以初步開發(fā)完成。
這是我前段時間寫過的一段代碼,你會發(fā)現,它簡直簡單到極點:
adubytes[0] = slaveId;aduBytes[1] = FUNCTION_CODE_READ_HOLDING_REGISTERS;aduBytes[2] = (byte)((startAddress >> 8) & 0xFF);aduBytes[3] = (byte)(startAddress & 0xFF);aduBytes[4] = (byte)((registerQuantity >> 8) & 0xFF);aduBytes[5] = (byte)(registerQuantity & 0xFF);long crcValue = CommonUtil.getCrcValue(aduBytes, 0, 6);aduBytes[6] = (byte)(crcValue & 0xFF);aduBytes[7] = (byte)((crcValue >> 8) & 0xFF);
天有點晚了,隨手寫了這篇文章,希望對MODBUS的開發(fā)者有用。