讀寫型記憶體-讀取指令(03)
當數值較大時,若分別以不同資料格式(例如 float32 或 int64)進行讀取與換算,因內部計算方式不同,可能會出現非常小的差異,通常小於 1/10,000,屬於正常現象。
不同參數大分類不能跨區讀取,一次最多40 個register 長度。超過該長度的指令會被忽略。
Function Code 功能碼 03
讀寫型記憶體 讀取指令,功能碼 (Function Code) 03 ,數據長度為1~125 個暫存器。可讀取單個或多個保持暫存器,用於讀取設備中定義之保持暫存器(Holding Registers)內的設定參數。
讀寫型記憶體-控制端發指令(03)格式


Modbus RTU 讀取讀寫型記憶體保持暫存器 (03) 範例
以主站使用功能碼 03 讀取 A02 Preset Pipe Spec 為例:
根據設備規格,起始暫存器位置為 00 00,欲讀取暫存器數量為 3(每個暫存器 2 bytes,共 6 bytes),資料型式皆為 int16(16 位元整數),位元組順序為 Big Endian。
主站將透過 Modbus RTU 協議發送讀取指令,從站(流量計)回覆對應的數據。
主站發送讀取指令 (TX 訊框)
slave address: 01(本流量計地址)
function code: 03(讀取指令)
讀取數據的啟始地址: 00 00(要讀取A02 Preset Pipe Spec的數據的啟始地址)
讀取registers 總數: 00 03(從 00 00 開始讀三個 register 的記憶體)
CRC: 05 CB (依 CRC 算法計算出的糾錯碼)
流量計回覆(03)格式
流量計回覆範例說明
slave address: 01(本流量計地址)
function code: 03(讀取指令)
回覆的Byte數: 06(3個register=6byte)
Data Byte:
00 06 (目前型態選項astm sch 80 pvc)
00 00 (讀取A02 RS485 init)
42 41 (讀取A02 RS485 init)
CRC: 59 E5 (依 CRC 算法計算出的糾錯碼)
常見問題
為什麼「記憶體列表」和「PLC 讀取位置」位置會有差異?
使用者可能遇到以下情況:記憶體列表位置為 40005,但在 PLC 端需填入 4(或顯示為 0004)才能讀到需求數值。
這是因為Modbus 位址表示方式的特性,根據Modbus定義,人看的位址(文件/記憶體表)與設備實際讀取的位址(通訊位置)兩者中間會存在一個「偏移量 offset」。
功能碼03的邏輯為:將「40001」作為基底,讀取時,從這裡開始計數,40001 代表第 1 個寄存器,偏移量是0000,讀取位置是0000。

因此當文件標示要讀取 40005 時,對應的 Modbus 功能碼 03 封包中的 實際起始位址為 0004,也就是:實際通訊位址 = 文件位址 − 40001。
註:Modbus 協定本身規範採 0-based addressing(實際通訊封包會從 0 開始編號),因此理論通則為:「實際通訊位址 = 文件位址−40001」
不過,若客戶端使用的 PLC 或 HMI 軟體 有特別設定為 1-based addressing(軟體自動將位址加 1),此時就需要依照軟體的位址規則來填入起始位址,讀取暫存器數據。
Last updated