Modbus 異常な応答码与故障トラブルシューティング完全手册:从 01 to 11 完全に。解析
关键词:Modbus Exception Code、Modbus 故障トラブルシューティング、Modbus エラー·コード、Modbus Exception Code、Modbus 通信故障
在工业自動化现场,Modbus 通信故障是最让エンジニア头疼的問題之一。当マスター发出リクエスト后,スレーブ戻る的ではない正常データ,而是一个「Exception Response」——这表明通信链路ない問題,但业务逻辑层出现了エラー。理解每一个異常コード。的含义、触发条件和トラブルシューティング方法,是每一位自動化エンジニア的必修课。
本記事将从 Modbus protocol specification(V1.1b3)出发,结合真实工业现场案例,深入解析すべて 11 个標準異常コード。的触发机制、トラブルシューティング流程和ソリューション。无论您是初次接触 Modbus 的新手,まだ希望系统化梳理知识的老兵,都能从本記事中找到实用的参照。
一、Modbus 異常な応答的基本机制
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 Poll、ModScan)中看到ステーションからのデータ时,判断は、否为異常な応答非常简单:
- 表示レスポンス機能コード是否大于 0x80(即最高位为 1)
- もし機能コード > 0x80,则第二バイト単位。即为異常コード。
- 根据異常コード。查表确定エラータイプ
在プログラミング実装中,检测逻辑如下:
// 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)
含义:スレーブサポートなし。リクエスト的機能コード。这是最も一般的な的異常コード。之一,通常发生在マスター使用了スレーブ未実装的機能コード时。
典型触发场景:
- 機能コード超出範囲:マスター送信了機能コード 0x14(ファイルレコードの読み取り),但スレーブ只実装了 0x03、0x04、0x06、0x10
- PLC 型号サポートなし。:部分低端 PLC 只サポート 0x03 和 0x06,尝试使用 0x10(write multiple registers)会戻る 0x01
- デバイス構成エラー:某些デバイス的 Modbus 実装経由設定开关有効/無効機能コード,もし对应功能被無効,同样戻る 0x01
- ゲートウェイ转换問題:Modbus TCP to RTU 的ゲートウェイ可能サポートなし。某些機能コード的透传
手順の確認:
- 查阅デバイス手册,確認スレーブサポート哪些機能コード
- 使用 Modbus Poll 等工具逐一测试機能コード,缩小問題範囲
- チェックGateway/Converter的機能コード过滤設定
- もし使用自研程序,確認機能コード常量定义是否正确
实际案例:某水処理项目中,トップマシン使用機能コード 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,可能触发越界
手順の確認:
- 使用 0x03 function code,住所から。 0 开始逐一読み取り,确定有效アドレス範囲
- 機器の確認手册中的アドレス是「プロトコルアドレス」まだ「PLC address」——两者可能相差 1
- 对于 32 ビット·データ,确保リクエスト的レジスタの数为偶数
- チェック报文中アドレス的大リトルエンディアンバイトオーダー是否正确
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」不一致
- 报文長さエラー:整个报文的实际長さ与报头中声明の長ささ不符
手順の確認:
- 重点チェック 0x10(write multiple registers)的报文構造——这是最容易出错的场景
- 验证「byte count = number of registers × 2」是否成立
- 確認値の書き込み是否在デバイス手册规定的範囲内
- 对于 0x06(write single register),チェック値の書き込み的範囲(0x0000 ~ 0xFFFF)
Exception Code 0x04 — Substation equipment malfunction(Slave Device Failure)
含义:スレーブ在処理リクエスト时发生了不可恢复的内部エラー。这是一个「万金油」Exception Code,表示スレーブ自身出现了严重問題。
典型触发场景:
- EEPROM/Flash 写入失敗:スレーブ将設定写入非易失性存储器时失敗
- センサーは故障:スレーブ连接的センサーは损坏,无法提供有效读数
- 内部通信故障:スレーブ内部的主控芯片与外设之间的通信異常
- 文件系统エラー:涉及文件操作的機能コード(0x14、0x15)遇到文件系统異常
手順の確認:
- チェックスレーブデバイス的电源是否稳定
- 表示スレーブ的 LED 指示灯ステータス(通常有故障灯)
- 尝试对スレーブ进行電源オフと再起動
- 联系デバイス厂商取得诊断工具或ファームウェアアップグレード
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
- スレーブ正在进行自诊断:部分デバイス在启动时会执行自检,期间不レスポンス通信
手順の確認:
- 适当增加マスター的ポーリング間隔(如从 100ms 增加到 500ms)
- 减少同时通信的スレーブ数量
- チェックスレーブ的固件版本,確認ありますか?已知的性能問題
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 デバイス停電或切断する
- 下游デバイスアドレスエラー:ゲートウェイ被設定为转发到不存在駅からの住所
- ゲートウェイ内部路由表エラー:ゲートウェイ的路由設定不正确
手順の確認:
- チェックゲートウェイ下游デバイス的通信ステータス指示灯
- 使用 Modbus Poll 直接连接下游デバイス,排除デバイス本身故障
- チェックゲートウェイ的路由表設定
- 確認下游デバイス的 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(中文) | 常见程度 |
|---|---|---|---|
| 0x01 | Illegal Function | Illegal function | ★★★★★ |
| 0x02 | Illegal Data Address | Illegal data address | ★★★★★ |
| 0x03 | Illegal Data Value | Illegal data value | ★★★★☆ |
| 0x04 | Slave Device Failure | Substation equipment malfunction | ★★★☆☆ |
| 0x05 | Acknowledge | Confirm(待機中中) | ★★★☆☆ |
| 0x06 | Slave Device Busy | The slave station equipment is busy | ★★★☆☆ |
| 0x07 | Negative Acknowledge | 否定確認 | ★☆☆☆☆ |
| 0x08 | Memory Parity Error | Memory verification error | ★☆☆☆☆ |
| 0x0A | Gateway Path Unavailable | Gateway path unavailable | ★★☆☆☆ |
| 0x0B | Gateway Target Failed | ゲートウェイ目标レスポンス失敗 | ★★☆☆☆ |
四、深度故障トラブルシューティング方法论
4.1 分层トラブルシューティング法
工业通信故障トラブルシューティング应遵循「自底向上」的原则,从物理層は逐步向上层トラブルシューティング:
- 物理層は:チェック线缆连接、終端抵抗、デバイス供电、接地情况
- データ链路层:使用オシロスコープ或ロジックアナライザチェック RS-485 信号质量
- 网络层:在 Modbus TCP 场景下,使用 Wireshark バッグの分析。
- アプリケーション層:使用 Modbus Poll 等工具送信最小化リクエスト来ポジショニング問題
4.2 对比除外の法則
当现场有多个同型号デバイス时,使用对比除外の法則是最高效的ポジショニング手段:
- 将疑似故障デバイス与正常工作的デバイス交換位置
- 使用同一台マスター工具分别测试两台デバイス
- 比较两台デバイス的レスポンス报文差异
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 RTU | Modbus 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: スレーブ完全不レスポンス(タイムアウト),而ではない例外コードを返す,该怎么トラブルシューティング?
完全に無反応。通常意味着問題在物理層は或データ链路层:
- チェック駅からの住所是否正确(アドレス不マッチング是スレーブ静默的最も一般的な原因)
- チェック RS-485 的 A/B 线是否接反
- チェックボーレート和チェック方式一致するかどうか
- 終端抵抗のチェック和バイアス抵抗体
- 使用オシロスコープ確認バス上是否信号がある。
八、总结
Modbus 的異常な応答机制是协议设计中的一大亮点——它ではない简单地让通信失敗,而是経由異常コード。精确地告诉マスター「哪里出了問題」。掌握这些異常コード。的含义和トラブルシューティング方法,可以将故障ポジショニング时间从数小时缩短到数分。
建议将本記事的異常なスピードチェック表打印出来贴在工位旁,或者在デバッグツール中集成異常コード。自动解析功能。在工业现场,每一分的停机都意味着真金白银的损失——而快速ポジショニング Modbus Exception Code,往往是解決問題的最初のステップ。
相关阅读:Modbus 機能コード完全解析 | Modbus RTU 与 TCP 深度对比 | Modbus CRC verification原理与プログラミング実装
Leave a Reply