1. DTC基础概念:DTC定义、在诊断协议中的位置与UDS服务的关系

1.1 DTC到底是什么?

DTC,全称是Diagnostic Trouble Code,诊断故障码。说白了,就是ECU自己给自己看病时,写下来的“病历本”。

我刚开始做嵌入式那会儿,总觉得DTC就是个错误编号。后来踩过坑才明白——它远不止一个编号那么简单。DTC背后承载的是:哪个系统出了问题、出了什么问题、问题严不严重、什么时候出的。

一个标准的DTC由三部分组成:

  • 故障码编号:比如P0101,一看就知道是进气流量系统的事
  • 故障类型:信号超范围、电路对地短路、信号不合理……
  • 故障状态:当前有没有故障、是不是历史故障、是否被确认过

核心理解:DTC不是“报个错就完事”,它是诊断系统的“证据链”。你想想看,维修技师拿到一辆车,第一件事就是读DTC。如果DTC设计得不好,修车就像大海捞针。

1.2 DTC在诊断协议中的位置

咱们做汽车电子的,绕不开ISO 14229(UDS)和ISO 15765(CAN诊断)。DTC在这套协议栈里,到底站在哪个位置?

我画了一张图,帮你理清这个关系:

DTC在UDS诊断协议栈中的位置 应用层(UDS服务) 0x19 读取DTC信息 | 0x14 清除DTC | 0x85 控制DTC设置 表示层(DTC数据格式定义) DTC编号(3字节) + 状态掩码(1字节) + 快照/扩展数据 会话层(诊断会话管理) 默认会话 | 扩展会话 | 编程会话 传输层(CAN / DoIP / LIN) ISO 15765-2 (CAN TP) | 单帧/多帧传输 DTC贯穿整个诊断协议栈:应用层定义服务,表示层定义格式,传输层负责收发

从这张图你能看到:DTC不是孤立的。它从应用层的UDS服务(比如0x19读故障码)发起,经过表示层的数据格式化,再通过传输层发到总线上。

我记得有一次调试,发现DTC读出来全是乱码。查了半天,原来是传输层多帧重组时,序列号搞错了。嗯,从那以后我特别重视协议栈各层之间的配合。

1.3 DTC与UDS服务的关系

UDS(统一诊断服务)里,跟DTC直接相关的服务主要有这几个:

服务ID 服务名称 跟DTC的关系
0x14 ClearDiagnosticInformation 清除DTC,把故障码状态复位
0x19 ReadDTCInformation 读取DTC,这是最常用的服务
0x85 ControlDTCSetting 控制DTC开关,比如刷写时关掉诊断
0x2E WriteDataByIdentifier 可以写DTC相关的数据标识符

这里我重点说说0x19服务。它有好几个子功能,我列一下常用的:

  • 0x01:按状态掩码读取DTC数量
  • 0x02:按状态掩码读取DTC列表
  • 0x03:读取所有DTC的快照数据
  • 0x04:读取所有DTC的扩展数据
  • 0x06:按DTC编号读取快照
  • 0x0A:读取所有DTC(包括状态)

个人经验:我建议你在设计DTC存储策略时,优先考虑0x19 0x02和0x0A这两个子功能。0x02适合快速扫描,0x0A适合深度诊断。我在一个项目中,就因为只实现了0x02没实现0x0A,结果客户抱怨读不到完整的故障信息……后来连夜补上了。

1.4 DTC的状态管理

DTC不是“有”或“没有”这么简单。每个DTC都有一个状态字节,8个bit,每个bit代表一种状态:

Bit位 含义 说明
Bit 0 testFailed 当前测试失败
Bit 1 testFailedThisOperationCycle 本次操作循环内测试失败
Bit 2 pendingDTC 待定故障(还没确认)
Bit 3 confirmedDTC 已确认故障
Bit 4 testNotCompletedSinceLastClear 上次清除后还没完成测试
Bit 5 testFailedSinceLastClear 上次清除后发生过故障
Bit 6 testNotCompletedThisOperationCycle 本次操作循环内测试未完成
Bit 7 warningIndicatorRequested 请求点亮警告灯

你想想看,这8个bit组合起来,能表达多少种故障状态?256种。这就是为什么DTC状态管理这么灵活。

避坑指南:我曾经在一个项目中,把Bit 3(confirmedDTC)和Bit 0(testFailed)搞混了。结果故障明明已经恢复了,Bit 0清掉了,但Bit 3还置着,导致仪表盘上的故障灯一直亮着。车主差点投诉到315……

记住:testFailed是瞬时状态,confirmedDTC是持久状态。只有经过一个完整的诊断循环,confirmedDTC才会被清除。

1.5 DTC的存储策略

DTC存哪儿?怎么存?这问题我当年也纠结过。常见的方案有三种:

  1. RAM + EEPROM双备份:RAM存当前故障,EEPROM存历史故障。掉电不丢失。
  2. 仅EEPROM:每次故障都写EEPROM。简单,但寿命是个问题。
  3. NVM(非易失性存储器)管理:用AutoSAR的NvM模块统一管理。最规范,但学习成本高。

我个人习惯用方案一。为什么?因为EEPROM有擦写寿命限制,一般10万次左右。如果某个传感器接触不良,频繁报故障,几天就能把EEPROM写废了。RAM做缓存,只有确认后的故障才写EEPROM,能大大延长寿命。

核心原则:DTC存储要遵循“先缓存,后确认,再持久化”的流程。别一有风吹草动就往EEPROM里写,那是给自己挖坑。

1.6 小结

这一章我们聊了DTC的定义、它在诊断协议栈中的位置、跟UDS服务的关系,还有状态管理和存储策略。说白了,DTC就是ECU的“病历本”,怎么记、记在哪儿、什么时候记,都是有讲究的。

下一章我们会深入DTC的编号规则和故障类型分类,到时候再细聊。


可可精品资料库