詳解MODBUS標準協議——下篇
二、特點
Modbus具有以下幾個特點:
1、標準、開放,用戶可以免費、放心地使用Modbus協議,不需要交納許可證費,也不會侵犯知識產權。目前,支持Modbus的廠家超過400家,支持Modbus的產品超過600種。
2、Modbus可以支持多種電氣接口,如RS-232、RS-485等,還可以在各種介質上傳送,如雙絞線、光纖、無線等。
3、Modbus的幀格式簡單、緊湊,通俗易懂。用戶使用容易,廠商開發簡單。
三、功能碼定義 1 ModBus功能碼 01 READ COIL STATUS 02 READ INPUT STATUS 03 READ HOLDING REGISTER 04 READ INPUT REGISTER 05 WRITE SINGLE COIL 06 WRITE SINGLE REGISTER 15 WRITE MULTIPLE COIL 16 WRITE MULTIPLE REGISTER 四、傳輸方式 在ModBus系統中有2種傳輸模式可選擇。這2種傳輸模式與從機PC通信的能力是同等的。選擇時應視所用ModBus主機而定,每個ModBus系統只能使用一種模式,不允許2種模式混用。一種模式是ASCII(美國信息 交換碼),另一種模式是RTU(遠程 終端設備)。 用戶選擇想要的模式,包括 串口通信參數( 波特率、校驗方式等),在配置每個控制器的時候,在一個Modbus網絡上的所有設備都必須選擇相同的傳輸模式和串口參數。所選的ASCII或RTU方式僅適用于標準的Modbus網絡,它定義了在這些網絡上連續傳輸的消息段的每一位,以及決定怎樣將信息打包成消息域和如何解碼。在其它網絡上(像MAP和Modbus Plus)Modbus消息被轉成與串行傳輸無關的幀。 1.傳輸模式特性: ASCII可打印字符便于故障檢測,而且對于用高級語言(如Fortran)編程的主計算機及主PC很適宜。RTU則適用于 機器語言編程的計算機和PC主機。 用RTU模式傳輸的數據是8位二進制字符。如欲轉換為ASCII模式,則每個RTU字符首先應分為高位和低位兩部分,這兩部分各含4位,然后轉換成十六進制等量值。用以構成 報文的ASCII字符都是十六進制字符。ASCII模式使用的 字符雖是RTU模式的兩倍,但ASCII數據的譯碼和處理更為容易一些,此外,用RTU模式時報文字符必須以連續數據流的形式傳送,用ASCII模式,字符之間可產生長達1s的間隔,以適應速度較慢的機器。 控制器能設置為兩種傳輸模式(ASCII或RTU)中的任何一種在標準的Modbus網絡通信。 2.ASCII模式: 當控制器設為在Modbus網絡上以ASCII(美國標準信息交換代碼)模式通信,一個信息中的每8位字節作為2個ASCII字符傳輸,如數值63H用ASCII方式時,需發送兩個字節,即ASCII“6"(0110110)和ASCII”3“(0110011),ASCII字符占用的位數有7位和8位,國際通用7位為多。這種方式的主要優點是字符發送的時間間隔可達到1秒而不產生錯誤。 代碼系統 十六進制,ASCII 字符0...9,A...F 消息中的每個ASCII字符都是一個十六進制字符組成 每個字節的位 1個起始位 7個 數據位,最小的有效位先發送 1個 奇偶校驗位,無校驗則無 1個停止位(有校驗時),2個Bit(無校驗時) 錯誤檢測域 LRC(縱向冗長檢測) 3.RTU模式: 當控制器設為在Modbus網絡上以RTU模式通信,在消息中的每個8Bit字節按照原值傳送,不做處理,如63H,RTU將直接發送01100011。這種方式的主要優點是:數據幀傳送之間沒有間隔,相同波特率下傳輸數據的密度要比ASCII高,傳輸速度更快。 代碼系統 8位二進制, 十六進制數0...9,A...F 消息中的每個8 位域都是一或兩個十六進制字符組成 每個字節的位 1個起始位 8個 數據位,最小的有效位先發送 1個 奇偶校驗位,無校驗則無 1個停止位(有校驗時),2個Bit(無校驗時) 五、數據校驗方式 1.CRC: CRC域是兩個字節,包含一16位的二進制值。它由傳輸設備計算后加入到消息中。接收設備重新計算收到消息的CRC,并與接收到的CRC域中的值比較,如果兩值不同,則有誤。 CRC是先調入一值是全“1”的16位寄存器,然后調用一過程將消息中連續的8位字節和當前寄存器中的值進行處理。僅每個字符中的8Bit數據對CRC有效,起始位和停止位以及 奇偶校驗位均無效。 CRC產生過程中,每個8位字符都單獨和寄存器內容相異或(XOR),結果向最低有效位方向移動,最高有效位以0填充。LSB被提取出來檢測,如果LSB為1,寄存器單獨和預置的值或一下,如果LSB為0,則不進行。整個過程要重復8次。在最后一位(第8位)完成后,下一個8位字節又單獨和寄存器的當前值相異或(XOR)。最終寄存器中的值,是消息中所有的字節都執行之后的CRC值。 CRC添加到消息中時,低字節先加入,然后高字節。 CRC-16錯誤校驗程序如下:報文(此處只涉及 數據位,不指起始位、停止位和任選的 奇偶校驗位)被看作是一個連續的二進制,其最高有效位(MSB)首選發送。報文先與X↑16相乘(左移16位),然后看X↑16+X↑15+X↑2+1除,X↑16+X↑15+X↑2+1可以表示為二進制數11000,0000,0000,0101。整數商位忽略不記,16位余數加入該報文(MSB先發送),成為2個CRC校驗字節。余數中的1全部初始化,以免所有的零成為一條報文被接收。經上述處理而含有CRC字節的報文,若無錯誤,到接收設備后再被同一多項式(X↑16+X↑15+X↑2+1)除,會得到一個零余數(接收設備核驗這個CRC字節,并將其與被傳送的CRC比較)。全部運算以2為模(無進位)。 習慣于成串發送數據的設備會首選送出字符的最右位(LSB-最低有效位)。而在生成CRC情況下,發送首位應是被除數的最高有效位MSB。由于在運算中不用進位,為便于操作起見,計算CRC時設MSB在最右位。生成多項式的位序也必須反過來,以保持一致。多項式的MSB略去不記,因其只對商有影響而不影響余數。 生成CRC-16校驗字節的步驟如下: ①裝如一個16位 寄存器,所有數位均為1。 ②該16位寄存器的高位 字節與開始8位字節進行“異或”運算。運算結果放入這個16位寄存器。 ③把這個16寄存器向右移一位。 ④若向右(標記位)移出的數位是1,則生成多項式10,1000,000,0000,001和這個寄存器進行“異或”運算;若向右移出的數位是0,則返回③。 ⑤重復③和④,直至移出8位。 ⑥另外8位與該十六位寄存器進行“異或”運算。 ⑦重復③~⑥,直至該 報文所有字節均與16位 寄存器進行“異或”運算,并移位8次。 ⑧這個16位寄存器的內容即2字節CRC錯誤校驗,被加到報文的最高有效位。 另外,在某些非ModBus通信協議中也經常使用CRC16作為校驗手段,而且產生了一些CRC16的變種,他們是使用CRC16多項式X↑16+X↑15+X↑2+1,單首次裝入的16位寄存器為0000;使用CRC16的反序X↑16+X↑14+X↑1+1,首次裝入寄存器值為0000或FFFFH。CRC簡單函數如下: LRC錯誤校驗用于ASCII模式。這個錯誤校驗是一個8位二進制數,可作為2個ASCII十六進制字節傳送。把十六進制字符轉換成二進制,加上無循環進位的二進制字符和二進制補碼結果生成LRC錯誤校驗(參見圖)。這個LRC在接收設備進行核驗,并與被傳送的LRC進行比較,冒號(:)、回車符號(CR)、換行字符(LF)和置入的其他任何非ASCII十六進制字符在運算時忽略不計。 Modbus與PROFIBUS-DP協議比較 Modbus的協議內容是完全公開的,內容是簡單滴,實現起來是非常容易滴,單片機、PLC、DCS統統都能輕易實現。 Profibus則要復雜一些,關鍵是需要專用芯片進行二次開發,并且需要得到上級組織的認證,開發成本肯定高不少 。 當然從性能上講,基于串口的modbus rtu/ASCII通訊性能肯定比不過profibus dp,但是就一些儀表級的簡單通訊或者控制器級別的小數據量通訊,modbus是足以勝任的。說白了,就是modbus是*絲,profibus是高富帥! Modbus支持的功能碼: 功能碼 名稱 作用 01 讀取線圈狀態 取得一組邏輯線圈的當前狀態(ON/OFF) 02 讀取輸入狀態 取得一組開關輸入的當前狀態(ON/OFF) 03 讀取保持寄存器 在一個或多個保持寄存器中取得當前的二進制值 04 讀取輸入寄存器 在一個或多個輸入寄存器中取得當前的二進制值 05 強置單線圈 強置一個邏輯線圈的通斷狀態 06 預置單寄存器 把具體二進值裝入一個保持寄存器 07 讀取異常狀態 取得8個內部線圈的通斷狀態,這8個線圈的地址由控制器決定 08 回送診斷校驗 把診斷校驗報文送從機,以對通信處理進行評鑒 09 編程(只用于484) 使主機模擬編程器作用,修改PC從機邏輯 10 控詢(只用于484) 可使主機與一臺正在執行長程序任務從機通信,探詢該從機是否已完成其操作任務,僅在含有功能碼9的報文發送后,本功能碼才發送 11 讀取事件計數 可使主機發出單詢問,并隨即判定操作是否成功,尤其是該命令或其他應答產生通信錯誤時 12 讀取通信事件記錄 可是主機檢索每臺從機的ModBus事務處理通信事件記錄。如果某項事務處理完成,記錄會給出有關錯誤 13 編程(184/384 484 584) 可使主機模擬編程器功能修改PC從機邏輯 14 探詢(184/384 484 584) 可使主機與正在執行任務的從機通信,定期控詢該從機是否已完成其程序操作,僅在含有功能13的報文發送后,本功能碼才得發送 15 強置多線圈 強置一串連續邏輯線圈的通斷 16 預置多寄存器 把具體的二進制值裝入一串連續的保持寄存器 17 報告從機標識 可使主機判斷編址從機的類型及該從機運行指示燈的狀態 18 (884和MICRO 84) 可使主機模擬編程功能,修改PC狀態邏輯 19 重置通信鏈路 發生非可修改錯誤后,是從機復位于已知狀態,可重置順序字節 20 讀取通用參數(584L) 顯示擴展存儲器文件中的數據信息 21 寫入通用參數(584L) 把通用參數寫入擴展存儲文件,或修改之 22~64 保留作擴展功能備用 65~72 保留以備用戶功能所用 留作用戶功能的擴展編碼 73~119 非法功能 120~127 保留 留作內部作用 128~255 保留 用于異常應答 功能碼命令詳解: 在這些功能碼中較長使用的是1、2、3、4、5、6號功能碼,使用它們即可實現對下位機的數字量和模擬量的讀寫操作。 1、01號命令,讀可讀寫數字量寄存器(線圈狀態): 計算機發送命令:[設備地址] [命令號01] [起始寄存器地址高8位] [低8位] [讀取的寄存器數高8位] [低8位] [CRC校驗的低8位] [CRC校驗的高8位] 例:[11][01][00][13][00][25][CRC低][CRC高] 意義如下: <1>設備地址:在一個485總線上可以掛接多個設備,此處的設備地址表示想和哪一個設備通訊。例子中為想和17號(十進制的17是十六進制的11)通訊。 <2>命令號01:讀取數字量的命令號固定為01。 <3>起始地址高8位、低8位:表示想讀取的開關量的起始地址(起始地址為0)。比如例子中的起始地址為19。 <4>寄存器數高8位、低8位:表示從起始地址開始讀多少個開關量。例子中為37個開關量。 <5>CRC校驗:是從開頭一直校驗到此之前。設備響應:[設備地址] [命令號01] [返回的字節個數][數據1][數據2]...[數據n] [CRC校驗的高8位] [CRC校驗的低8位] 例:[11][01][05][CD][6B][B2][0E][1B] [CRC高] [CRC低] 意義如下: <1>設備地址和命令號和上面的相同。 <2>返回的字節個數:表示數據的字節個數,也就是數據1,2...n中的n的值。 <3>數據1...n:由于每一個數據是一個8位的數,所以每一個數據表示8個開關量的值,每一位為0表示對應的開關斷開,為1表示閉合。比如例子中,表示20號(索引號為19)開關閉合,21號斷開,22閉合,23閉合,24斷開,25斷開,26閉合,27閉合...如果詢問的開關量不是8的整倍數,那么最后一個字節的高位部分無意義,置為0。 <4>CRC校驗同上。 2、05號命令,寫數字量(線圈狀態): 計算機發送命令:[設備地址] [命令號05] [需下置的寄存器地址高8位] [低8位] [下置的數據高8位] [低8位] [CRC校驗的低8位] [CRC校驗的高8位] 例:[11][05][00][AC][FF][00][CRC高][CRC低] 意義如下: <1>設備地址和上面的相同。 <2>命令號:寫數字量的命令號固定為05。 <3>需下置的寄存器地址高8位,低8位:表明了需要下置的開關的地址。 <4>下置的數據高8位,低8位:表明需要下置的開關量的狀態。例子中為把該開關閉合。注意,此處只可以是[FF][00]表示閉合[00][00]表示斷開,其他數值非法。 <5>注意此命令一條只能下置一個開關量的狀態。 設備響應:如果成功把計算機發送的命令原樣返回,否則不響應。 3、03號命令,讀可讀寫模擬量寄存器(保持寄存器): 計算機發送命令:[設備地址] [命令號03] [起始寄存器地址高8位] [低8位] [讀取的寄存器數高8位] [低8位] [CRC校驗的高8位] [CRC校驗的低8位] 例:[11][03][00][6B][00][03] [CRC高][CRC低] 意義如下: <1>設備地址和上面的相同。 <2>命令號:讀模擬量的命令號固定為03。 <3>起始地址高8位、低8位:表示想讀取的模擬量的起始地址(起始地址為0)。比如例子中的起始地址為107。 <4>寄存器數高8位、低8位:表示從起始地址開始讀多少個模擬量。例子中為3個模擬量。注意,在返回的信息中一個模擬量需要返回兩個字節。 設備響應:[設備地址] [命令號03] [返回的字節個數][數據1][數據2]...[數據n] [CRC校驗的高8位] [CRC校驗的低8位] 例:[11][03][06][02][2B][00][00][00][64] [CRC高] [CRC低] 意義如下: <1>設備地址和命令號和上面的相同。 <2>返回的字節個數:表示數據的字節個數,也就是數據1,2...n中的n的值。例子中返回了3個模擬量的數據,因為一個模擬量需要2個字節所以共6個字節。 <3>數據1...n:其中[數據1][數據2]分別是第1個模擬量的高8位和低8位,[數據3][數據4]是第2個模擬量的高8位和低8位,以此類推。例子中返回的值分別是555,0,100。 <4>CRC校驗同上。 4、06號命令,寫單個模擬量寄存器(保持寄存器): 計算機發送命令:[設備地址] [命令號06] [需下置的寄存器地址高8位] [低8位] [下置的數據高8位] [低8位] [CRC校驗的高8位] [CRC校驗的低8位] 例:[11][06][00][01][00][03] [CRC高] [CRC低] 意義如下: <1>設備地址和上面的相同。 <2>命令號:寫模擬量的命令號固定為06。 <3>需下置的寄存器地址高8位,低8位:表明了需要下置的模擬量寄存器的地址。 <4>下置的數據高8位,低8位:表明需要下置的模擬量數據。比如例子中就把1號寄存器的值設為3。 <5>注意此命令一條只能下置一個模擬量的狀態。 設備響應:如果成功把計算機發送的命令原樣返回,否則不響應。 5、16號命令,寫多個模擬量寄存器(保持寄存器): 計算機發送命令:[設備地址] [命令號16] [需下置的寄存器地址高8位] [低8位] [數據數量高8位] [數據數量低8位] [下置的數據高8位] [低8位][……][……] [CRC校驗的高8位] [CRC校驗的低8位] 例:[11][16][00][01][00][01][00][05] [CRC高] [CRC低] 意義如下: <1>設備地址和上面的相同。 <2>命令號:寫模擬量的命令號固定為16。 <3>需下置的寄存器地址高8位,低8位:表明了需要下置的模擬量寄存器的地址。 <4>需下置的數據數量高8位,低8位:表明了需要下置的數據數量,這里為1。 <5>下置的數據高8位,低8位:表明需要下置的模擬量數據。比如例子中就把1號寄存器的值設為5。 設備響應:如果成功把計算機返回的如下命令,否則不響應。設備響應:[設備地址] [命令號16] [需下置的寄存器地址高8位] [低8位] [數據數量高8位] [數據數量低8位] [CRC校驗的高8位] [CRC校驗的低8位],如上例返回:[11][16][00][01][00][01] [CRC高] [CRC低]
2.LRC: