MODBUS詳解精簡版
一、基本術語
1、 字word、位元組byte、位bit
1 word = 2 byte;
1 byte = 8 bit.
2、 校驗碼
校驗碼是由前面的資料透過某種演算法得出的,用以檢驗該組資料的正確性。程式碼作為資料在向計算機或其它裝置進行輸入時,容易產生輸入錯誤,為了減少這種輸入錯誤,編碼專家發明了各種校驗檢錯方法,並依據這些方法設定了校驗碼。
常用的校驗有:累加和校驗SUM、位元組異或校驗XOR、縱向冗餘校驗LRC、迴圈冗餘校驗CRC……
3、 協議和介面
協議是一種規範和約定,是一種通訊的語言,規定了通訊雙方能夠識別並使用的訊息結構和資料格式。
介面是一種裝置的物理連線,指的是在物理層上的定義,像RS422/RS232/RS485/乙太網口等。協議和介面並不是一個概念,不能混淆。
Modbus協議一般執行在RS485物理介面上,半雙工的,是一種主從協議。
二、Modbus協議概述
Modbus協議是應用於電子控制器上的一種通用語言,實現控制器之間、控制器由網路和其它裝置之間的通訊,支援傳統的RS232/RS422/RS485和最新發展的乙太網裝置。它已經成為一種通用工業標準。有了它,不同廠商生產的控制裝置可以連成工業網路,進行集中控制。此協議定義了一個控制器能認識使用的訊息結構。
Modbus協議是一種請求——應答方式的協議。
三、兩種傳輸方式
1、 ASCII模式
ASCII:美國標準資訊交換程式碼
特點:
① 訊息中每個8bit都作為兩個ASCII字元傳送
② 1個起始位、7個數據位、1個奇偶校驗位和1個停止位(或者兩個停止位)
④ 字元傳送的時間間隔可達到1秒而不會產生錯誤
2、 RTU模式
RTU:遠端終端單元
① 訊息中每個8bit位元組包含兩個4bit的十六進位制字元,因此,在波特率相同的情況下,傳輸效率比ascii傳輸方式大
② 1個起始位、8個數據位、1個奇偶校驗位和1個停止位(或者兩個停止位)
④ 訊息傳送至少要以3.5個字元時間的停頓間隔開始。整個訊息幀必須作為一連續的流傳輸。如果在幀完成之前有超過1.5個字元時間的停頓時間,接收裝置將重新整理不完整的訊息並假定下一個位元組是一個新訊息的地址域。同樣地,如果一個新訊息在小於3.5個字元時間內接著前個訊息開始,接收的裝置將認為它是前一訊息的延續。1.5~3.5個字元間隔就算接收異常,只有超過3.5個字元間隔才認為幀結束。
目前常用的是RTU傳輸方式,因為下面的將以RTU傳輸方式為例.
四、報文格式
讀資料:
下行報文:
從機地址
功能碼
暫存器起始地址高位元組
暫存器起始地址低位元組
讀取暫存器個數高位元組
讀取暫存器個數低位元組
CRC校驗低
CRC校驗高
上行報文:
返回位元組個數
暫存器資料
CRC校驗
寫資料:
暫存器起始地址
寫暫存器個數
要寫的資料
寫入的資料
1、 從機地址範圍:1~247,0為廣播地址,佔一個位元組。
理論上Modbus協議可以接247個從機,但若用於485介面上則由於485介面的限制,在沒有中繼情況下,最多可以接32個從機。
2、功能碼,1~255,佔一個位元組,有些程式碼適用於所有的控制器,有些事應用於某種控制器,還有些保留以備後用。
電力系統中modbus協議的資料主要分為四類:離散量輸入、線圈狀態、輸入暫存器、保持暫存器。離散量輸入對應開入(遙信),線圈狀態對應哪開出(遙控),輸入暫存器對應只讀的模擬量(遙測),保持暫存器對應可讀可寫的模擬量(遙調)。
從機若正常返回,則功能不變,若錯誤返回,則功能碼的最高位為1,且從機會將一獨特的程式碼放到迴應訊息的資料域中,以便於告訴主裝置發生了什麼錯誤。主裝置應用程式得到異議的迴應後,典型的處理過程是重發訊息,或者診斷髮給從裝置的訊息並報告給操作員。如03功能碼,錯誤返回為83。
電力系統中常用功能碼錶
資料型別
讀功能碼
寫功能碼
物件型別
離散量輸入
02
單個位
線圈狀態
01
05,15
輸入暫存器
04
16位字
保持暫存器
03
06,16
上表中是對應資料型別的標準功能碼,但在實際應用中,廠家通常會根據實用性做些變通,但並不影響資料的讀寫。
3、暫存器起始地址
暫存器起始地址佔兩個位元組,高位元組在前,低位元組在後。
Modbus協議中資料模型常用的有兩種,帶有4個獨立塊的modbus資料模型和僅有1個塊的modbus資料模型,對於不同的資料模型引數地址的編制不同。一般採用1個塊的modbus資料模型,如下
引數地址,暫存器編號
00001~0FFFF
10001~1FFFF
30001~3FFFF
40001~4FFFF
Modbus協議中暫存器地址從1開始,而實際儲存中地址從0開始。假如要讀取暫存器編號為40005(4為塊編號,5為modbus中暫存器地址)的暫存器的資料,則應把00 04放入報文的地址域。暫存器定義,又名碼錶或者資訊點表,應由廠家提供的。
舉例:
暫存器編號
屬性
定義
係數
備註
40001
RO
A相電壓
從40048中讀取電壓係數
40002
B相電壓
如要讀A相電壓,則應將0x00 0x00放入暫存器起始地址域中。
4、要讀取的暫存器個數
暫存器個數佔兩個位元組,同樣是高位元組在前,低位元組在後,下行報文使用。
5、資料的位元組數
資料的位元組數,佔一個位元組,上行報文用,不同於暫存器個數。
6、資料域
資料域佔n個位元組,也是高位元組在前,低位元組在後
7、CRC校驗
CRC校驗佔兩個位元組,低位元組在前,高位元組在後
CRC常用函式如下:
unsigned char *puchMsg ;
unsigned short usDataLen ;
unsigned int CRC16(unsigned char puchMsg, unsigned int usDataLen)
{
unsigned char uchCRCHi = 0xFF ;
unsigned char uchCRCLo = 0xFF ;
unsigned uIndex ;
while (usDataLen--)
uIndex = uchCRCHi ^ *puchMsgg++ ;
uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex} ;
uchCRCLo = auchCRCLo[uIndex] ;
}
return (uchCRCHi << 8 | uchCRCLo) ;
設返回值為crc,則將crc>>8和crc&0xff依次放入報文中。這裡將高位元組先入,是因為在crc校驗函式中已經將高低位元組做了調換。
五、報文例項
1、讀40005、40006兩個暫存器,假設從機地址為1
下行報文:01 03 00 04 00 02 85 ca
讀取暫存器個數
00 04
00 02
85 ca
上行報文:01 03 04 00 00 00 00 21 33
暫存器40005資料
暫存器40006資料
00 00
21 33
2、向40005暫存器中寫入0x12,0x34,假設從機地址為1
下行報文:01 06 00 04 00 01 12 34 4a b0
要寫入的資料
00 01
12 34
上行報文:01 06 00 04 00 01 12 34 4a b0
Modbus協議定義的暫存器地址是5位十進位制地址,即:
線圈(DO)地址:00000~09999
觸點(DI)地址:10000~19999
輸入暫存器(AI)地址:30000~39999
輸出暫存器(AO)地址:40000~49999
由於上述各類地址是唯一對應的,因此有些資料就以其第一個數字區分各類地址,
即:0x代表線圈(DO)類地址,1x代表觸點(DI)類地址、 3x代表輸入暫存器(AI)類地址、4x代表輸出暫存器(AO)類地址。
在實際程式設計中,由於字首的區分作用,所以只需說明後4位數,而且需轉換為4位十六進位制地址。
關於 MODBUS 各地址的說明
MODBUS 協議中裝置型別為 0x,1x,3x,4x,5x,6x,
還有 4x_bit,3x_bit 等,下面分別說明這些裝置型別在 MODBUS 協議中支援哪些功能碼。
0x: 是一個可讀可寫的裝置型別,相當於操作 PLC 的輸出點。該裝置型別讀位狀態的時候,發出的功能碼為 01H,寫位狀態的時候發出的功能碼為 05H。
1x:是一個只讀的裝置型別,相當於讀 PLC 的輸入點。讀位狀態的時候發出的功能碼為 02H。
3x: 是一個只讀的裝置型別,相當於讀 PLC 的模擬量。讀資料的時候,發出的功能碼為 04H。
4x:是一個可讀可寫的裝置型別,相當於操作 PLC 的資料暫存器。當讀資料的時候,發出的功能碼是 03H,當寫資料的時候發出的功能碼是 10H。
5x: 該裝置型別與 4x 的裝置型別屬性是一樣的。即發出讀寫的功能碼完全一樣。不同之處在於,當為雙字時,例如 32_bit unsigned 格式的資料,使用 5x 和 4x 兩種裝置型別分別讀取資料時,高字和低字的位置是顛倒的。例如,使用 4x 裝置型別讀到的資料是 0x1234,那麼使用 5x裝置型別讀取的資料是 0x3412。
6x: 是一個可讀可寫的裝置型別,讀資料的時候發出的功能碼也是 03H,與 4x 不同之處在於寫資料的時候,發出的功能碼為 06H,即寫單個暫存器的資料。
3x_bit: 該裝置型別支援的功能碼與 3x 裝置型別完全一致,不同之處是,3x 是讀資料,而3x_bit 是讀資料中的某一個 bit 的狀態。
4x_bit: 該裝置型別支援的功能碼與 4x 裝置型別完全一致,不同之處是,4x 是讀資料,而4x_bit 是讀資料中的某一個 bit 的狀態。
MODBUS詳解精簡版
一、基本術語
1、 字word、位元組byte、位bit
1 word = 2 byte;
1 byte = 8 bit.
2、 校驗碼
校驗碼是由前面的資料透過某種演算法得出的,用以檢驗該組資料的正確性。程式碼作為資料在向計算機或其它裝置進行輸入時,容易產生輸入錯誤,為了減少這種輸入錯誤,編碼專家發明了各種校驗檢錯方法,並依據這些方法設定了校驗碼。
常用的校驗有:累加和校驗SUM、位元組異或校驗XOR、縱向冗餘校驗LRC、迴圈冗餘校驗CRC……
3、 協議和介面
協議是一種規範和約定,是一種通訊的語言,規定了通訊雙方能夠識別並使用的訊息結構和資料格式。
介面是一種裝置的物理連線,指的是在物理層上的定義,像RS422/RS232/RS485/乙太網口等。協議和介面並不是一個概念,不能混淆。
Modbus協議一般執行在RS485物理介面上,半雙工的,是一種主從協議。
二、Modbus協議概述
Modbus協議是應用於電子控制器上的一種通用語言,實現控制器之間、控制器由網路和其它裝置之間的通訊,支援傳統的RS232/RS422/RS485和最新發展的乙太網裝置。它已經成為一種通用工業標準。有了它,不同廠商生產的控制裝置可以連成工業網路,進行集中控制。此協議定義了一個控制器能認識使用的訊息結構。
Modbus協議是一種請求——應答方式的協議。
三、兩種傳輸方式
1、 ASCII模式
ASCII:美國標準資訊交換程式碼
特點:
① 訊息中每個8bit都作為兩個ASCII字元傳送
② 1個起始位、7個數據位、1個奇偶校驗位和1個停止位(或者兩個停止位)
④ 字元傳送的時間間隔可達到1秒而不會產生錯誤
2、 RTU模式
RTU:遠端終端單元
特點:
① 訊息中每個8bit位元組包含兩個4bit的十六進位制字元,因此,在波特率相同的情況下,傳輸效率比ascii傳輸方式大
② 1個起始位、8個數據位、1個奇偶校驗位和1個停止位(或者兩個停止位)
④ 訊息傳送至少要以3.5個字元時間的停頓間隔開始。整個訊息幀必須作為一連續的流傳輸。如果在幀完成之前有超過1.5個字元時間的停頓時間,接收裝置將重新整理不完整的訊息並假定下一個位元組是一個新訊息的地址域。同樣地,如果一個新訊息在小於3.5個字元時間內接著前個訊息開始,接收的裝置將認為它是前一訊息的延續。1.5~3.5個字元間隔就算接收異常,只有超過3.5個字元間隔才認為幀結束。
目前常用的是RTU傳輸方式,因為下面的將以RTU傳輸方式為例.
四、報文格式
讀資料:
下行報文:
從機地址
功能碼
暫存器起始地址高位元組
暫存器起始地址低位元組
讀取暫存器個數高位元組
讀取暫存器個數低位元組
CRC校驗低
CRC校驗高
上行報文:
從機地址
功能碼
返回位元組個數
暫存器資料
CRC校驗
寫資料:
下行報文:
從機地址
功能碼
暫存器起始地址
寫暫存器個數
要寫的資料
CRC校驗
上行報文:
從機地址
功能碼
暫存器起始地址
寫暫存器個數
寫入的資料
CRC校驗
1、 從機地址範圍:1~247,0為廣播地址,佔一個位元組。
理論上Modbus協議可以接247個從機,但若用於485介面上則由於485介面的限制,在沒有中繼情況下,最多可以接32個從機。
2、功能碼,1~255,佔一個位元組,有些程式碼適用於所有的控制器,有些事應用於某種控制器,還有些保留以備後用。
電力系統中modbus協議的資料主要分為四類:離散量輸入、線圈狀態、輸入暫存器、保持暫存器。離散量輸入對應開入(遙信),線圈狀態對應哪開出(遙控),輸入暫存器對應只讀的模擬量(遙測),保持暫存器對應可讀可寫的模擬量(遙調)。
從機若正常返回,則功能不變,若錯誤返回,則功能碼的最高位為1,且從機會將一獨特的程式碼放到迴應訊息的資料域中,以便於告訴主裝置發生了什麼錯誤。主裝置應用程式得到異議的迴應後,典型的處理過程是重發訊息,或者診斷髮給從裝置的訊息並報告給操作員。如03功能碼,錯誤返回為83。
電力系統中常用功能碼錶
資料型別
讀功能碼
寫功能碼
物件型別
離散量輸入
02
單個位
線圈狀態
01
05,15
單個位
輸入暫存器
04
16位字
保持暫存器
03
06,16
16位字
上表中是對應資料型別的標準功能碼,但在實際應用中,廠家通常會根據實用性做些變通,但並不影響資料的讀寫。
3、暫存器起始地址
暫存器起始地址佔兩個位元組,高位元組在前,低位元組在後。
Modbus協議中資料模型常用的有兩種,帶有4個獨立塊的modbus資料模型和僅有1個塊的modbus資料模型,對於不同的資料模型引數地址的編制不同。一般採用1個塊的modbus資料模型,如下
資料型別
引數地址,暫存器編號
離散量輸入
00001~0FFFF
線圈狀態
10001~1FFFF
輸入暫存器
30001~3FFFF
保持暫存器
40001~4FFFF
Modbus協議中暫存器地址從1開始,而實際儲存中地址從0開始。假如要讀取暫存器編號為40005(4為塊編號,5為modbus中暫存器地址)的暫存器的資料,則應把00 04放入報文的地址域。暫存器定義,又名碼錶或者資訊點表,應由廠家提供的。
舉例:
暫存器編號
屬性
定義
係數
備註
40001
RO
A相電壓
從40048中讀取電壓係數
40002
RO
B相電壓
如要讀A相電壓,則應將0x00 0x00放入暫存器起始地址域中。
4、要讀取的暫存器個數
暫存器個數佔兩個位元組,同樣是高位元組在前,低位元組在後,下行報文使用。
5、資料的位元組數
資料的位元組數,佔一個位元組,上行報文用,不同於暫存器個數。
6、資料域
資料域佔n個位元組,也是高位元組在前,低位元組在後
7、CRC校驗
CRC校驗佔兩個位元組,低位元組在前,高位元組在後
CRC常用函式如下:
unsigned char *puchMsg ;
unsigned short usDataLen ;
unsigned int CRC16(unsigned char puchMsg, unsigned int usDataLen)
{
unsigned char uchCRCHi = 0xFF ;
unsigned char uchCRCLo = 0xFF ;
unsigned uIndex ;
while (usDataLen--)
{
uIndex = uchCRCHi ^ *puchMsgg++ ;
uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex} ;
uchCRCLo = auchCRCLo[uIndex] ;
}
return (uchCRCHi << 8 | uchCRCLo) ;
}
設返回值為crc,則將crc>>8和crc&0xff依次放入報文中。這裡將高位元組先入,是因為在crc校驗函式中已經將高低位元組做了調換。
五、報文例項
1、讀40005、40006兩個暫存器,假設從機地址為1
下行報文:01 03 00 04 00 02 85 ca
從機地址
功能碼
暫存器起始地址
讀取暫存器個數
CRC校驗
01
03
00 04
00 02
85 ca
上行報文:01 03 04 00 00 00 00 21 33
從機地址
功能碼
返回位元組個數
暫存器40005資料
暫存器40006資料
CRC校驗
01
03
04
00 00
00 00
21 33
2、向40005暫存器中寫入0x12,0x34,假設從機地址為1
下行報文:01 06 00 04 00 01 12 34 4a b0
從機地址
功能碼
暫存器起始地址
讀取暫存器個數
要寫入的資料
CRC校驗
01
03
00 04
00 01
12 34
85 ca
上行報文:01 06 00 04 00 01 12 34 4a b0
從機地址
功能碼
暫存器起始地址
讀取暫存器個數
寫入的資料
CRC校驗
01
03
00 04
00 01
12 34
85 ca
Modbus協議定義的暫存器地址是5位十進位制地址,即:
線圈(DO)地址:00000~09999
觸點(DI)地址:10000~19999
輸入暫存器(AI)地址:30000~39999
輸出暫存器(AO)地址:40000~49999
由於上述各類地址是唯一對應的,因此有些資料就以其第一個數字區分各類地址,
即:0x代表線圈(DO)類地址,1x代表觸點(DI)類地址、 3x代表輸入暫存器(AI)類地址、4x代表輸出暫存器(AO)類地址。
在實際程式設計中,由於字首的區分作用,所以只需說明後4位數,而且需轉換為4位十六進位制地址。
關於 MODBUS 各地址的說明
MODBUS 協議中裝置型別為 0x,1x,3x,4x,5x,6x,
還有 4x_bit,3x_bit 等,下面分別說明這些裝置型別在 MODBUS 協議中支援哪些功能碼。
0x: 是一個可讀可寫的裝置型別,相當於操作 PLC 的輸出點。該裝置型別讀位狀態的時候,發出的功能碼為 01H,寫位狀態的時候發出的功能碼為 05H。
1x:是一個只讀的裝置型別,相當於讀 PLC 的輸入點。讀位狀態的時候發出的功能碼為 02H。
3x: 是一個只讀的裝置型別,相當於讀 PLC 的模擬量。讀資料的時候,發出的功能碼為 04H。
4x:是一個可讀可寫的裝置型別,相當於操作 PLC 的資料暫存器。當讀資料的時候,發出的功能碼是 03H,當寫資料的時候發出的功能碼是 10H。
5x: 該裝置型別與 4x 的裝置型別屬性是一樣的。即發出讀寫的功能碼完全一樣。不同之處在於,當為雙字時,例如 32_bit unsigned 格式的資料,使用 5x 和 4x 兩種裝置型別分別讀取資料時,高字和低字的位置是顛倒的。例如,使用 4x 裝置型別讀到的資料是 0x1234,那麼使用 5x裝置型別讀取的資料是 0x3412。
6x: 是一個可讀可寫的裝置型別,讀資料的時候發出的功能碼也是 03H,與 4x 不同之處在於寫資料的時候,發出的功能碼為 06H,即寫單個暫存器的資料。
3x_bit: 該裝置型別支援的功能碼與 3x 裝置型別完全一致,不同之處是,3x 是讀資料,而3x_bit 是讀資料中的某一個 bit 的狀態。
4x_bit: 該裝置型別支援的功能碼與 4x 裝置型別完全一致,不同之處是,4x 是讀資料,而4x_bit 是讀資料中的某一個 bit 的狀態。