Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

2.11 清除诊断信息(0x14)——消除症状

治好了,症状列表要清掉

你已经通过0x19读到了P0305——5号缸失火。冻结帧告诉你故障发生在87km/h的高速巡航时——水温正常,长期燃油修正+3.1%。你检查了火花塞、更换了点火线圈、清除了燃烧室积碳。发动机重新启动——怠速平稳,短途试车没有异常。

现在你需要让ECU知道:“这个故障已经修好了——你可以擦掉这条DTC了。”

这就是0x14 ClearDiagnosticInformation的全部使命。但这里藏着一个设计上的微妙之处——你不能只删一条DTC,你得删一整组。


为什么是分组清除而不是逐条清除

如果你回到OBD-II时代——Mode 0x04是清除排放诊断信息的标准命令。OBD-II的设计者面临一个选择:是让诊断仪逐条DTC发送清除指令,还是一次性清掉整组?

逐条清除听起来更精细——但实际上在诊断实践中是一个反模式。你想想真实的诊断场景:一个ECU可能有几十个DTC——转速传感器间歇失效、氧传感器老化、三元催化器效率下降、EGR流量不足、凸轮轴位置偏移……这些故障共享根因的概率极高——都是因为同一个O2传感器响应迟缓导致ECU做了一连串有误的喷油修正。维修技师把O2传感器换新之后——所有DTC都应该消失。

如果他必须逐条DTC发清除命令——几十条请求+响应——在500kbps的CAN总线上耗时几秒——诊断效率被人为降低。分组清除是 “治好了根因,所有症状自然消失” 的设计。

但这不是唯一的原因。DTC的分配规则本身就阻止了“不相关的故障码被误删“:排放相关的动力总成DTC归组0xFFFF33;底盘稳定DTC归车厂自定义的组;车身控制DTC再归另一组。你清除排放组时不会碰到底盘组的DTC。

核心洞察:分组清除的设计哲学不是“偷懒不想做逐条清除“——它是工程实践中DTC根因的高度相关性在协议层的映射。同一个物理故障会触发多条上下游的DTC——这些DTC必须一同消去,否则诊断仪和ECU就会处在不一致的状态。


groupOfDTC——三个字节的门牌号

groupOfDTC是一个3字节的值。在ISO 14229-1:2013的语境中,它的最高三位(bit23-21)编码了DTC的类别,正好映射到OBD-II的P/C/B/U分类:

groupOfDTC[0] bits:   类别编码 (00=Powertrain, 01=Chassis, 10=Body, 11=Network)
groupOfDTC[1] bits:   能识别具体的DTC前缀范围
groupOfDTC[2] bytes:  填充对应范围

两个特殊值你永远不会忘记:

  • 0x000000 = 空白组(不常用)
  • 0xFFFFFF = 所有组 —— 维修站最常用的值:一键清理全部DTC

法规也定义了具体的组号:

  • 0xFFFF33 = 排放相关组(Emissions-related group)——这是OBD-II法规最关注的
  • 0xFFFX00~0xFFFF31 = 法规定义的其他组(动力总成、底盘、车身、网络通信)

请求格式——唯一不带子功能的UDS服务

Byte 0: 0x14 (SID)
Byte 1-3: groupOfDTC (3字节,大端序——高位Byte在前)

正响应只有一个字节:

Byte 0: 0x54 (SID+0x40)

没有额外数据。没有成功的标志位解释、没有被清除的DTC数量统计、没有剩余DTC清单。

为什么这么自信?因为如果清除操作失败——ECU会返回负响应(NRC 0x22条件不满足,或NRC 0x72通用编程失败)。如果清除完成——那一条字节0x54就够了。不需要增加任何数据成本。

核心洞察:0x54这个单字节正响应是UDS里最节约成本的确认机制。它代表了ECU给诊断仪的信息:“我已完成清除全部所请求的组下所有DTC——不需要你再来验证哪些没了哪些还在。如果失败了我会明确告诉你为什么。


0x14具体清除了什么——不止删DTC条目

执行0x14时,ECU在DEM(Diagnostic Event Manager)中执行以下动作:

被清除详细含义
DTC Status Byte 所有8位testFailed、pendingDTC、confirmedDTC……全部归0
DTC Snapshot(快照数据)故障发生那刻记录的PID数据——清除
DTC Extended Data(扩展数据)故障计数器、发生时间戳、老化计数器——清除
FirstTestFailedDTC / MostRecentTestFailedDTC首次失败/最近失败DTC的登记——清除
ConfirmedDTC标志确认标记清除——故障码不再被视为永久

不被清除的

不清除原因
Mirror Memory DTC镜像内存的DTC受法规保护——即使主内存被擦——排放相关DTC的镜像必须永久保留
Event Memory DTC(某些实现相关)事件存储器中的DTC不应因诊断清除而消除
Permanent DTC(永久DTC)法规要求某些排放DTC在老化之前不能随意清除

核心洞察:0x14不是你想象中的“删一条DTC就像删一个文件“——它是一个全组重置操作。DTC条目、快照、扩展数据、内部各种计数器和标记位——全部归零。但镜像内存是法律要求必须保存的底线——它在主内存被清之后仍然保有一份记录。


DTCStatus掩码在Clear后的行为

清除执行完成后,DTC的所有状态位置0,但某些位随后会自动置1

  • testNotCompletedSinceLastClear (bit4) → 清除后立即设为1
  • testNotCompletedThisOperationCycle (bit6) → 当前操作周期内也设为1(如果检测尚未完成)

这很聪明——ECU在清除完毕后明确通知“我现在还没有重新做检测——所以这个DTC的检测状态是’未完成’。你下一次读取DTC时会看到bit4和bit6=1——这不是故障复现,是清除后的正常重置。


无法清除——可能发生的情况

诊断仪 → ECU:  0x14 0x00 0x00 0x00  (groupOfDTC=0x000000——空组)
ECU → 诊断仪:   0x7F 0x14 0x31 (NRC 0x31 = requestOutOfRange)

groupOfDTC=0x000000通常无效——因为没有一个DTC会属于“组0“。

诊断仪 → ECU:  0x14 0xFF 0xFF 0xFF
ECU → 诊断仪:   0x7F 0x14 0x22 (NRC 0x22 = conditionsNotCorrect)

可能是ECU正在编程模式下不允许清DTC——或当前有未处理的SafetyCritical DTC阻止清除。更常见的情况是安全访问未解锁(NRC 0x33 = securityAccessDenied)——如果DTC清除受安全等级保护,必须先执行0x27解锁。


clearDiagnosticInformation在医院里的最终映射

在医院里,0x14是你决定病人已不需要住院——然后把整本纸质病历归档——并把电子病历系统里的症状清单标记为“已解除“。下次病人再来时检查是空白的——之前的所有症状记录都已记录到历史存档中、但不再作为活跃状态显示。

镜像内存呢?相当于医院的法律合规备份——不管你门诊怎么清——法律要求保留患者在某个特定时刻的全部病历记录。


本篇小结

  1. 0x14是分组清除——不是单DTC清除——因为工程实践中同一根因的多条DTC必须同时消去,避免不一致。
  2. groupOfDTC=0xFFFFFF是全部组的预设值——大多数诊断工具以此作为“清除所有DTC“的命令。
  3. 清除后DTC状态位全0——但bit4(testNotCompletedSinceLastClear)自动置1以示意“检测重新开始“。
  4. 镜像内存的记录不受0x14影响——这是法规留下的不可篡改痕迹。

【下集预告】:DTC清了——你开始给ECU刷新固件。但你肯定不希望刷写过程中ECU还在往DEM里写新的DTC。你需要在刷写前暂停DTC记录——0x85 ControlDTCSetting就是暂缓发病症状的总开关。