4. DTC状态位详解(下):confirmedDTC、testNotCompletedSinceLastClear、testFailedSinceLastClear、testNotCompletedThisOperationCycle、warningIndicatorRequested
好,咱们接着聊DTC状态位。上一节我们把前三个bit讲透了,这一节把剩下的五个啃完。说实话,这五个bit在实际项目中踩坑的概率比前面三个还高,尤其是confirmedDTC和warningIndicatorRequested,我见过太多工程师在这两个位上翻车。
4.1 Bit 3:confirmedDTC(确认故障)
这个位,说白了就是“实锤位”。当一个故障被确认了,这个位就置1。什么叫“确认”?就是ECU经过多次检测,认定这个故障不是偶发的,是真的有问题。
什么时候会置1?
- 当
testFailed和testFailedThisOperationCycle同时为1时,ECU会立即把confirmedDTC置1 - 或者,当故障检测计数器达到确认阈值(通常是连续失败次数达到设定值)
什么时候会清零?
- 执行
ClearDiagnosticInformation服务(0x14)时,所有DTC状态位清零 - 或者,ECU内部的自清除机制(某些OEM会定义“行驶循环后自动清除”)
重点来了:confirmedDTC一旦置1,即使故障消失了,这个位也不会自动清零。它就像个“案底”,除非你主动清除,否则它一直挂着。
我在项目里遇到过一件事:某款车在产线上刷完软件后,confirmedDTC一直亮着。产线工人以为是故障,反复刷写。后来一查,是刷写流程里漏了ClearDiagnosticInformation这一步。嗯,这个坑我踩过,你们别踩。
4.2 Bit 4:testNotCompletedSinceLastClear(自上次清除后未完成测试)
这个位有点绕,我换个说法你就懂了:它表示“自从上次清码之后,这个故障的监测逻辑还没跑完一遍”。
置1条件:
- 执行完
ClearDiagnosticInformation后,该DTC对应的监测任务还没有完成至少一次完整的测试周期
清零条件:
- 监测任务完成了一次完整的测试,并且结果是通过(pass)
- 或者,监测任务完成了一次完整的测试,结果是失败(fail),此时
testFailedSinceLastClear会置1,但这个位会清零
我的习惯:在做产线终检时,我会先读一下这个位。如果某个DTC的testNotCompletedSinceLastClear还是1,说明这个监测还没跑完,这时候读到的故障状态是不完整的。我会让车辆再跑一段路,等监测完成再读。
4.3 Bit 5:testFailedSinceLastClear(自上次清除后测试失败)
这个位更直接:自从上次清码以来,这个故障有没有至少失败过一次?有就置1,没有就保持0。
你想想看,它和testFailed(Bit 0)的区别是什么?
testFailed:当前时刻,这个故障是不是激活的?testFailedSinceLastClear:自上次清码以来,这个故障有没有发生过?哪怕现在好了,只要曾经坏过,这个位就是1
| 场景 | testFailed (Bit 0) | testFailedSinceLastClear (Bit 5) |
|---|---|---|
| 故障从未发生 | 0 | 0 |
| 故障当前激活 | 1 | 1 |
| 故障曾经发生,现已恢复 | 0 | 1 |
这个位在售后诊断中特别有用。比如客户说“我的车昨天亮故障灯了,但今天又不亮了”,你读一下testFailedSinceLastClear,如果为1,说明确实发生过,不是客户瞎说。
4.4 Bit 6:testNotCompletedThisOperationCycle(本操作循环未完成测试)
这个位和Bit 4很像,但范围更小。Bit 4是“自上次清除以来”,Bit 6是“本操作循环”。
什么叫“操作循环”?
- 对于大多数ECU,一个操作循环就是一次上电到下一次上电之间的过程
- 对于OBD系统,一个操作循环通常定义为发动机启动到熄火
置1条件:
- 当前操作循环内,该DTC对应的监测任务还没有完成
清零条件:
- 当前操作循环内,监测任务完成了一次完整的测试(无论通过还是失败)
- 或者,ECU下电(进入休眠),下一个操作循环开始时,这个位会重新置1
注意:这个位在每次上电时都会自动置1。如果你刚上电就读DTC状态,看到这个位是1,别慌,这是正常的。等监测跑完一遍,它就会清零。
我曾经调试过一个项目,客户抱怨“每次上电后第一个故障总是抓不到”。后来发现,是诊断仪在ECU刚上电时就发请求,而监测任务还没跑完,testNotCompletedThisOperationCycle还是1,导致读到的状态不完整。解决方案很简单:等几秒钟再读,或者加一个“监测完成”的信号。
4.5 Bit 7:warningIndicatorRequested(警告指示灯请求)
这个位,就是“亮灯位”。当ECU认为这个故障严重到需要点亮仪表盘上的故障灯时,这个位就置1。
置1条件:
- 通常,当
confirmedDTC置1时,warningIndicatorRequested也会跟着置1 - 但有些OEM会定义更严格的策略:比如连续3个操作循环都检测到故障,才点亮故障灯
清零条件:
- 执行
ClearDiagnosticInformation服务 - 或者,ECU内部的自恢复机制(比如连续3个操作循环都没有检测到故障,自动熄灭故障灯)
关键点:这个位是“请求”位,不是“实际点亮”位。ECU把这个位置1,仪表盘收到后才会点亮故障灯。如果仪表盘和ECU之间的通信断了,即使这个位是1,故障灯也不会亮。
我遇到过最离谱的一个案例:某款车的warningIndicatorRequested一直为1,但故障灯就是不亮。查了三天,最后发现是仪表盘的CAN报文解析有bug,把故障灯信号解析到了另一个不用的位上。嗯,这种跨ECU的联调问题,最头疼。
小结一下
这五个bit,我按使用频率排个序:
- confirmedDTC:最常用,判断故障是否被确认
- warningIndicatorRequested:判断故障灯是否该亮
- testFailedSinceLastClear:判断历史故障
- testNotCompletedSinceLastClear:判断监测是否完成
- testNotCompletedThisOperationCycle:判断当前循环的监测状态
下一节,我们会把八个bit串起来,讲一个完整的DTC状态变迁图。到时候你会看到,这些bit之间是怎么互相影响的。嗯,那才是真正烧脑的地方。