MODBUS_RTU協議:是指國際上通用的 MODBUS_RTU議。以后簡稱MODBUS協議。詳見《MODBUS協議中文版》官方文檔。
JM_MOD協議:是指完全在遵循MODBUS_RTU 協議的規則下,為了適應某些捷麥公司的設備和應用場景對MODBUS_RTU協議做了更細致定義的協議。 支持JM_MOD協議的設備或軟件接口可與任何標準MODBUS主機或設備直接通信。
JM_BUS協議:是指基于JM_MOD協議,為了 適應遠程測控一個站點的各種數據一次采集的特性做了相應改動的協議。此協議不遵循MODBUS_RTU, 不能與標準MODBUS主機或設備直接通信。詳見《JMBUS協議說明》。
本協議適用于JM公司所有標明“支持MODBUS協議”的硬件設 備和應用軟件。例如T40S無線PLC、KZ04擴展模塊、遠程通PC組態和遠程通手機組態等。
JM_MOD的數據通信指令為標準的MODBUS_RTU協議,以下為 MODBUS的基本協議規范。
圖1. 通用的MODBUS幀
圖2:MODBUS事務處理(無差錯)
圖3:MODBUS事務處理(異常響應)
下文中,講接收數據并處理響應的“服務器”稱之 為“MODBUS從機”。
JM_MOD 使用一個‘big-Endian’ 表示地址和數據項。這意 味著當發射多個字節時,首先發送最高有效位。例如:
寄存器大小 | 值 | |
16-比特 | 0x1234 | 發送的第一字節為0x12然后0x34 |
同樣的道理,如果傳送實數數據時,首先發送最高有效位, 最后發送最低位(組態軟件中的HV1 HV2 HV3 HV4)。
特例:起始地址為330001和430001的浮點型數據內容是小端模式,組態軟件中的HV4 HV3 HV2 HV1。
JM_MOD以一系列具有不同特征的數據模型為基礎。幾個基本數據模型為:
基本類型 | 對象類型 | 屬性 | 內容 | 常用符號 |
離散量輸入 | 單個bit | 只讀 | I/O 系統提供數據 | DI、I*.* |
線圈 | 單個bit | 讀寫 | 通過應用程序改變數據 | DO、Q*.* |
整數輸入存儲區 | 16bit | 只讀 | I/O 系統提供數據 | -- |
字節輸入存儲區 | 8bit | 只讀 | I/O 系統提供數據 | -- |
實數輸入存儲區 | 32bit | 只讀 | I/O 系統提供數據 | AI |
整數保持存儲區 | 16bit | 讀寫 | 通過應用程序改變數據 | -- |
字節保持存儲區 | 8bit | 讀寫 | 通過應用程序改變數據 | V |
實數保持存儲區 | 32bit | 讀寫 | 通過應用程序改變數據 | AQ |
由于MODBUS協議中沒有所有的字節和實數的定義,而只有一個籠統的“04輸入寄存器和03/06/10保持寄存器”的說法。在JM_MOD協議中需要在借用MODBUS協議中的偏移地址的最高位的值和命令碼來區分設備中的不同存儲區,詳見下一章節。
定義匯總,字節和實數部分本文說明,離散和整數部分在“上篇”中說明。
存儲區名稱 | 意義 | 功能碼 | 地址(標準表示) | 數據類型 | 傳輸形式 |
離散輸入 | 讀離散輸入 | 02 | 0 (10001) | bit | bit |
離散輸出 | 讀離散輸出 | 01 | 0 (00001) | bit | bit |
寫單個離散輸出 | 05 | 0 (00001) | bit | bit | |
寫多個離散輸出 | 0x0F | 0 (00001) | bit | bit | |
字節輸入 | 讀字節輸入 | 04 | 10000 (310001) | 16bit | 16bit |
字節輸出 | 讀字節輸出 | 03 | 10000 (410001) | 16bit | 16bit |
寫單個字節輸出 | 06 | 10000 (410001) | 16bit | 16bit | |
寫多個字節輸出 | 0x10 | 10000 (410001) | 16bit | 16bit | |
整數輸入 | 讀整數輸入 | 04 | 0 (30001) | 8bit | 16bit |
整數輸出 | 讀整數輸出 | 03 | 0 (30001) | 8bit | 16bit |
寫單個整數輸出 | 06 | 0 (30001) | 8bit | 16bit | |
寫多個整數輸出 | 0x10 | 0 (30001) | 8bit | 16bit | |
實數輸入 | 讀實數輸入 | 04 | 30000 (330001) | 32bit | 16bit |
實數輸出 | 讀實數輸出 | 03 | 30000 (430001) | 32bit | 16bit |
寫單個實數輸出 | 06 | 30000 (430001) | 32bit | 16bit | |
寫多個實數輸出 | 0x10 | 30000 (430001) | 32bit | 16bit |
這個功能代碼是用來讀MODBUS從機相鄰的字節(8bit)輸入 存儲區單元。請求協議數據單元詳細說明了寄存器的起始地址和讀出數量。每個存儲區單元占1個字 節。正常的響應會返回功能代碼,讀出的寄存器的數量及內容。
字節輸入存儲區的開始偏移地址:10000 (1388H)
請求協議數據單元
功能代碼 | 1字節 | 04H |
起始地址 | 2字節 | 2710H到7530H |
*寄存器個數 (字節存儲區2倍) | 2字節 | 0001H-007DH |
*寄存器個數:由于字節輸入存儲區單元占1個字節,而標準 MODBUS協議中讀輸入寄存器采用2個字節,因此此處的寄存器個數是指是讀取了兩倍的字節寄存器數 量。例如在協議中寄存器個數為2,表示要讀取4個字節存儲區單元。
響應協議數據單元
功能代碼 | 1字節 | 04H |
字節數 | 1 個字節 | *N |
寄存器的內容 | *N 個字節 |
*N=輸入字節寄存器的數量
注意:由于每個字節存儲區單元占用一個字節,而MODBUS讀輸入寄存器是兩個字節,因此,每一個 偏移地址對應著兩個字節存儲區單元,由于字節存儲區的開始偏移地址是從10000(2710H)開始的, 因此偏移地址10000就是字節存儲區的1和2,偏移地址N就是字節存儲區(N-10000)*2+1和字節存儲區 (N-10000)*2+2。從這個定于可以看出,一次至少可讀取兩個字節存儲區單元。
下例是從字節輸入存儲區3開始讀4個存儲區單元,讀取的內 容為00 0A和01 02。
請求 | 響應 | ||
字段名稱 | (Hex) | 字段名稱 | (Hex) |
功能 | 04 | 功能 | 04 |
起始地址高位 | 27 | 字節數 | 04 |
起始地址低位 | 11 | 單元3 | 00 |
寄存器個數高位 | 00 | 單元4 | 0A |
寄存器個數低位 | 02 | 單元5 | 01 |
單元6 | 02 |
這個功能代碼是用來讀MODBUS從機相鄰的字節(8bit)輸出 存儲區單元。請求協議數據單元詳細說明了寄存器的起始地址和讀出數量。每個存儲區單元占1個字 節。正常的響應會返回功能代碼,讀出的寄存器的數量及內容。
字節輸出存儲區的開始偏移地址:10000 (2710H)
請求協議數據單元
功能代碼 | 1字節 | 03H |
起始地址 | 2字節 | 2710H到7530H |
*寄存器個數 (字節存儲區2倍) | 2字節 | 0001H-007DH |
*寄存器個數:由于字節輸出存儲區單元占1個字節,而標準 MODBUS協議中讀輸出寄存器采用2個字節,因此此處的寄存器個數是指是讀取了兩倍的字節寄存器數 量。例如在協議中寄存器個數為2,表示要讀取4個字節存儲區單元。
響應協議數據單元
功能代碼 | 1字節 | 03H |
字節數 | 1 個字節 | *N |
寄存器的內容 | *N 個字節 |
*N=輸出字節寄存器的數量
注意:由于每個字節存儲區單元占用一個字節,而MODBUS讀輸出寄存器是兩個字節,因此,每一個 偏移地址對應著兩個字節存儲區單元,由于字節存儲區的開始偏移地址是從10000(2710H)開始的, 因此偏移地址10000就是字節存儲區的1和2,偏移地址N就是字節存儲區(N-10000)*2+1和字節存儲區 (N-10000)*2+2。從這個定義可以看出,一次至少可讀取兩個字節存儲區單元。
下例是從字節輸出存儲區3開始讀4個存儲區單元,讀取的內 容為00 0A和01 02。
請求 | 響應 | ||
字段名稱 | (Hex) | 字段名稱 | (Hex) |
功能 | 03 | 功能 | 03 |
起始地址高位 | 27 | 字節數 | 04 |
起始地址低位 | 11 | 單元3 | 00 |
寄存器個數高位 | 00 | 單元4 | 0A |
寄存器個數低位 | 02 | 單元5 | 01 |
單元6 | 02 |
這個功能代碼是用來寫MODBUS從機兩個字節(8bit)輸出存 儲區單元。請求協議數據單元詳細說明了寄存器的起始地址、數值。每個存儲區單元占1個字節。正 常的響應會返回功能代碼、起始地址和寄存器數值。
*兩個字節輸出存儲單元:由于字節輸出存儲區單元占1個字 節,而標準MODBUS協議中寫輸出寄存器采用2個字節。所以對于MOD-BUS06指令為寫單個寄存器,到這 里就成了寫兩個字節輸出寄存器。
字節輸出存儲區的開始偏移地址:10000(2710H)
請求協議數據單元
功能代碼 | 1字節 | 06H |
起始地址 | 2字節 | 2710H到7530H |
數據 | 2字節 | 0-FFFFH值 |
響應協議數據單元
功能代碼 | 1字節 | 06H |
起始地址 | 2字節 | 2710H到7530H |
數據 | 2字節 | 0-FFFFH值 |
注意:由于每個整數存儲區單元占用兩個字節,而MODBUS讀輸出寄存器也是兩個字節,因此,每一 個偏移地址正好一一對應著每個整數存儲區單元,由于整數存儲區的開始偏移地址是從0000H開始的 ,因此偏移地址00就是整數存儲區單元1,偏移地址N就是整數存儲區單元N+1。
下面這個例子是寫從字節輸出寄存器3開始的內容為00、 03 :
請求 | 響應 | ||
字段名稱 | (Hex) | 字段名稱 | (Hex) |
功能 | 06 | 功能 | 06 |
起始地址高位 | 27 | 起始地址高位 | 13 |
起始地址低位 | 11 | 起始地址低位 | 89 |
寄存器值高位 | 00 | 寄存器值高位 | 00 |
寄存器值低位 | 03 | 寄存器值低位 | 03 |
這個功能代碼是用來寫MODBUS從機相鄰的字節(8bit)輸出 存儲區單元。請求協議數據單元詳細說明了寄存器的起始地址、數量和內容。每個存儲區單元占1個 字節。正常的響應會返回功能代碼和起始地址。
字節輸出存儲區的開始偏移地址:10000 (2710H)
請求協議數據單元
功能代碼 | 1字節 | 10H |
起始地址 | 2字節 | 2710H到7530H |
寄存器個數 (字節存儲區2倍) | 2字節 | 0001H-007DH |
字節數 | 1字節 | *N |
數據 | *N | 值 |
*N=輸出字節寄存器的數量
響應協議數據單元
功能代碼 | 1字節 | 10H |
起始地址 | 2字節 | 2710H到7530H |
寄存器個數 | 2字節 | 0001H-007DH |
注意:由于字節寄存器占用一個字節,而MODBUS寫輸出寄存器是兩個字節,因此,每一個偏移地址 對應著兩個字節寄存器,由于整數存儲區的開始偏移地址區從10000(2710H)開始的,因此偏移地址 10000就是字節寄存器1和2,偏移地址N就是字節存儲區(N-10000)*2+1和字節存儲區(N-10000)*2+2。 從這個定于可以看出,寫字節輸出存儲區一次至少寫兩個。
下面這個例子是寫從字節輸出寄存器3開始的內容為00、 0A 、01和 02到存儲區中:
請求 | 響應 | ||
字段名稱 | (Hex) | 字段名稱 | (Hex) |
功能 | 10 | 功能 | 10 |
起始地址高位 | 27 | 起始地址高位 | 00 |
起始地址低位 | 11 | 起始地址低位 | 01 |
寄存器個數高位 | 00 | 寄存器個數高位 | 00 |
寄存器個數低位 | 02 | 寄存器個數低位 | 02 |
字節數 | 04 | ||
單元3 | 00 | ||
單元4 | 0A | ||
單元5 | 01 | ||
單元6 | 02 |
這個功能代碼是用來讀MODBUS從機相鄰的實數(32bit)輸入 存儲區單元。請求協議數據單元詳細說明了寄存器的起始地址和讀出數量。每個寄存器為4個字節。 正常的響應會返回功能代碼,讀出的寄存器的數量及內容。
實數輸入存儲區的開始偏移地址:30000 (7530H)
請求協議數據單元
功能代碼 | 1字節 | 04H |
起始地址 | 2字節 | 7530H到9C40H |
*寄存器個數 (實數存儲區單元個數1/2) | *2字節 | 0001H-007DH |
*寄存器個數:由于每個實數輸入存儲區單元占4個字節,而 標準MODBUS協議中讀輸入寄存器采用2個字節,因此此處的每一個寄存器個數是指是讀取半個實數存 儲區單元的數量。例如在協議中寄存器個數為2,表示要讀取1個實數存儲區單元。
響應協議數據單元
功能代碼 | 1字節 | 04H |
字節數 | 1 個字節 | *N ×4 |
寄存器的內容 | *N×4 個字節 |
*N=輸入實數寄存器的數量
注意:由于每個實數儲存單元占用4個字節,而MODBUS讀輸入寄存器是兩個字節,因此,每兩個偏 移地址對應著一個實數存儲區單元,由于實數存儲區的開始偏移地址從30000(7530H)開始的,因此 偏移地址30000和30001就是實數存儲區0,偏移地址N(N為偶數)就是實數存儲區(N-30000)/2+1。從 這個定于可以看出,讀實數輸入存儲區必須是從偏移地址是偶數位置開始的(0,2,4,6…)。
下例是從實數輸入存儲區單元2開始讀1個單元,值內容為 3.14(C3 F5 48 40) ( 40 48 F5 C3)
請求 | 響應 | ||
字段名稱 | (Hex) | 字段名稱 | (Hex) |
功能 | 04 | 功能 | 04 |
起始地址高位 | 75 | 字節數 | 04 |
起始地址低位 | 34 | 單元2-1/4 | C3 |
寄存器個數高位 | 00 | 單元2-2/4 | F5 |
寄存器個數低位 | 02 | 單元2-3/4 | 48 |
單元2-4/4 | 40 |
這個功能代碼是用來讀MODBUS從機相鄰的實數(32bit)輸出 存儲區單元。請求協議數據單元詳細說明了寄存器的起始地址和讀出數量。每個寄存器為4個字節。 正常的響應會返回功能代碼,讀出的寄存器的數量及內容。
實數輸出存儲區的開始偏移地址:30000 (7530H)
請求協議數據單元
功能代碼 | 1字節 | 03H |
起始地址 | 2字節 | 7530H到9C40H |
*寄存器個數 (實數存儲單元個數1/2) | *2字節 | 0001H-007DH |
*寄存器個數:由于每個實數輸出存儲區單元占4個字節,而 標準MODBUS協議中讀輸出寄存器采用2個字節,因此此處的每一個寄存器個數是指是讀取半個實數存 儲區單元的數量。例如在協議中寄存器個數為2,表示要讀取1個實數存儲區單元。
響應協議數據單元
功能代碼 | 1字節 | 03H |
字節數 | 1 個字節 | *N ×4 |
寄存器的內容 | *NX4個字節 |
*N=輸出實數寄存器的數量
注意:由于每個實數儲存單元占用4個字節,而MODBUS讀輸出寄存器是兩個字節,因此,每兩個偏 移地址對應著一個實數存儲區單元,由于實數存儲區的開始偏移地址從30000(7530H)開始的,因此 偏移地址30000和30001就是實數存儲區0,偏移地址N(N為偶數)就是實數存儲區(N-30000)/2+1。從 這個定于可以看出,讀實數輸出存儲區必須是從偏移地址是偶數位置開始的(0,2,4,6…)。
下例是從實數輸出存儲區單元2開始讀1個單元,值內容為 3.14(C3 F5 48 40)
請求 | 響應 | ||
字段名稱 | (Hex) | 字段名稱 | (Hex) |
功能 | 03 | 功能 | 03 |
起始地址高位 | 75 | 字節數 | 04 |
起始地址低位 | 34 | 單元2-1/4 | C3 |
寄存器個數高位 | 00 | 單元2-2/4 | F5 |
寄存器個數低位 | 02 | 單元2-3/4 | 48 |
單元2-4/4 | 40 |
這個功能代碼是用來寫MODBUS從機相鄰的實數(32bit)輸出 存儲區單元。請求協議數據單元詳細說明了寄存器的起始地址、數量和內容。每個寄存器為4個字節 。正常的響應會返回功能代碼和起始地址。
實數輸出存儲區的開始偏移地址:30000 (7530H)
請求協議數據單元
功能代碼 | 1字節 | 10H |
起始地址 | 2字節 | 7530H到9C40H |
寄存器個數 (實數存儲單元個數1/2) | 2字節 | 0001H-007DH |
字節數 | 1字節 | *N×4 |
數據 | *N | 值 |
*寄存器個數:由于每個實數輸出存儲區單元占4個字節,而 標準MODBUS協議中寫輸出寄存器采用2個字節,因此此處的每一個寄存器個數是指是寫半個實數存儲 區單元的數量。例如在協議中寄存器個數為2,表示要寫1個實數存儲區單元。
響應協議數據單元
功能代碼 | 1字節 | 10H |
起始地址 | 2字節 | 7530H到9C40H |
寄存器個數 | 2字節 | 0001H-007DH |
注意:由于每個實數儲存單元占用4個字節,而MODBUS寫輸出寄存器是兩個字節,因此,每兩個偏 移地址對應著一個實數存儲區單元,由于實數存儲區的開始偏移地址從30000(7530H)開始的,因此 偏移地址30000和30001就是實數存儲區0,偏移地址N(N為偶數)就是實數存儲區(N-30000)/2+1。從 這個定于可以看出,讀實數輸出存儲區必須是從偏移地址是偶數位置開始的(0,2,4,6…)。
下例是寫內容為3.14(C3 F5 48 40)到實數輸出存儲區單元 2開始的存儲區中:
請求 | 響應 | ||
字段名稱 | (Hex) | 字段名稱 | (Hex) |
功能 | 10 | 功能 | 10 |
起始地址高位 | 75 | 起始地址高位 | 75 |
起始地址低位 | 32 | 起始地址低位 | 32 |
寄存器個數高位 | 00 | 寄存器個數高位 | 00 |
寄存器個數低位 | 02 | 寄存器個數低位 | 02 |
字節數 | 04 | ||
數據值VOD2高字節 | C3 | ||
數據值VOD2低字節 | F5 | ||
數據值VOD3高字節 | 48 | ||
數據值VOD3低字節 | 40 |