天天看點

Modbus 網絡通訊協定

開發人員編碼注意:      
在使用Modbus通訊協定,一定要編寫Modbus通訊協定和CRC校驗。      
(在遠距離資料通信中,為確定高效而無差錯地傳送資料,防止資料被破壞或者篡改,必須對資料進行CRC校驗。      
盡管CRC在錯誤檢測中非常有用,但CRC并不能可靠地校驗資料完整性,這是因為CRC多項式是線性結構,可以非常容易地通過改變資料方式達到CRC碰撞,這裡給一個更加通俗的解釋,假設一串帶有CRC校驗的代碼在傳輸中,如果連續出現差錯,當出錯次數達到一定次數時,那麼幾乎可以肯定會出現一次碰撞(值不對但CRC結果正确),但随着CRC資料位增加,碰撞幾率會顯著降低,比如CRC32比CRC16具有更可靠的驗證性,CRC64又會比CRC32更可靠,當然這都是按照ITU規範标準條件下。)      
如果你發送指定的指令,其中的CRC校驗直接使用提供的CRC低位位元組表和CRC高位位元組表中的位元組資料,那就不需要編寫CRC校驗。      
如今在工業現場總線中,常采用序列槽實作一些要求不太高的通訊控制,modbus協定更是最常用的傳輸資料的協定,而在整個通訊過程中,CRC校驗碼計算是一個注意點。      
Moldbus沒有規定實體層用什麼接口實作。隻要半雙工以上就可以。是以232口沒問題。
如果你的PLC用的是Modbus,那你一定要實作CRC校驗。否則接收端如果收不到CRC校驗包或者CRC校驗包不對,就會認為收到的資料包錯誤,不做任何響應。      
modbus通信協定是應用層協定(第七層),它目前可以用于3種通信網絡:      
1)用于串行口通信網絡,傳輸模式為modbus RTU和modbus ASCII;      
2)用于以太網口通信網絡,傳輸模式為modbus TCP;      
3)用于高速鍊路網絡,傳輸模式為modbus PLUS。

包括modbus協定在内,有很多種通信協定都可以用于現場總線。modbus PLUS就是一種現場總線,而modbus RTU/ASCII、modbus TCP隻是低速的普通通信網絡。      
========================
通訊傳送分為獨立的資訊頭,和發送的編碼資料      
編 碼 8位二進制 
起始位 1位 
資料位 8位 
奇偶校驗位 1位(偶校驗位) 
停止位 1位 
錯誤校檢 CRC(備援循環碼) 
初始結構 = ≥4位元組的時間       
(傳送的資料幀結構組成如下)      

位址碼 = 1 位元組 功能碼 = 1 位元組 資料區 = N 位元組 錯誤校檢 = 16位CRC碼  結束結構 = ≥4位元組的時間

位址碼:位址碼為通訊傳送的第一個位元組。這個位元組表明由使用者設定位址碼的從機将接收由主機發送來的資訊。并且每個從機都有具有唯一的位址碼,并且響應回送均以各自的位址碼開始。主機發送的位址碼表明将發送到的從機位址,而從機發送的位址碼表明回送的從機位址。 位址碼在溫濕度傳感器上電啟動後,可以顯示屏上看得到,且讀取位址碼發送的指令中必須跟該位址碼一緻。否則接收過來的響應會是錯誤的信号。 功能碼:通訊傳送的第二個位元組。ModBus通訊規約定義功能号為1到127。本儀表隻利用其中的一部分功能碼。作為主機請求發送,通過功能碼告訴從機執行什麼動作。作為從機響應,從機發送的功能碼與從主機發送來的功能碼一樣,并表明從機已響應主機進行操作。如果從機發送的功能碼的最高位為1(比如功能碼大與此同時127),則表明從機沒有響應操作或發送出錯。 資料區:資料區是根據不同的功能碼而不同。資料區可以是實際數值、設定點、主機發送給從機或從機發送給主機的位址。 CRC碼:二位元組的錯誤檢測碼。  

傳輸格式

(1)指令封包格式

  讀資料:

位址 功能碼 資料起始位址高位 資料起始位址低位 資料個數高位 資料個數低位

CRC

16位校驗

xx 04 00 00 00 02 xxxx低位在前

 傳回:

位址 功能碼 位元組長度 資料1輸入 資料2輸入

CRC

16位校驗

xx 04 04 xx高位在前 xx高位在前 xx xxxx低位在前

(2)、異常應答傳回

   非法功能:

從站位址 功能碼 異常碼 CRC16校驗
xx 80H+原功能碼 01 xxxx低位在前

   非法資料位址:

從站位址 功能碼 異常碼 CRC16校驗
xx 80H+原功能碼 02 xxxx低位在前

非法資料值:

從站位址 功能碼 異常碼 CRC16校驗
xx 80H+原功能碼 03 xxxx低位在前

(3)、變送器位址設定:

指令封包格式:

指令代碼高位 指令代碼地位 位址資料

CRC

16位校驗

FF A5 xx xxxx低位在前

傳回:

指令代碼高位 指令代碼地位 位址資料

CRC

16位校驗

FF A5 xx xxxx低位在前

// RTU協定 CRC校驗碼的計算

// *pushMsg為需要校驗的數組指針變量,usDataLen為需要校驗的資料個數變量

void CRC16(BYTE* pushMsg, unsigned short usDataLen)
 {
	BYTE uchCRCHi = 0xFF;
 	BYTE uchCRCLo = 0xFF;
 
 	unsigned int uIndex;
 	while(usDataLen--)
 	{
 		uIndex = uchCRCHi^*pushMsg++;	//計算CRC
 		uchCRCHi = uchCRCLo^auchCRCHi[uIndex];
 		uchCRCLo = auchCRCLo[uIndex];
 	}
 
 	*pushMsg++ = uchCRCHi;	//校驗資料高位在後
 	*pushMsg = uchCRCLo;	//校驗資料低位在前
 
 }
           

位址為1時, 讀取溫濕度值:(CRC校驗低位在前) 上位機發送: 01 03 00 02 00 02 65 CB (讀從資料起始位址為0000H開始的1個模拟量)

變送器傳回: 01 03 04 00 B4 01 EA 3B BD      即顯示屏上顯示的溫濕度資料:

T:17.9
H:49.0

 讀取位址碼值(即擷取裝置的型号ID):(CRC校驗低位在前)

上位機發送: 00 03 00 00 00 01 85 DB (讀從資料起始位址為0000H開始的1個模拟量)

變送器傳回: 00 03 02 00,位址L ,CRC_L,CRC_H 

從機傳回的溫濕度資料分别用兩個位元組表示,高位在前,低位在後; 傳回的資料範圍-32768 ~ 32767,實際溫濕度資料需要将傳回值除以10; 例如: 傳回濕度16進制資料:0x0311,對應10進制785,表示濕度為78.5%RH 傳回溫度16進制資料:0x00FF,對應10進制255,表示溫度為25.5℃ 傳回溫度16進制資料:0x8064,最高位為1表示附屬對應10進制785,表示濕度為78.5%RH

為變送器設定新位址碼,如“2”:(CRC校驗低位在前)

上位機發送:FF A5 02 BB 61

變送器傳回:FF A5 02 BB 61

如設定新位址碼“6”:(CRC校驗低位在前)

上位機發送:FF A5 06 BA A2

變送器傳回:FF A5 06 BA A2

(若需要同時與多台裝置Modbus協定通訊時,也可以自己去設定位址碼)

Modbus網絡通信其實就是串行通信,實體層和RS232/485等都是一樣的,      
二進制從做到右傳輸.一般來說,标準MODBUS是:1:位址碼2:功能碼 3:資料區 4:校驗碼(常用CRC校驗)最多255位.它是一主多從,主機發出指令,隻能是位址相對的從機回應,從機和從機之間無法通信.

========================

Modbus 協定是應用于電子控制器上的一種通用語言。通過此協定,控制器互相之間、控制器經由網絡(例如以太網)和其它裝置之間可以通信。它已經成為一通用工業标準。有了它,不同廠商生産的控制裝置可以連成工業網絡,進行集中監控。此協定定義了一個控制器能認識使用的消息結構,而不管它們是經過何種網絡進行通信的。它描述了一控制器請求通路其它裝置的過程,如果回應來自其它裝置的請求,以及怎樣偵測錯誤并記錄。它制定了消息域格局和内容的公共格式。
當在一Modbus網絡上通信時,此協定決定了每個控制器須要知道它們的裝置位址,識别按位址發來的消息,決定要産生何種行動。如果需要回應,控制器将生成回報資訊并用Modbus協定發出。在其它網絡上,包含了Modbus協定的消息轉換為在此網絡上使用的幀或包結構。這種轉換也擴充了根據具體的網絡解決節位址、路由路徑及錯誤檢測的方法。
1、在Modbus網絡上轉輸
标準的Modbus口是使用一RS-232C相容串行接口,它定義了連接配接口的針腳、電纜、信号位、傳輸波特率、奇偶校驗。控制器能直接或經由Modem組網。
控制器通信使用主—從技術,即僅一裝置(主裝置)能初始化傳輸(查詢)。其它裝置(從裝置)根據主裝置查詢提供的資料作出相應反應。典型的主裝置:主機和可程式設計儀表。典型的從裝置:可程式設計控制器。      
Modbus支援的功能碼:      
下表是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] [起始寄存器位址高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校驗:是從開頭一直校驗到此之前。在此協定的最後再作介紹。此處需要注意,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、讀隻可讀數字量寄存器(輸入狀态): 

和讀取線圈狀态類似,隻是第二個位元組的指令号不再是1而是2。

3、寫數字量(線圈狀态): 

計算機發送指令:[裝置位址] [指令号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>注意此指令一條隻能下置一個開關量的狀态。

裝置響應:如果成功把計算機發送的指令原樣傳回,否則不響應。


4、讀可讀寫模拟量寄存器(保持寄存器):

計算機發送指令:[裝置位址] [指令号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校驗同上。


5、讀隻可讀模拟量寄存器(輸入寄存器): 

和讀取儲存寄存器類似,隻是第二個位元組的指令号不再是2而是4。


6、寫單個模拟量寄存器(保持寄存器): 

計算機發送指令:[裝置位址] [指令号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>注意此指令一條隻能下置一個模拟量的狀态。

裝置響應:如果成功把計算機發送的指令原樣傳回,否則不響應。
      

繼續閱讀