UDS 设备配置
在平台上接入 CAN/UDS 设备分两步:先在工位页面**「配置 CAN 设备」绑定仪器,再在仪器指令库中「编辑读取指令 / 编辑设置指令」**创建指令。UDS(Unified Diagnostic Services,ISO 14229)是车用 ECU 诊断标准协议:平台发出「读 DID / 写 DID」请求,ECU 应答数据,多帧组包拆包由系统自动完成。
本文以一台虚构的 DEMO_PS3000 高压直流电源(CAN 总线 500 kbps)为贯穿示例,读哪个量、写哪个设置,直接对照第 6 节速查表复制即可。
相关页面:仪器兼容表、PMBus 设备配置、PLC 设备配置。
1. 第一步:配置 CAN 设备
在工位页面打开目标 CAN 仪器的**「配置 CAN 设备」**弹窗,按下面填写后保存。
1.1 弹窗字段对照
| 弹窗字段 | 必填 | 填写说明 |
|---|---|---|
| 协议 | 是 | 二选一:Raw(原始帧) / UDS(诊断协议)。读/写 DID 必须选 UDS;误选 Raw 指令会按原始 CAN 帧解析,模板失败 |
| 资源 | 是 | 下拉选择,如 can0 |
| 仪器型号 | 是 | 下拉选择仪器型号,如 DEMO_PS3000 |
| 仪器序列号 | 是 | 该台仪器的唯一编号,如 aabb;同一总线上不同仪器用不同序列号区分 |
| 测试端地址 | 是 | 诊断请求 CAN ID(测试端发出),如 0x7DF |
| 设备地址 | 是 | ECU 应答 CAN ID(设备返回),如 0x7E8 |
| 波特率 | 建议核对 | 下拉选择,与总线一致,常见 500000 |
| 超时时间(s) | 建议核对 | 单位秒,默认 1;ECU 响应慢或多帧时适当加大(2~5) |
| 字节序 | 可选 | 大端(Big)(默认)/ 小端(Little),对该仪器所有读写指令统一生效 |
| 字序 | 可选 | 大端(Big)(默认)/ 小端(Little),主要用于 32/64 位数值,一般保持默认 |
点「设置高级参数 ∨」展开波特率、超时时间、字节序、字序;点「收起 ∧」折叠。
1.2 地址怎么填
两个地址以设备诊断规范(或设备厂家 FAE 提供)为准:
| 场景 | 测试端地址 | 设备地址 | 说明 |
|---|---|---|---|
| OBD 功能寻址 | 0x7DF | 0x7E8 | 广播请求,常见诊断口场景 |
| 物理寻址 | 0x7E0 | 0x7E8 | 点对点;请求 ID 以 ECU 规范为准 |
| 扩展帧(29 位) | 0x18DA00F1 | 0x18DAF100 | ID 大于 0x7FF 时按扩展帧处理 |
本文示例 DEMO_PS3000 填:测试端地址 0x7F、设备地址 0x70(以该设备诊断规范为准)。
重要:字节序 / 字序只能在这个弹窗里配置,不能写在单条指令的模板或参数里。同一总线上若不同 DID 字节序不同,需拆成两个仪器(不同序列号)分别绑定。
1.3 保存后检查清单
- 协议选了 UDS(诊断协议)(不是 Raw)
- 测试端地址 / 设备地址与诊断规范一致,且未填反
- 资源与实际接好的 CAN 通道一致
- 波特率与总线一致
2. 第二步:编辑读取指令(服务 0x22)
在仪器指令库中新增读取指令,页面分三块:基本信息(指令名称 / 指令编码 / 示例模板 / 指令模板 / 指令说明)、测试参数、测试指标(点「添加指标」新增,字段:指标名称 / 指标编码 / 指标类型 / 指标分类 / 指标单位 / 模拟数据 / 解析规则)。核心是填好指令模板和测试指标。
2.1 模板格式
READ:DID:0x<DID>:<数据类型>| 段 | 含义 |
|---|---|
READ:DID | 固定前缀,表示 UDS 读 DID |
0x<DID> | 数据标识符,如 0xF190(也支持十进制写法,如 61840) |
<数据类型> | 如何解码数据域,见下表 |
数据类型与测试指标选型:
| 数据类型 | 适用场景 | 指标类型 | 指标分类参考 |
|---|---|---|---|
STRING | VIN、软件号等文本 | 字符串 | 字符串 |
HEX | 先看原始字节、结构体未拆解 | 字符串 | 字符串 |
UINT8 / INT8 | 单字节状态、偏移 | 数值 | 数字 |
UINT16 / INT16 | 转速、计数等双字节 | 数值 | 数字 |
UINT32 / INT32 | 里程等四字节 | 数值 | 数字 |
FLOAT / DOUBLE | 浮点物理量 | 数值 | 按物理量选 |
BOOL | 标志位(按整字节最低位) | 数值 | 数字 |
单字段读时:测试指标有且仅有 1 项。
2.2 配置示例:读取温度(含多字段换算)
以 DEMO_PS3000「读取温度」为例(对应「编辑读取指令」页面截图)——一个 DID 返回打包结构,3 路温度原始值各除以 10 得到 ℃,共 6 条测试指标:
| 项目 | 填写 |
|---|---|
| 指令名称 | 读温度(Outlet/Inlet/Max) |
| 指令编码 | DEMO_TEMP |
| 示例模板 | (与指令模板相同,系统自动带出) |
| 指令模板 | READ:DID:0x0007;FIELD:22:2:UINT16;FIELD:24:2:UINT16;FIELD:26:2:UINT16;EXPR:outlet_raw/10.0;EXPR:inlet_raw/10.0;EXPR:max_raw/10.0 |
| 指令说明 | DID 0x0007 ReadTemperature |
测试参数:不添加(页面显示「暂无参数」)。
测试指标(点「添加指标」添加 6 条,顺序与模板中 FIELD/EXPR 段一一对应):
| 顺序 | 指标名称 | 指标编码 | 指标类型 | 指标分类 | 指标单位 | 小数位 |
|---|---|---|---|---|---|---|
| 1 | OutletRaw | outlet_raw | 数值 | 数字 | / | 0 |
| 2 | InletRaw | inlet_raw | 数值 | 数字 | / | 0 |
| 3 | MaxRaw | max_raw | 数值 | 数字 | / | 0 |
| 4 | Outlet | outlet | 数值 | 温度 | ℃ | 1 |
| 5 | Inlet | inlet | 数值 | 温度 | ℃ | 1 |
| 6 | Max | max | 数值 | 温度 | ℃ | 1 |
要点:
- EXPR 中的变量名必须是前面某条测试指标的指标编码(如
outlet_raw) - FIELD 偏移从数据域第 0 字节起算(系统已自动跳过响应头),不要把响应头字节算进去
- 实测参考:outlet≈29.7 ℃、inlet≈25.5 ℃、max≈57.5 ℃
- 换算字段务必填小数位(如 1),否则浮点可能被格式化为整数
2.3 配置示例:读取单字段(简单场景)
不需要拆字段、换算时,一条模板只配 1 条测试指标。以读转速为例:
| 项目 | 填写 |
|---|---|
| 指令名称 | 读取转速 |
| 指令编码 | get_read_rpm |
| 指令模板 | READ:DID:0x4101:UINT16 |
| 指标名称 / 编码 | 转速 / rpm |
| 指标类型 / 分类 / 单位 | 数值 / 数字 / rpm |
ECU 返回「原始计数」、希望按物理量展示时,在测试指标上配 scale / 小数位 / 单位:如解码值 5000 显示 5.00 krpm —— scale 0.001、小数位 2、单位 krpm。换算公式不是简单乘系数(例如 x/10 - 273.15)时,请用模板里的 EXPR 段,不要硬套 scale。
3. 第三步:编辑设置指令(服务 0x2E)
在仪器指令库中新增设置指令(写入)。写操作一般不需要测试指标,但通常要点「添加参数」把写入值开放为执行时填写。
3.1 模板格式
WRITE:DID:0x<DID>:<数据类型>:<写入值>3.2 配置示例:写风扇占空比
以 DEMO_PS3000「写风扇占空比」为例:
| 项目 | 填写 |
|---|---|
| 指令名称 | 写风扇占空比 |
| 指令编码 | DEMO_FAN_DUTY |
| 示例模板 | WRITE:DID:0x000E:UINT16:{{duty}} |
| 指令模板 | WRITE:DID:0x000E:UINT16:{{duty}} |
| 指令说明 | DID 0x000E WriteFanSpeed duty 0-100(慎用,未写测) |
测试参数(点「添加参数」,弹窗内填写):
| 字段 | 填写 | 说明 |
|---|---|---|
| 参数名称 | 风扇占空比 | 执行时显示的中文名 |
| 参数编码 | duty | 必须与模板中的占位符一致 |
| 参数分类 | 数字 | 下拉选择 |
| 默认单位 | % | 按物理量填 |
| 参数类型 | 数值 | 下拉选择 |
| 参数形式 | 自定义 | 有固定几种取值时改选「选项」 |
| 值范围 | 0 ~ 100 | 占空比 0–100 |
| 参数说明 | 按设备实际含义填写 | 给同事看的备注 |
页面提示「指令模板使用参数标识码或者指标标识码,对应的测试参数和测试指标标识为例必填」——含义即:模板里出现
{{xxx}},「测试参数」中必须有编码为xxx的参数;读取模板解出的每个值,「测试指标」中必须有对应编码的指标。
3.3 写入速查
| 需求 | 指令模板 |
|---|---|
| 写字节标志 | WRITE:DID:0x0100:UINT8:1 |
| 写有符号温度偏移 | WRITE:DID:0x0101:INT8:-10 |
| 写浮点电压 | WRITE:DID:0x4300:FLOAT:13.8 |
| 写字符串标签 | WRITE:DID:0xF191:STRING:ABC |
| 写原始十六进制 | WRITE:DID:0x0500:HEX:01020304(含空格亦可:01 02 03 04) |
写入值的编码格式遵循设备绑定的字节序 / 字序(默认大端)。写入成功后平台返回成功即可。
4. 平台 UDS 指令能力
平台 UDS 指令模板当前支持以下两个服务:
| 操作 | UDS 服务 | 平台指令类型 | 模板前缀 |
|---|---|---|---|
| 读 DID | 0x22 ReadDataByIdentifier | 读取指令 | READ:DID: |
| 写 DID | 0x2E WriteDataByIdentifier | 设置指令 | WRITE:DID: |
诊断会话切换(0x10)、安全访问(0x27)、例程控制(0x31)、DTC 读取(0x19)、刷写(0x34~0x37)等服务不能通过指令模板配置。
ECU 响应超过单帧长度时(如读 VIN、固件版本),系统自动完成多帧组装,无需在指令里额外配置。
5. 常用进阶
5.1 多字段拆解规则
判定规则:模板里出现 ; → 多字段;否则 → 单字段。
READ:DID:0x<DID>;FIELD:<偏移>:<长度>:<数据类型>[;FIELD:...][;EXPR:<表达式>]| 规则 | 说明 |
|---|---|
| 偏移起点 | 数据域第一个字节(系统已自动跳过响应头) |
| 指标数 = 段数 | 每个 FIELD / EXPR 对应一条测试指标,顺序一一对应 |
| 字节序 | 用设备绑定弹窗里配置的字节序,不要在 FIELD 末尾写 little |
按 bit 拆解:FIELD:<字节偏移>:1:BOOL:<位> 从数据域某字节取出单个位(0/1),一位对应一条测试指标,指标名称承担具名含义。位范围每段 0~7;跨字节(bit8~15)用字节偏移定位(bit8 → 偏移 1、位 0)。
示例——读取综合告警 READ:DID:0x2000;FIELD:0:1:BOOL:0;FIELD:0:1:BOOL:1;FIELD:1:1:BOOL:0,配 3 条指标:fan_alarm 风扇告警、temp_alarm 温度告警、dcdc_alarm DCDC 告警。数据域 02 01 → 风扇告警 0(bit0)、温度告警 1(bit1)、DCDC 告警 1(字节 1 bit0)。
5.2 多字段易错点
| 错误做法 | 正确做法 |
|---|---|
| 多字段但测试指标只有 1 项(或数量对不上) | 每个 FIELD/EXPR 配一条指标 |
在 FIELD 末尾写 :little | 在「配置 CAN 设备」里把字节序设为 小端(Little) |
| 偏移从含响应头的整帧起算 | 从数据域第 0 字节起算 |
单字段写成 READ:0xF190:STRING(缺 DID) | 必须是 READ:DID:0xF190:STRING |
| EXPR 用了未声明的变量名 | 变量名必须是前面某条指标的指标编码 |
| 换算指标不填小数位 | 浮点结果可能显示成整数,换算字段务必填小数位 |
6. 全量填写速查
- 同一条命令既能读又能写时,表中拆成两行,分别在「编辑读取指令」「编辑设置指令」页面创建。
- 读取指令:测试指标必填;设置指令:一般不添加测试指标,写入值用测试参数开放。
- 指令模板请原样复制,不要改写成指令编码。
6.1 常用读取(照抄建指令)
| 界面 | 指令名称 | 指令编码 | 指令模板 | 测试指标(编码 / 名称 / 类型 / 单位 / 小数位) |
|---|---|---|---|---|
| 读取指令 | 读取VIN码 | get_read_vin | READ:DID:0xF190:STRING | vin / VIN码 / 字符串 / / / — |
| 读取指令 | 读取原始数据 | get_read_raw | READ:DID:0xF190:HEX | raw / 原始数据 / 字符串 / / / — |
| 读取指令 | 读取单字节状态 | get_read_status | READ:DID:0x0100:UINT8 | status / 状态 / 数值 / / / 0 |
| 读取指令 | 读取温度偏移 | get_read_temp_offset | READ:DID:0x0101:INT8 | temp_offset / 温度偏移 / 数值 / ℃ / 0 |
| 读取指令 | 读取转速 | get_read_rpm | READ:DID:0x4101:UINT16 | rpm / 转速 / 数值 / rpm / 0 |
| 读取指令 | 读取里程 | get_read_odometer | READ:DID:0x4200:UINT32 | odometer / 里程 / 数值 / km / 0 |
| 读取指令 | 读取电压 | get_read_voltage | READ:DID:0x4300:FLOAT | voltage / 电压 / 数值 / V / 2 |
| 读取指令 | 读取布尔标志 | get_read_flag | READ:DID:0x0102:BOOL | flag / 标志 / 数值 / / / 0 |
6.2 DEMO_PS3000 示例指令(已验证)
以下指令已在 DEMO_PS3000 样机上验证通过(对应 1.2 节绑定示例):
| 界面 | 指令名称 | 指令编码 | 指令模板 | 测试指标 |
|---|---|---|---|---|
| 读取指令 | 读硬件版本 | DEMO_HW_REV | READ:DID:0x0003:UINT8 | hw_rev / HwRev / 数值(实测 0) |
| 读取指令 | 读包版本 | DEMO_PACK_REV | READ:DID:0x0011:HEX | pack_rev / PackRev / 字符串(实测 07080819) |
| 读取指令 | 读固件版本 | DEMO_FW_REV | READ:DID:0x0000:HEX | fw_rev / ApplFblFwRev / 字符串(实测 24 字节 HEX,多帧自动组装) |
| 读取指令 | 读六路风扇 | DEMO_FAN | READ:DID:0x000F;FIELD:0:2:UINT16;FIELD:2:2:UINT16;FIELD:4:2:UINT16;FIELD:6:2:UINT16;FIELD:8:2:UINT16;FIELD:10:2:UINT16 | fan1~fan6 / 数值 / rpm / 0(实测约 11500~12000 rpm) |
| 读取指令 | 读温度 | DEMO_TEMP | READ:DID:0x0007;FIELD:22:2:UINT16;FIELD:24:2:UINT16;FIELD:26:2:UINT16;EXPR:outlet_raw/10.0;EXPR:inlet_raw/10.0;EXPR:max_raw/10.0 | 见2.2 节 6 条指标 |
| 读取指令 | 读AC输入(精简) | DEMO_INPUT_SIMPLE | READ:DID:0x002E;FIELD:0:2:UINT16;FIELD:6:2:UINT16;FIELD:18:2:UINT16;FIELD:20:2:UINT16;EXPR:vin_ab/100.0;EXPR:iin_a/100.0;EXPR:freq_raw/10.0 | vin_ab、iin_a、pin_total(W)、freq_raw 原始值 + vin_ab_v(V, 2 位)、iin_a_a(A, 2 位)、freq_hz(Hz, 1 位) |
| 设置指令 | 写风扇占空比 | DEMO_FAN_DUTY | WRITE:DID:0x000E:UINT16:{{duty}} | 无指标;参数 duty(数值,0~100,单位 %) |
6.3 写入(照抄建指令)
| 界面 | 指令名称 | 指令编码 | 指令模板 | 测试参数 |
|---|---|---|---|---|
| 设置指令 | 设置转速限制 | set_rpm_limit | WRITE:DID:0x4101:UINT16:500 | 无(固定值)或 rpm |
| 设置指令 | 设置字节标志 | set_flag | WRITE:DID:0x0100:UINT8:1 | 无 |
| 设置指令 | 设置温度偏移 | set_temp_offset | WRITE:DID:0x0101:INT8:-10 | 无 |
| 设置指令 | 设置浮点电压 | set_voltage | WRITE:DID:0x4300:FLOAT:13.8 | 无 |
| 设置指令 | 设置字符串标签 | set_label | WRITE:DID:0xF191:STRING:ABC | 无 |
| 设置指令 | 写原始十六进制 | set_raw_data | WRITE:DID:0x0500:HEX:01020304 | 无 |
| 设置指令 | 动态写 DID | set_did_value | WRITE:DID:{{did}}:UINT16:{{value}} | did、value |
7. 填错了怎么办
指令执行失败时,优先看返回的提示信息:
| 现象 / 提示关键词 | 可能原因 | 处理建议 |
|---|---|---|
| 超时 / 读取超时 | 总线不通、地址填反、波特率不对、超时过短、设备未上电 | 查接线;核对测试端地址 / 设备地址;加大超时时间;看工位 CAN 设备日志确认是否有收发 |
UDS 否定响应: … (0x31) | DID 不存在或当前条件不允许 | 核对 DID;确认设备是否允许该请求 |
UDS 否定响应: … (0x22) | 条件不满足 | 检查设备运行状态 |
UDS 否定响应: … (0x33) | 安全访问未通过 | 该 DID 有写保护,需先通过安全访问(当前不支持) |
UDS 缺少测试端地址/设备地址 | 绑定时未配齐两个地址 | 回到「配置 CAN 设备」补全测试端地址 / 设备地址 |
UDS 读/写模板格式错误 | 模板少写 DID: 或段数不对 | 对照第 2/3 章格式重写 |
UDS 读操作缺少 replys / 段数与指标不一致 | 读取指令未配指标,或多字段数量对不上 | 单字段 1 项;多字段段数 = 指标数 |
FIELD 位索引非法: "little" | 把字节序写进了 FIELD | 删掉 FIELD 末尾的 little/big,改在「配置 CAN 设备」里配置 |
UDS 数据解码失败 | 数据类型与实际数据长度不符 | 改用 HEX 先看长度,再选对类型或改用 FIELD 拆解 |
常见否定响应码(NRC)速查
| NRC | 含义 | 配置侧常见处理 |
|---|---|---|
0x11 | 服务不支持 | 确认设备是否支持 0x22 / 0x2E |
0x13 | 长度/格式错误 | 检查写入值与数据类型是否匹配 |
0x22 | 条件不正确 | 检查设备运行状态 |
0x31 | 请求超出范围 | 核对 DID |
0x33 | 安全访问拒绝 | 该 DID 可能有安全保护 |
0x78 | 响应挂起 | 适当增大超时时间后重试 |
自查顺序(建议)
- 协议是否选了 UDS,测试端地址 / 设备地址是否与诊断规范一致
- 用最简单的读(如
HEX或已知合法 DID)验证通路 - 再细化数据类型 / FIELD / EXPR
- 仍失败时打开工位 CAN 设备日志,核对是否有请求发出、是否收到响应
8. 配置流程速览
准备 DID / CAN ID / 波特率(来自设备诊断规范)
↓
配置 CAN 设备:协议=UDS + 测试端地址/设备地址 + 波特率/超时时间/字节序/字序
↓
编辑读取指令:READ:DID:0x....:<数据类型> + 测试指标
或编辑设置指令:WRITE:DID:0x....:<数据类型>:<写入值>(+ 测试参数)
↓
需要拆字段 / 复杂换算?
→ 使用 FIELD / EXPR(段数对齐测试指标)
↓
失败 → 按第 7 章排查(地址 → 超时 → NRC → 模板)