MODBUS是一個工業(yè)上通信常用的通訊協(xié)議,一般在PLC上面用的比較多,主要是定義了一種數(shù)據(jù)傳輸?shù)囊?guī)范,比如數(shù)據(jù)發(fā)給誰,數(shù)據(jù)是干嘛的,數(shù)據(jù)錯沒錯,接收到數(shù)據(jù)的從機(jī)告訴我數(shù)據(jù)有沒有接受到等.
傳輸?shù)姆绞降脑挶容^多的是使用RS232c形式的串口傳輸,當(dāng)然485傳輸也可以,比較高端的可以使用網(wǎng)絡(luò)的tcp傳輸,但是是和之前的串口傳輸有區(qū)別的.
在使用232傳輸?shù)臅r候,整個系統(tǒng)中只有一個主機(jī),剩下的全部是設(shè)備,也就是說,只有作為主機(jī)的那個角色才能初始化網(wǎng)絡(luò),并且對整個網(wǎng)絡(luò)上的所有從機(jī)進(jìn)行控制,從機(jī)和從機(jī)之間不允許直接通訊,這就相當(dāng)于一臺PLC對它外接的設(shè)備進(jìn)行控制了.
在使用TCP傳輸?shù)臅r候就沒有主機(jī)從機(jī)的概念了,對等技術(shù)通訊,也就是說,所有的節(jié)點(diǎn)的地位是對等的,控制器即可以接受數(shù)據(jù)并作出響應(yīng),也可以主動查詢網(wǎng)絡(luò)上另一個控制器的狀態(tài),當(dāng)然,但是協(xié)議上,依然會有主機(jī)從機(jī)的數(shù)據(jù)定義
之所以這樣是因?yàn)樵?32的網(wǎng)絡(luò)上沒有沖突檢測,要是兩個主機(jī),那數(shù)據(jù)很容易就混亂了,但是到了tcp時代,底層的數(shù)據(jù)鏈路層已經(jīng)做了沖突檢測的工作,自然就可以同時傳輸不擔(dān)心數(shù)據(jù)撞車了.
到這里我們看看modbus數(shù)據(jù)傳輸?shù)膮f(xié)議模型
開頭是地址幀,在modbus網(wǎng)絡(luò)中,每一個從機(jī)都有一個地址,主機(jī)在訪問從機(jī)的時候依靠這個唯一的地址識別,多個從機(jī)接收到主機(jī)的數(shù)據(jù)的時候,匹配接收到的數(shù)據(jù)和自身的地址,匹配上的那個從機(jī)作出響應(yīng),其他的都忽略.
第二個是功能碼,決定這一幀數(shù)據(jù)主要是干嘛的,輸入數(shù)據(jù),輸出數(shù)據(jù),讀取控制量等
第三是數(shù)據(jù),可以有也可以沒有
第四是差錯校驗(yàn),用來對之前發(fā)送的數(shù)據(jù)校驗(yàn),防止發(fā)送過程中因?yàn)殡姶鸥蓴_,數(shù)據(jù)出錯.
上面只是簡單地協(xié)議原型,接下來這個協(xié)議原型有兩種實(shí)現(xiàn),分別叫做ascii實(shí)現(xiàn)和RTU實(shí)現(xiàn),我個人比較喜歡稱之為命令行實(shí)現(xiàn)和代碼實(shí)現(xiàn),為什么這么叫后面你就會知道了.首先我們要知道,modbus是按byte傳輸?shù)?也就是一次傳輸一個字節(jié)
RTU模式
在該模式下,傳輸是這樣的
首先,數(shù)據(jù)已幀為單位傳輸,如果一byte數(shù)據(jù)的傳輸時間為T,那么沒兩幀之間的間隔最小應(yīng)該要大于3.5T,否則從機(jī)不能分辨這是兩幀,第二,同一幀連續(xù)的兩個數(shù)據(jù)之間的間隔時間不能超過1.5T,否則節(jié)點(diǎn)會認(rèn)為這一幀數(shù)據(jù)不完整,這說明我們在modbus傳輸?shù)臅r候要使能一個定時器的工作.
其次,地址位一個字節(jié) 功能代碼一個字節(jié),數(shù)據(jù)n字節(jié),crc校驗(yàn)2字節(jié),那么這個n的限制是多少?協(xié)議規(guī)定一幀中數(shù)據(jù)最多是252字節(jié),最少可以是0字節(jié)
Ascii模式
在該模式下,傳輸?shù)膸械臄?shù)據(jù)的每一位只能是ascii碼的0-9 a-f,因?yàn)閞tu模式下一字節(jié)一個數(shù)據(jù),也就是1字節(jié)0x00-0xff,所以在ascii模式下為了傳送相同的數(shù)據(jù),必須兩個字節(jié)標(biāo)識一個有效數(shù)據(jù),也就是如下
可以看到,找ascii模式下,不是依靠時間間隔判定幀起始了,而是依靠特定字符判斷,結(jié)束也是按照特定字符判斷,起始的判斷是’:’字符,結(jié)束的判斷是windows下的回車換行,數(shù)據(jù)的最大長度被擴(kuò)容到了2*252,這樣,兩種傳輸模式能傳輸相同的數(shù)據(jù)量,但是ascii傳輸?shù)母?
但是并不是說時間判據(jù)在ascii模式中就沒有用了,還是有用的,字符間的間隔不能大于1s,大于1s認(rèn)為這一幀數(shù)據(jù)丟失.同樣我們可以計(jì)算出來ascii幀的最大長度是513字節(jié)
這個時候你能理解為什么這個叫命令行模式了,因?yàn)檫@種模式下發(fā)送的是可視化的字符串,可以人工的輸入,而之前的rtu模式,手工輸入多麻煩啊,一般程序輸入,而且我們可以判定,他以回車換行作為結(jié)尾,應(yīng)該早期主要是在windows上調(diào)試的,因?yàn)閘inux只需要回車就能實(shí)現(xiàn)windows的回車換行,在這種模式下可以把指令寫在文本中直接輸入.不過這兩年acsii模式用的少了,因?yàn)檎{(diào)試軟件的出現(xiàn)簡化了手工輸入的步驟.
說到這里,兩種模式之間的不同還有一個校驗(yàn)方式的不同,RTU使用crc校驗(yàn),ASCII使用LRC校驗(yàn),首先看看crc
然后是LRC
前面說了,不符合時間規(guī)則的數(shù)據(jù)將會被丟掉,那主機(jī)怎么知道被丟掉了呢?而且假如主機(jī)向100設(shè)備發(fā)數(shù)據(jù),網(wǎng)絡(luò)里面沒有100怎么辦?
是這樣的,modbus最多能支持255個子設(shè)備的接入,地址從0x01-0xff,而0x00是廣播地址,也就是說,0x00發(fā)送的數(shù)據(jù)所有的設(shè)備都要接收,但是不能響應(yīng),而其他的節(jié)點(diǎn)的設(shè)備在收到數(shù)據(jù)之后,必須在有限的時間里面進(jìn)行響應(yīng),或者說是應(yīng)答,主機(jī)端會有一個超時管理,超過一定時間沒有反應(yīng)就會認(rèn)為數(shù)據(jù)丟失,該時間可以自由設(shè)置,設(shè)計(jì)者在設(shè)計(jì)的時候應(yīng)當(dāng)保證盡量使得超時時間大于任何一個外設(shè)的響應(yīng)時間.
其實(shí),當(dāng)設(shè)備接收到了數(shù)據(jù)應(yīng)該怎么應(yīng)答,這個時候又分為正確應(yīng)答和錯誤應(yīng)答,正確應(yīng)答很好說,還是這個格式的數(shù)據(jù)幀
地址是從機(jī)自己的地址,功能碼和主機(jī)發(fā)送來的功能碼保持一致,數(shù)據(jù)看需求(功能碼的需求)
錯誤的請求的回應(yīng),還是在功能碼上下功夫,之前忘了說,功能碼是從0x00-0x7f,也就是最高位都是0,當(dāng)請求出錯的時候,將主機(jī)發(fā)送過來的功能碼加上一個0x80,讓最高位為1就OK了,數(shù)據(jù)部分可以定義一個異常碼,比如請求獲取溫度,發(fā)現(xiàn)溫度傳感器離線了,定義一個異常碼0x01,數(shù)據(jù)域放0x01,主機(jī)就知道出錯的具體原因是什么了.
到這里基本上寫一部分就說完了,最后附錄上modbus預(yù)定義的功能碼和異常碼,具體可以參考modbus協(xié)議文檔.
功能碼有:
異常碼為
聯(lián)系客服