Modbus 異常な応答码与故障トラブルシューティング完全手册:从 01 to 11 完全に。解析

freeFree Technical Resource

This content is free to read, suitable for basic learning and search traffic.

Modbus 異常な応答码与故障トラブルシューティング完全手册:从 01 to 11 完全に。解析

关键词:Modbus Exception Code、Modbus 故障トラブルシューティング、Modbus エラー·コード、Modbus Exception Code、Modbus 通信故障

在工业自動化现场,Modbus 通信故障是最让エンジニア头疼的問題之一。当マスター发出リクエスト后,スレーブ戻る的ではない正常データ,而是一个「Exception Response」——这表明通信链路ない問題,但业务逻辑层出现了エラー。理解每一个異常コード。的含义、触发条件和トラブルシューティング方法,是每一位自動化エンジニア的必修课。

本記事将从 Modbus protocol specification(V1.1b3)出发,结合真实工业现场案例,深入解析すべて 11 个標準異常コード。的触发机制、トラブルシューティング流程和ソリューション。无论您是初次接触 Modbus 的新手,まだ希望系统化梳理知识的老兵,都能从本記事中找到实用的参照。

一、Modbus 異常な応答的基本机制

Modbus 異常な応答码与故障トラブルシューティング完全手册:从 01 to 11 完全に。解析イラスト
▲ 图1:正常リクエストフレーム与異常な応答フレーム形式对比。異常时機能コード最高位置1(+0x80),紧跟1バイト異常コード。。

1.1 普通の反応 vs Exception Response

在 Modbus protocol中,master(Master/Client)向スレーブ(Slave/Server)リクエストの送信报文,スレーブ処理后戻るレスポンス报文。当一切正常时,レスポンス的機能コード与リクエスト的機能コード完全一致:

Request: [slave address] [function code 0x03] [開始アドレスハイバイト] [開始アドレス低バイト数] [レジスタの数ハイバイト] [レジスタの数低バイト数] [CRC低] [CRC高]
普通の反応: [slave address] [function code 0x03] [byte count] [data...] [CRC低] [CRC高]

当スレーブ无法正常処理リクエスト时,它会将機能コード的最高位(bit 7)置为 1,并在データ区放入一バイト単位。的異常コード。。也就是说,異常な機能コード = リクエスト機能コード + 0x80。例如,リクエスト機能コード 0x03 出现異常时,レスポンス機能コード变为 0x83。

異常な応答报文構造(RTU モード):
[slave address] [function code+0x80] [Exception Code] [CRC低] [CRC高]

example - リクエスト不存在的レジスター·アドレス:
Request: 01 03 27 10 00 01 [CRC]
Exception Response: 01 83 02 [CRC]  
→ function code 0x83 = 0x03 + 0x80,Exception Code 0x02 = Illegal data address

1.2 異常な応答的判断逻辑

Modbus 異常な応答码与故障トラブルシューティング完全手册:从 01 to 11 完全に。解析イラスト1
▲ 图2:通信故障トラブルシューティング决策树 — 从物理層は到アプリケーション層的系统化诊断流程。

当您在デバッグツール(如 Modbus Poll、ModScan)中看到ステーションからのデータ时,判断は、否为異常な応答非常简单:

  1. 表示レスポンス機能コード是否大于 0x80(即最高位为 1)
  2. もし機能コード > 0x80,则第二バイト単位。即为異常コード。
  3. 根据異常コード。查表确定エラータイプ

在プログラミング実装中,检测逻辑如下:

// C 语言異常な応答检测サンプル
if (response_function_code & 0x80) {
    uint8_t exception_code = response_data[0];
    switch (exception_code) {
        case 0x01: // 違法な機能コード
        case 0x02: // Illegal data address
        case 0x03: // Illegal data value
        // ... 其他異常コード。処理
    }
}

二、11 个標準異常コード。完全解析

Modbus protocol specification定义了 11 个標準異常コード。(0x01 ~ 0x0B)。下面逐一深度解析每个異常コード。的含义、触发条件、典型场景和トラブルシューティング方法。

Exception Code 0x01 — Illegal function(Illegal Function)

Modbus 異常な応答码与故障トラブルシューティング完全手册:从 01 to 11 完全に。解析イラスト2
▲ 图3:8种標準異常なスピードチェック表 — 一表掌握すべての異常原因与ソリューション。

含义:スレーブサポートなし。リクエスト的機能コード。这是最も一般的な的異常コード。之一,通常发生在マスター使用了スレーブ未実装的機能コード时。

典型触发场景:

  • 機能コード超出範囲:マスター送信了機能コード 0x14(ファイルレコードの読み取り),但スレーブ只実装了 0x03、0x04、0x06、0x10
  • PLC 型号サポートなし。:部分低端 PLC 只サポート 0x03 和 0x06,尝试使用 0x10(write multiple registers)会戻る 0x01
  • デバイス構成エラー:某些デバイス的 Modbus 実装経由設定开关有効/無効機能コード,もし对应功能被無効,同样戻る 0x01
  • ゲートウェイ转换問題:Modbus TCP to RTU 的ゲートウェイ可能サポートなし。某些機能コード的透传

手順の確認:

  1. 查阅デバイス手册,確認スレーブサポート哪些機能コード
  2. 使用 Modbus Poll 等工具逐一测试機能コード,缩小問題範囲
  3. チェックGateway/Converter的機能コード过滤設定
  4. もし使用自研程序,確認機能コード常量定义是否正确

实际案例:某水処理项目中,トップマシン使用機能コード 0x17(读/write multiple registers)操作シュナイダー PM800 パワーメーター,始终例外コードを返す 0x01。经マニュアルを参照。发现 PM800 只サポート 0x03 和 0x10。ソリューション:拆分为先 0x03 read、再 0x10 写入两步操作。

Exception Code 0x02 — Illegal data address(Illegal Data Address)

含义:リクエスト的レジスター·アドレス在スレーブ中不存在。这是エンジニア在デバッグ阶段最容易遇到的異常コード。。

典型触发场景:

  • アドレス偏移エラー:PLC 的 Modbus アドレス通常从 0 开始,但トップマシン設定时可能填了 1 起始的アドレス
  • レジスタ範囲越界:リクエスト的開始アドレス + 数量超出了スレーブ的最大レジスタ範囲
  • アドレスマッピングエラー:一部のデバイス使用不同的アドレスマッピングテーブル(如一部のデバイス 40001 对应内部アドレス 0,一部の对应 1)
  • データ型混淆:32 ビット浮動小数点数占用 2 Registers,もし只リクエスト 1 Registers,可能触发越界

手順の確認:

  1. 使用 0x03 function code,住所から。 0 开始逐一読み取り,确定有效アドレス範囲
  2. 機器の確認手册中的アドレス是「プロトコルアドレス」まだ「PLC address」——两者可能相差 1
  3. 对于 32 ビット·データ,确保リクエスト的レジスタの数为偶数
  4. チェック报文中アドレス的大リトルエンディアンバイトオーダー是否正确

Exception Code 0x03 — Illegal data value(Illegal Data Value)

含义:リクエスト中的数值在スレーブ的允许範囲之外。这不涉及アドレス問題,而是「值」的問題。

典型触发场景:

  • 値の書き込み超出範囲:温度の設定值範囲为 0~100°C,但メインステーション書き込み了 150
  • レジスタの数不合法:0x10 機能コード的「number of registers」字段为 0 或超过了スレーブ单次可処理的最大值(通常为 123)
  • Bytesの数不マッチング:0x10 機能コード的「byte count」字段与「number of registers × 2」不一致
  • 报文長さエラー:整个报文的实际長さ与报头中声明の長ささ不符

手順の確認:

  1. 重点チェック 0x10(write multiple registers)的报文構造——这是最容易出错的场景
  2. 验证「byte count = number of registers × 2」是否成立
  3. 確認値の書き込み是否在デバイス手册规定的範囲内
  4. 对于 0x06(write single register),チェック値の書き込み的範囲(0x0000 ~ 0xFFFF)

Exception Code 0x04 — Substation equipment malfunction(Slave Device Failure)

含义:スレーブ在処理リクエスト时发生了不可恢复的内部エラー。这是一个「万金油」Exception Code,表示スレーブ自身出现了严重問題。

典型触发场景:

  • EEPROM/Flash 写入失敗:スレーブ将設定写入非易失性存储器时失敗
  • センサーは故障:スレーブ连接的センサーは损坏,无法提供有效读数
  • 内部通信故障:スレーブ内部的主控芯片与外设之间的通信異常
  • 文件系统エラー:涉及文件操作的機能コード(0x14、0x15)遇到文件系统異常

手順の確認:

  1. チェックスレーブデバイス的电源是否稳定
  2. 表示スレーブ的 LED 指示灯ステータス(通常有故障灯)
  3. 尝试对スレーブ进行電源オフと再起動
  4. 联系デバイス厂商取得诊断工具或ファームウェアアップグレード

Exception Code 0x05 — Confirm(Acknowledge)

含义:スレーブ已经接受リクエスト,但需要较长时间来処理。这ではない一个エラー,而是一个「请稍候」的信号。スレーブ正在执行操作,処理完成后会戻る普通の反応。

典型触发场景:

  • EEPROM 写入耗时较长:某些デバイス的非易失性存储器写入可能需要数百毫秒
  • ファームウェアアップグレード操作:写入程序存储器需要较长时间
  • 电机执行动作:スレーブ正在执行物理动作(如阀门开关)

プログラミング建议:マスター異常コードを受信 0x05 后,不应立即重试或报错,而应待機中适当时间后重新ポーリング。建议使用ステータス机処理:

// 异步処理確認レスポンス的ステータス机
enum { IDLE, WAITING, POLLING } state = IDLE;

void modbus_handler(uint8_t func, uint8_t* data) {
    if (func & 0x80) {
        if (data[0] == 0x05) {
            state = POLLING;
            start_poll_timer(500); // 500ms 后重新查询
        }
    }
}

Exception Code 0x06 — The slave station equipment is busy(Slave Device Busy)

含义:スレーブ処理中です。一个耗时较长的命令,暂时无法レスポンス新的リクエスト。与 0x05 違いはありません在于:0x05 是「我在処理你刚发的リクエスト」,0x06 是「我现在没空処理任何リクエスト」。

典型触发场景:

  • スレーブ在执行耗时操作:如ファームウェアアップグレード、大量データ拷贝
  • slave CPU 負荷过高:硬件性能有限,无法及时処理 Modbus Request
  • スレーブ正在进行自诊断:部分デバイス在启动时会执行自检,期间不レスポンス通信

手順の確認:

  1. 适当增加マスター的ポーリング間隔(如从 100ms 增加到 500ms)
  2. 减少同时通信的スレーブ数量
  3. チェックスレーブ的固件版本,確認ありますか?已知的性能問題

Exception Code 0x07 — 否定確認(Negative Acknowledge)

含义:スレーブ无法执行リクエスト中的プログラミング功能。这是专门为 0x0D(プログラミング功能)设计的異常コード。,表示プログラミングリクエスト被拒绝。

典型触发场景:

  • プログラミングリクエストタイプサポートなし。:スレーブ的プログラミング功能有限,サポートなし。特定的プログラミング操作
  • プログラミング参数无效:リクエスト中包含了サポートなし。的プログラミング参数

Precautions:Exception Code 0x07 在 Modbus protocol specification V1.1b3 中定义,但实际上绝大多数 Modbus デバイス并不実装機能コード 0x0D(プログラミング),因此这个異常コード。在现实中极少遇到。

Exception Code 0x08 — 存储器奇偶検証エラー(Memory Parity Error)

含义:スレーブ在読み取り文件记录时,检测到存储器奇偶検証エラー。仅与文件操作機能コード(0x14、0x15)Related。

典型触发场景:

  • 文件记录损坏:文件存储エリア因电源故障または他の原因データ损坏
  • Flash 存储器老化:频繁写入导致 Flash 存储ユニット的可靠性下降

Exception Code 0x0A — Gateway path unavailable(Gateway Path Unavailable)

含义:ゲートウェイ无法建立到目标デバイス的内部通信路径。这通常发生在ゲートウェイ连接了多个下游デバイス时。

典型触发场景:

  • 下游デバイスオフライン:ゲートウェイ后的 Modbus RTU デバイス停電或切断する
  • 下游デバイスアドレスエラー:ゲートウェイ被設定为转发到不存在駅からの住所
  • ゲートウェイ内部路由表エラー:ゲートウェイ的路由設定不正确

手順の確認:

  1. チェックゲートウェイ下游デバイス的通信ステータス指示灯
  2. 使用 Modbus Poll 直接连接下游デバイス,排除デバイス本身故障
  3. チェックゲートウェイ的路由表設定
  4. 確認下游デバイス的 Modbus アドレス和ボーレート設定

Exception Code 0x0B — Gateway target device response failed(Gateway Target Device Failed to Respond)

含义:ゲートウェイ能够建立通信路径,但目标デバイス未能提供有效レスポンス。与 0x0A 違いはありません:0x0A 是ゲートウェイ内部路径通信不可,0x0B 是路径終わったけど目标デバイスが応答しません。

典型触发场景:

  • 目标デバイス繁忙:デバイス処理中です。上一条指令
  • 目标デバイスレスポンス·タイムアウト:Modbus RTU 的 3.5 文字タイムアウト机制触发
  • データ格式不マッチング:下游デバイス的通信パラメータ(Baud rate、チェック方式)与ゲートウェイ設定不一致

三、異常なスピードチェック表

Exception Code Name(英文) Name(中文) 常见程度
0x01Illegal FunctionIllegal function★★★★★
0x02Illegal Data AddressIllegal data address★★★★★
0x03Illegal Data ValueIllegal data value★★★★☆
0x04Slave Device FailureSubstation equipment malfunction★★★☆☆
0x05AcknowledgeConfirm(待機中中)★★★☆☆
0x06Slave Device BusyThe slave station equipment is busy★★★☆☆
0x07Negative Acknowledge否定確認★☆☆☆☆
0x08Memory Parity ErrorMemory verification error★☆☆☆☆
0x0AGateway Path UnavailableGateway path unavailable★★☆☆☆
0x0BGateway Target Failedゲートウェイ目标レスポンス失敗★★☆☆☆

四、深度故障トラブルシューティング方法论

4.1 分层トラブルシューティング法

工业通信故障トラブルシューティング应遵循「自底向上」的原则,从物理層は逐步向上层トラブルシューティング:

  1. 物理層は:チェック线缆连接、終端抵抗、デバイス供电、接地情况
  2. データ链路层:使用オシロスコープ或ロジックアナライザチェック RS-485 信号质量
  3. 网络层:在 Modbus TCP 场景下,使用 Wireshark バッグの分析。
  4. アプリケーション層:使用 Modbus Poll 等工具送信最小化リクエスト来ポジショニング問題

4.2 对比除外の法則

当现场有多个同型号デバイス时,使用对比除外の法則是最高效的ポジショニング手段:

  1. 将疑似故障デバイス与正常工作的デバイス交換位置
  2. 使用同一台マスター工具分别测试两台デバイス
  3. 比较两台デバイス的レスポンス报文差异

4.3 最小化复现法

将复杂リクエスト简化为最简单的合法リクエスト,逐步增加复杂度:

步骤 1: 送信最简リクエスト 01 03 00 00 00 01 [CRC] —— 読み取りアドレス 0 的 1 Registers
步骤 2: もし成功,逐步增加レジスタの数 00 02, 00 03 ...
步骤 3: もし失敗,缩小アドレス範囲トラブルシューティング

五、RTU 与 TCP モード下的異常差异

虽然異常コード。的定义在 RTU 和 TCP モード下完全一致,但2つのモデル下的異常処理流程有所不同:

对比维度Modbus RTUModbus TCP
タイムアウト処理3.5 文字の時間応答なし。判定タイムアウトTCP 接続タイムアウト由オペレーティングシステム控制
異常检测CRC verificationエラー直接丢弃报文TCP 层保证データ完全性
MBAP Header需要チェックトランザクション識別子マッチング
ゲートウェイ场景较少涉及Exception Code 0x0A/0x0B 更常见

六、プログラミング実装:異常処理的ベストプラクティス

以下是使用 C 语言実装 Modbus 異常処理的完全な例,適用されるエンベデッド·イン系统开发:

/**
 * Modbus 異常コード。処理函数
 * @param func      リクエスト機能コード
 * @param exception Exception Code
 * @return 人类可读的エラー説明ストリング·ストリング
 */
const char* modbus_exception_str(uint8_t func, uint8_t exception) {
    static char buf[128];
    const char* exc_name;
    
    switch (exception) {
        case 0x01: exc_name = "違法な機能コード"; break;
        case 0x02: exc_name = "Illegal data address"; break;
        case 0x03: exc_name = "Illegal data value"; break;
        case 0x04: exc_name = "Substation equipment malfunction"; break;
        case 0x05: exc_name = "Confirm(待機中中)"; break;
        case 0x06: exc_name = "The slave station equipment is busy"; break;
        case 0x07: exc_name = "否定確認"; break;
        case 0x08: exc_name = "Memory verification error"; break;
        case 0x0A: exc_name = "Gateway path unavailable"; break;
        case 0x0B: exc_name = "ゲートウェイ目标レスポンス失敗"; break;
        default:   exc_name = "Unknown exception code"; break;
    }
    
    snprintf(buf, sizeof(buf), 
             "Modbus 異常: function code 0x%02X → Exception Code 0x%02X (%s)",
             func, exception, exc_name);
    return buf;
}

/**
 * 処理 Modbus Response
 * 戻る 0 表示普通の反応,负值表示異常
 */
int modbus_handle_response(uint8_t* rsp, int rsp_len,
                           uint8_t expected_func) {
    if (rsp_len < 2) return -1; // レスポンス長さ異常
    
    uint8_t func = rsp[1]; // RTU モード下,第二个byteは機能コード
    
    if (func & 0x80) {
        // Exception Response
        uint8_t exception = rsp[2];
        log_error(modbus_exception_str(func & 0x7F, exception));
        
        // 根据異常コード。采取不同的重试策略
        switch (exception) {
            case 0x01: // 機能コードサポートなし。 - 不重试
            case 0x02: // アドレス非法 - 不重试
                return -exception;
            case 0x05: // Confirm - 待機中后重试
            case 0x06: // デバイスビジー - 延迟重试
                return -exception; // 调用者処理重试逻辑
            default:
                return -exception;
        }
    }
    
    // 普通の反応処理...
    return 0;
}

七、common problems FAQ

Q1: Modbus スレーブ戻る了異常コード。 0x02,但アドレス看起来是正确的,なぜか。?

最も一般的な的原因是「アドレス偏移 1」的問題。某些デバイス(特别是 PLC)的 Modbus アドレス与プロトコルアドレス存在 1 的偏移。比如 PLC 端設定アドレス为 40001,但 Modbus protocol中对应的内部アドレス是 0(而ではない 1)。请查阅デバイス手册確認アドレスマッピング关系。

Q2: なぜか。スレーブ有时戻る正常データ,有时例外コードを返す 0x06?

这通常意味着スレーブ的 CPU 処理能力不足。当ポーリング频率过高时,スレーブ来不及処理すべてのリクエスト,就会戻る 0x06。解決方法:ポーリング頻度の低減,或减少单次リクエスト的レジスタの数。

Q3: Exception Code 0x05 和 0x06 違いは何ですか??

0x05(Confirm):スレーブ已经在処理你送信的特定リクエスト,需要待機中完成。0x06(デバイスビジー):スレーブ当前无法処理任何新リクエスト,原因可能是任意操作。简单记忆:0x05 是「你的事我在办」,0x06 是「我现在很忙谁都别来」。

Q4: スレーブ完全不レスポンス(タイムアウト),而ではない例外コードを返す,该怎么トラブルシューティング?

完全に無反応。通常意味着問題在物理層は或データ链路层:

  1. チェック駅からの住所是否正确(アドレス不マッチング是スレーブ静默的最も一般的な原因)
  2. チェック RS-485 的 A/B 线是否接反
  3. チェックボーレート和チェック方式一致するかどうか
  4. 終端抵抗のチェック和バイアス抵抗体
  5. 使用オシロスコープ確認バス上是否信号がある。

八、总结

Modbus 的異常な応答机制是协议设计中的一大亮点——它ではない简单地让通信失敗,而是経由異常コード。精确地告诉マスター「哪里出了問題」。掌握这些異常コード。的含义和トラブルシューティング方法,可以将故障ポジショニング时间从数小时缩短到数分。

建议将本記事的異常なスピードチェック表打印出来贴在工位旁,或者在デバッグツール中集成異常コード。自动解析功能。在工业现场,每一分的停机都意味着真金白银的损失——而快速ポジショニング Modbus Exception Code,往往是解決問題的最初のステップ。

相关阅读:Modbus 機能コード完全解析 | Modbus RTU 与 TCP 深度对比 | Modbus CRC verification原理与プログラミング実装

Put this resource to use in a real project?

Go to the Tool Center for message parsing, CRC verification and device debugging, or submit your requirements for selection and integration advice.

Engineer Membership

Turn this article into actionable debugging resources

After activation, you can use advanced message parsing, resource pack downloads, code examples, engineering cases and priority technical support, suitable for real project delivery.

Unlimited Advanced Tools
Resource & Code Packs
Complete Engineering Case Library
Priority Technical Support

Leave a Reply

Your email address will not be published. Required fields are marked *.