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.9 读取DTC信息(0x19)——查看症状清单

一个服务,掌管所有“查病历“的需求

你在第1.5节的完整诊断流程中已经见过0x19——你向ECU询问“有多少个confirmed故障码“,ECU回答“3个“,你继续追问“哪三个?P0102、P0305、C0421——它们的故障快照数据给我看看“。

0x19是UDS协议里子功能最多的SID——一共19种子功能(ISO 14229-1:2013定义0x01~0x13),每种子功能应对不同的DTC查询场景。为什么需要19种?因为 “查病历“本身不是一种操作——它是一系列不同维度的追问

你问的问题对应子功能为什么需要独立子功能
有多少个Confirmed的DTC?0x01 reportNumberOfDTCByStatusMask只需数字——先了解一下严重性——别急着展开全部详情
列出所有这些DTC和状态0x02 reportDTCByStatusMask展开列表——每个DTC 4字节(3+DTCStatus=1)
这些DTC的快照数据可以拿吗?0x03 reportDTCSnapshotIdentificationDID+record信息——先拿到有哪些快照可以获取
P0305的快照数据给我0x04 reportDTCSnapshotRecordByDTCNumber基于DTC号拿完整的快照数据
有多少排放OBD相关DTC?0x12OBD-II的法规需求——和UDS DTC并行管理
镜像内存里有什么DTC?0x0F不可擦除的“备份病历“

核心洞察:0x19不是被设计成“一个强大的DTC查询工具“——它是被逐个子功能需求叠加出来的。每一个子功能的诞生都对应一个实际诊断场景:“法规要求能看到排放OBD永久码”(→ 0x12/0x13/0x15)、“维修站需要DTC冻结帧来定位故障发生上下文”(→ 0x03/0x04)、“产线需要批量验证所有支持的DTC”(→ 0x0A)——因此19种子功能逐层叠加。


请求报文结构

Byte 1: sub-function (reportType, bit6-0)
        bit7 = suppressPosRsp
        bit6-0 = 0x01~0x19
Byte 2+: 附加参数 (取决于子功能)

各子功能的附加参数不能一一全讲——但核心几类子功能如下:


核心子功能A组:按状态掩码查询

0x01 reportNumberOfDTCByStatusMask: 报告数量(无具体DTC)
0x02 reportDTCByStatusMask: 报告DTC列表(含DTC编号+状态字节)

0x01→0x02构成典型的“先问有多少,再问具体内容“两阶段查询模式——先用量统计判断严重性,再展开完整列表。

附加参数:DTCStatusMask (1字节)

请求格式:

0x19 0x01 0x09
      sub   DTCStatusMask=0x09=(confirmedDTC|testFailed)

正响应(0x01):

Byte 0: 0x59
Byte 1: 0x01 (子功能回声)
Byte 2: DTCStatusAvailabilityMask (0x09)
Byte 3: DTCFormatIdentifier (0x01=OBD, 0x02=J1939, 0x03=ISO14229)
Byte 4-5: DTCCount (大端序) → 有几个DTC

正响应(0x02):

Byte 0: 0x59
Byte 1: 0x02
Byte 2: DTCStatusAvailabilityMask
Byte 3+: 重复N次 [ DTC(3 bytes) + statusOfDTC(1 byte) ]

例子:读取所有confirmed的DTC列表:

请求:  0x19 0x02 0x08 → DTCStatusMask=0x08 (confirmedDTC)
响应:  0x59 0x02 0x08 0x01 0x02 0x08 0x09 0x01 0x03 0x04 0x0F
                mask    DTC1:010208 status=09  DTC2:010304 status=0F
  解读:
    DTC1 = 0x010208 → OBD格式 P0102 (MAF传感器电路低电压), status=testFailed+confirmed
    DTC2 = 0x010304 → OBD格式 P0304 (4号缸失火), status=testFailed+confirmed+testNotCompletedSinceLastClear+warningIndicatorRequested
> 注:ISO 14229-1使用三字节DTC编码(如0x010208),OBD-II使用五字符编码(如P0102),两者之间通过标准映射规则互相转换——高半字节决定前缀(0x0→P, 0x1→C, 0x2→B, 0x3→U),后续字节决定数字部分。

核心子功能B组:冻结帧/快照查询

0x03 reportDTCSnapshotIdentification: 列出所有有快照的DTC
0x04 reportDTCSnapshotRecordByDTCNumber: 根据DTC编号获取快照数据

冻结帧(Freeze Frame)是DTC发生那一刻ECU自动记录的一组环境参数——发动机转速、车速、冷却液温度、进气温度、燃油修正——帮助诊断技师理解故障发生的上下文。

Step 1: 查明哪些DTC有快照
请求:  0x19 0x03
响应:  0x59 0x03 0x01 0x02 0x03 0x01 0x01 0x03 0x05 0x02
          DTC1:010203 Record=1  DTC2:010305 Record=2
         P0103有1条快照记录,P0305有2条快照记录

Step 2: 拿到快照
请求:  0x19 0x04 0x01 0x03 0x05 0x02
          sub     DTC=010305         recordNumber 0x02

响应:  0x59 0x04 + DTCAndStatusRecord + DTCSnapshotRecord
         ...包含一组数据项 (每个数据项是一个DID + dataRecord)
         VehicleSpeed=87km/h, EngineSpeed=2450rpm, CoolantTemp=92°C, LTFT=+3.1%

核心子功能C组:扩展数据

0x06 reportDTCExtDataRecordByDTCNumber: 获取扩展数据记录

扩展数据是DTC的辅助信息——故障计数器、衰老计数器、发生时间、里程数——这些信息对诊断仪来说极其关键。比如“故障计数器=127“表示一个DTC已经发生了127次——这是个高频故障——而不是偶尔一次短路。


镜像内存的特殊含义

ISO 14229-1:2013引入了 镜像内存(Mirror Memory) 的概念:

  • DTC可以在两个存储器中共存——主存储器和镜像存储器
  • 0x14清除DTC只清除主存储器——镜像存储器的DTC不被清除
  • 镜像存储器的读取通过0x19的子功能0x0F~0x11完成

为什么需要镜像内存?法规需求——某些排放相关的DTC必须保留“永久记录“——即使主诊断清除了也不能消除痕迹。类似于你的医疗记录会被注销——但你的医疗记录归档到医管局的备份不能随意注销。


本篇小结

  1. 0x19读DTC信息是UDS里子功能最多的SID——19种子功能分别应对11种DTC查询维度:数量统计、列表枚举、快照、扩展数据、OBD合规、镜像内存、永久状态等。
  2. DTCStatusMask是0x19的核心参数——它定义“满足匹配条件“的DTC集合。statusOfDTC的8位编码(取Bit掩码比较)使查询粒度极细化——你不仅能查“confirmed DTC“,还能查“confirmed+testFailed且pending的DTC“。
  3. 快照(Freeze Frame)和扩展数据是0x19最强大的诊断能力——不是看“你有多少故障“,而是看“什么时候故障、故障的瞬间引擎正在做什么“。
  4. 镜像内存(Mirror Memory)给诊断数据持久性提供了第二重保障——即使主内存被清除也不丢排放合规相关的永久记录。

【下集预告】:DTC查完了——但每个DTC的状态字节到底在说什么?testFailed、confirmed、pending、warningIndicator这些bit位不是一堆随机标志——它们构成了一个故障的完整生命周期:从“首次检测到异常“到“确认“到“维修后清除“。0x19的子功能依赖这个状态字节做筛选——不理解状态字节,你读到的DTC列表就是一团乱码。下一节我们拆开这个字节的每一位。