1. 引言
在UDS诊断服务中,0x19 ReadDTCInformation(读取DTC信息) 堪称诊断功能的"重中之重"。DTC(Diagnostic Trouble Code,诊断故障代码)是ECU检测到故障时存储的标准化代码,是故障排查的第一手依据。
与刷写上位机不同,诊断上位机的核心任务之一就是读取并解析ECU中存储的DTC 。UDS协议为0x19服务定义了多达28个子服务(Sub-function) ,覆盖了从基础故障码读取到高级快照数据获取的完整能力。但在实际工程中,最常用的子服务主要集中在以下几个:
| 子服务 | 功能 |
|---|---|
| 0x01 | 按状态掩码读取DTC数量 |
| 0x02 | 按状态掩码读取DTC列表及状态 |
| 0x04 | 读取指定DTC的快照数据 |
| 0x06 | 读取指定DTC的扩展数据 |
| 0x0A | 读取ECU支持的所有DTC及状态 |
TOOMOSS_SID19_ReadDTCInformation.vi封装了UDS 0x19服务的核心子功能,通过调用TOOMOSS_SendAndWaitResp.vi通信基座完成请求发送和响应接收,并对响应数据进行解析,最终以结构化的DTC列表形式返回给上位机。
2. 子VI功能概述
2.1 设计目标
-
支持0x19服务最常用的子功能(0x01、0x02、0x04、0x0A)
-
根据用户指定的子功能和参数构造请求报文
-
解析ECU返回的响应数据,提取DTC编号和状态信息
-
返回结构化的DTC列表供界面显示
2.2 UDS 0x19服务协议说明
服务名称:ReadDTCInformation(读取DTC信息)
功能:允许客户端从服务器(ECU)读取存储的诊断故障代码信息。
请求格式(通用):
Byte 0: SID = 0x19
Byte 1: subFunction(子功能)
Byte 2~N: 子功能对应的参数
肯定响应格式(通用):
Byte 0: SID = 0x59(0x19 + 0x40)
Byte 1: subFunction(回声,与请求一致)
Byte 2~N: 响应数据(取决于子功能)
2.3 常用子功能详解
2.3.1 0x01 --- reportNumberOfDTCByStatusMask
功能:按状态掩码统计符合条件DTC的数量。
请求格式:
19 01 [StatusMask]
StatusMask:1字节DTC状态掩码,用于筛选特定状态的DTC
肯定响应格式:
59 01 [DTCStatusAvailabilityMask] [DTCFormatIdentifier] [DTCCount_High] [DTCCount_Low]
-
DTCStatusAvailabilityMask:ECU支持的DTC状态位掩码 -
DTCFormatIdentifier:DTC格式标识符(01表示ISO 14229格式) -
DTCCount:符合条件的DTC数量(2字节)
示例:请求已确认(confirmedDTC)的DTC数量
-
发送:
19 01 08(掩码0x08表示confirmedDTC位) -
响应:
59 01 FF 01 00 04(表示有4个已确认DTC)
2.3.2 0x02 --- reportDTCByStatusMask
功能:按状态掩码返回符合条件的DTC列表及其状态。
请求格式:
19 02 [StatusMask]
肯定响应格式:
59 02 [DTCStatusAvailabilityMask] [DTC1_High] [DTC1_Mid] [DTC1_Low] [Status1] [DTC2_High] ...
- 每个DTC占用4字节:3字节DTC编号 + 1字节状态
示例:
-
发送:
19 02 08(读取所有已确认DTC) -
响应:
59 02 FF 11 22 33 04 ...(DTC 0x112233状态为0x04)
2.3.3 0x0A --- reportSupportedDTC
功能:返回ECU支持的所有DTC及状态。
请求格式:
19 0A
无需额外参数。
肯定响应格式:
59 0A [DTCStatusAvailabilityMask] [DTC1_High] [DTC1_Mid] [DTC1_Low] [Status1] ...
格式与0x02相同。
2.3.4 0x04 --- reportDTCSnapshotRecordByDTCNumber
功能:读取指定DTC的快照记录(冻结帧)。快照数据记录了故障发生时ECU的关键运行参数(如车速、电压、转速、时间戳等)。
请求格式:
19 04 [DTC_High] [DTC_Mid] [DTC_Low] [DTCSnapshotRecordNumber]
-
DTC编号:3字节 -
DTCSnapshotRecordNumber:快照记录号(0xFF表示请求所有快照记录)
肯定响应格式:
59 04 [DTC_High] [DTC_Mid] [DTC_Low] [Status] [RecordNum] [Count] [DID1_High] [DID1_Low] [Data...] ...
-
RecordNum:快照记录号 -
Count:该记录中包含的DID数量 -
后续为(DID + 数据)的重复结构
2.3.5 0x06 --- reportDTCExtDataRecordByDTCNumber
功能:读取指定DTC的扩展数据记录(如老化计数器、故障发生次数等)。
请求格式:
19 06 [DTC_High] [DTC_Mid] [DTC_Low] [DTCExtDataRecordNumber]
肯定响应格式:
59 06 [DTC_High] [DTC_Mid] [DTC_Low] [Status] [ExtDataRecordNum] [Data...]
2.4 DTC状态位(StatusOfDTC)
DTC状态位是一个1字节的位掩码,每一位代表DTC的一种状态:
| Bit | 含义 | 说明 |
|---|---|---|
| 0 | testFailed | 当前测试失败 |
| 1 | testFailedThisOperationCycle | 本次操作循环测试失败 |
| 2 | pendingDTC | 待定DTC |
| 3 | confirmedDTC | 已确认DTC |
| 4 | testNotCompletedSinceLastClear | 自上次清除后测试未完成 |
| 5 | testFailedSinceLastClear | 自上次清除后测试失败 |
| 6 | testNotCompletedThisOperationCycle | 本次操作循环测试未完成 |
| 7 | warningIndicatorRequested | 请求警告指示 |
3. 输入输出参数
3.1 输入参数
| 控件 | 类型 | 说明 |
|---|---|---|
| 设备句柄 | U32 | 由TOOMOSS_OpenDev(CAN).vi返回 |
| 通道号 | 枚举(CAN1/CAN2) | 选择CAN通道 |
| 物理地址 | U32 | 请求报文ID |
| 响应地址 | U32 | 响应报文ID |
| 子功能 | 枚举 | 0x01/0x02/0x04/0x06/0x0A |
| 状态掩码 | U8 | 仅0x01/0x02时有效 |
| DTC编号 | U32(3字节) | 仅0x04/0x06时有效 |
| 记录号 | U8 | 仅0x04/0x06时有效(0xFF表示全部) |
3.2 输出参数
| 控件 | 类型 | 说明 |
|---|---|---|
| DTC数量 | U16 | 符合条件的DTC个数(0x01子功能) |
| DTC列表 | 字符串数组 | 故障码编码列表 |
| DTC状态 | U8数组 | 每个DTC对应的状态字节 |
| 原始数据 | U8数组 | ECU返回的完整响应数据 |
| 返回值 | I32 | 0成功,-1失败 |
| 错误信息 | 字符串 | 错误描述 |
4. 程序框图设计
4.1 整体流程
子功能选择 → 构造请求数据 → 调用TOOMOSS_SendAndWaitResp.vi
↓
判断响应类型(0x59/0x7F)
↓
解析响应数据(取决于子功能)
↓
输出DTC数量/列表/状态/原始数据
4.2 第一步:构造请求数据
根据子功能枚举值构造对应的请求数据:
| 子功能 | 请求数据 |
|---|---|
| 0x01 | [0x19, 0x01, StatusMask] |
| 0x02 | [0x19, 0x02, StatusMask] |
| 0x0A | [0x19, 0x0A] |
| 0x04 | [0x19, 0x04, DTC_High, DTC_Mid, DTC_Low, RecordNum] |
| 0x06 | [0x19, 0x06, DTC_High, DTC_Mid, DTC_Low, ExtRecordNum] |
使用创建数组函数组合各字节。


4.3 第二步:调用通信基座
将请求数据传递给TOOMOSS_SendAndWaitResp.vi:
| 参数 | 来源 |
|---|---|
| 设备句柄 | 子VI输入 |
| 通道号 | 子VI输入 |
| 物理地址 | 子VI输入 |
| 响应地址 | 子VI输入 |
| 请求数据 | 构造的请求数组 |
| 数据长度 | 数组大小 |
4.4 第三步:判断响应类型
肯定响应(首字节=0x59):
-
继续解析响应数据
-
子功能回声应与请求一致
否定响应(首字节=0x7F):
-
解析NRC,返回错误信息
-
常见NRC:0x12(子功能不支持)、0x13(报文长度错误)、0x22(条件不满足)

4.5 第四步:解析响应数据
4.5.1 解析0x01子功能响应
响应格式:59 01 [StatusMask] [DTCFormat] [Count_High] [Count_Low]
-
从索引2取DTCStatusAvailabilityMask
-
从索引3取DTCFormatIdentifier
-
从索引4-5取DTC数量(2字节大端)

4.5.2 解析0x02/0x0A子功能响应
响应格式:59 02/0A [StatusMask] [DTC1_3字节] [Status1] [DTC2_3字节] [Status2] ...
-
从索引2取DTCStatusAvailabilityMask
-
从索引3开始,每4字节为一组(3字节DTC编号 + 1字节状态)
-
将每组DTC编号转换为标准故障码
-
存储DTC列表和对应的状态

4.5.3 解析0x04子功能响应
响应格式:59 04 [DTC_3字节] [Status] [RecordNum] [Count] [DID_High] [DID_Low] [Data...]
-
提取DTC编号、状态、记录号
-
提取DID和数据对
5. 前面板设计

6. 典型调用示例
6.1 读取所有已确认DTC(0x02 + 掩码0x08)
输入配置:
-
子功能 = 0x02
-
状态掩码 = 0x08
实际发送 :19 02 08
期望响应 :59 02 FF 11 22 33 04 55 66 77 08 ...
解析结果:
-
DTC 0x112233 → P4386-33,状态0x04(已确认)
-
DTC 0x556677 → U5566-77,状态0x08(待定)
6.2 获取所有支持DTC数量(0x01 + 掩码0xFF)
输入配置:
-
子功能 = 0x01
-
状态掩码 = 0xFF
实际发送 :19 01 FF
期望响应 :59 01 FF 01 00 0A
解析结果:共10个DTC
6.3 读取指定DTC快照(0x04)
输入配置:
-
子功能 = 0x04
-
DTC编号 = 0x112233
-
记录号 = 0x01
实际发送 :19 04 11 22 33 01
期望响应 :59 04 11 22 33 04 01 02 F1 90 48 32 30 ...
7. 错误处理
| 错误场景 | 返回值 | 错误信息 |
|---|---|---|
| 设备句柄无效 | -1 | "设备句柄无效" |
| 通信超时 | -1 | "ECU未响应" |
| 否定响应 | -1 | 根据NRC返回对应信息 |
| 响应首字节非0x59非0x7F | -1 | "未知响应类型" |
8. 注意事项
| 要点 | 说明 |
|---|---|
| 会话要求 | 0x19服务通常可在默认会话下执行,但部分ECU要求扩展会话 |
| 多帧处理 | DTC列表可能超过单帧长度,通信基座已处理ISO-TP多帧 |
| 掩码含义 | 状态掩码中每一位代表DTC的一种状态,按位与匹配 |
| DTC数量 | 0x01返回的是数量,0x02返回的是完整列表 |
| 快照数据 | 不同ECU的快照DID和格式可能不同 |
9. 总结
TOOMOSS_SID19_ReadDTCInformation.vi封装了UDS 0x19读取DTC信息服务的核心子功能,是诊断上位机不可或缺的组成部分。与刷写上位机不同,诊断场景下对DTC的读取和解析是基础能力,该子VI提供了从请求构造到DTC标准化的完整链路。