MODBUS協議詳解


   MODBUS是一個工業上通信常用的通訊協議,一般在PLC上面用的比較多,主要是定義了一種數據傳輸的規范,比如數據發給誰,數據是干嘛的,數據錯沒錯,接收到數據的從機告訴我數據有沒有接受到等.

   傳輸的方式的話比較多的是使用RS232c形式的串口傳輸,當然485傳輸也可以,比較高端的可以使用網絡的tcp傳輸,但是是和之前的串口傳輸有區別的.

  在使用232傳輸的時候,整個系統中只有一個主機,剩下的全部是設備,也就是說,只有作為主機的那個角色才能初始化網絡,並且對整個網絡上的所有從機進行控制,從機和從機之間不允許直接通訊,這就相當於一台PLC對它外接的設備進行控制了.

  在使用TCP傳輸的時候就沒有主機從機的概念了,對等技術通訊,也就是說,所有的節點的地位是對等的,控制器即可以接受數據並作出響應,也可以主動查詢網絡上另一個控制器的狀態,當然,但是協議上,依然會有主機從機的數據定義

  之所以這樣是因為在232的網絡上沒有沖突檢測,要是兩個主機,那數據很容易就混亂了,但是到了tcp時代,底層的數據鏈路層已經做了沖突檢測的工作,自然就可以同時傳輸不擔心數據撞車了.

  到這里我們看看modbus數據傳輸的協議模型

  開頭是地址幀,在modbus網絡中,每一個從機都有一個地址,主機在訪問從機的時候依靠這個唯一的地址識別,多個從機接收到主機的數據的時候,匹配接收到的數據和自身的地址,匹配上的那個從機作出響應,其他的都忽略.

  第二個是功能碼,決定這一幀數據主要是干嘛的,輸入數據,輸出數據,讀取控制量等

  第三是數據,可以有也可以沒有

  第四是差錯校驗,用來對之前發送的數據校驗,防止發送過程中因為電磁干擾,數據出錯.

 

  上面只是簡單地協議原型,接下來這個協議原型有兩種實現,分別叫做ascii實現和RTU實現,我個人比較喜歡稱之為命令行實現和代碼實現,為什么這么叫后面你就會知道了.首先我們要知道,modbus是按byte傳輸的,也就是一次傳輸一個字節

RTU模式

  在該模式下,傳輸是這樣的

  首先,數據已幀為單位傳輸,如果一byte數據的傳輸時間為T,那么沒兩幀之間的間隔最小應該要大於3.5T,否則從機不能分辨這是兩幀,第二,同一幀連續的兩個數據之間的間隔時間不能超過1.5T,否則節點會認為這一幀數據不完整,這說明我們在modbus傳輸的時候要使能一個定時器的工作.

  其次,地址位一個字節 功能代碼一個字節,數據n字節,crc校驗2字節,那么這個n的限制是多少?協議規定一幀中數據最多是252字節,最少可以是0字節

 

  Ascii模式

在該模式下,傳輸的幀中的數據的每一位只能是ascii碼的0-9 a-f,因為rtu模式下一字節一個數據,也就是1字節0x00-0xff,所以在ascii模式下為了傳送相同的數據,必須兩個字節標識一個有效數據,也就是如下

可以看到,找ascii模式下,不是依靠時間間隔判定幀起始了,而是依靠特定字符判斷,結束也是按照特定字符判斷,起始的判斷是’:’字符,結束的判斷是windows下的回車換行,數據的最大長度被擴容到了2*252,這樣,兩種傳輸模式能傳輸相同的數據量,但是ascii傳輸的更慢了,

  但是並不是說時間判據在ascii模式中就沒有用了,還是有用的,字符間的間隔不能大於1s,大於1s認為這一幀數據丟失.同樣我們可以計算出來ascii幀的最大長度是513字節

  這個時候你能理解為什么這個叫命令行模式了,因為這種模式下發送的是可視化的字符串,可以人工的輸入,而之前的rtu模式,手工輸入多麻煩啊,一般程序輸入,而且我們可以判定,他以回車換行作為結尾,應該早期主要是在windows上調試的,因為linux只需要回車就能實現windows的回車換行,在這種模式下可以把指令寫在文本中直接輸入.不過這兩年acsii模式用的少了,因為調試軟件的出現簡化了手工輸入的步驟.

  說到這里,兩種模式之間的不同還有一個校驗方式的不同,RTU使用crc校驗,ASCII使用LRC校驗,首先看看crc

然后是LRC

  前面說了,不符合時間規則的數據將會被丟掉,那主機怎么知道被丟掉了呢?而且假如主機向100設備發數據,網絡里面沒有100怎么辦?

  是這樣的,modbus最多能支持255個子設備的接入,地址從0x01-0xff,而0x00是廣播地址,也就是說,0x00發送的數據所有的設備都要接收,但是不能響應,而其他的節點的設備在收到數據之后,必須在有限的時間里面進行響應,或者說是應答,主機端會有一個超時管理,超過一定時間沒有反應就會認為數據丟失,該時間可以自由設置,設計者在設計的時候應當保證盡量使得超時時間大於任何一個外設的響應時間.

  其實,當設備接收到了數據應該怎么應答,這個時候又分為正確應答和錯誤應答,正確應答很好說,還是這個格式的數據幀

  地址是從機自己的地址,功能碼和主機發送來的功能碼保持一致,數據看需求(功能碼的需求)

  錯誤的請求的回應,還是在功能碼上下功夫,之前忘了說,功能碼是從0x00-0x7f,也就是最高位都是0,當請求出錯的時候,將主機發送過來的功能碼加上一個0x80,讓最高位為1就OK了,數據部分可以定義一個異常碼,比如請求獲取溫度,發現溫度傳感器離線了,定義一個異常碼0x01,數據域放0x01,主機就知道出錯的具體原因是什么了.

  到這里基本上寫一部分就說完了,最后附錄上modbus預定義的功能碼和異常碼,具體可以參考modbus協議文檔.

功能碼有:

 

異常碼為


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM