J1939/J1587 CAN诊断排障:终端电阻、源地址与清故障实战 简介面向商用车与工程机械电控集成工程师、OEM 整车匹配人员及维修诊断技术人员的康明斯 Quantum 系列发动机技术文档对应 AEB 15.43 工程公告重点解决 J1587J1939 数据链路接入、故障码读取与诊断功能落地的问题。内容围绕 Quantum 诊断体系展开涵盖高级诊断、在线Onboard与离线Offboard诊断的适用场景并逐一说明 J1587 与 J1939 的报文格式、传输速率、错误检测机制以及 QSM11、QSX15 的 J1939 安装与线束连接要求同时指明与电子特性、OEM 组件接口、安装推荐等关联公告的查阅顺序便于按需延伸。压缩包共 1 个 PDF 文件约 240KB为 64 页英文原版工程公告篇幅紧凑、便于随查随用。已有 3563 人学习下载适合需要对照原文核对协议细节、梳理诊断流程或做集成方案评审的读者查阅。1. J1939 一上电就报“无通讯”先别换 ECM八成是终端电阻和屏蔽层在打架重型柴油机 J1939/J1587 通讯协议与诊断、CAN 通讯诊断与集成最容易在整机厂首次上电时翻车钥匙一拧仪表报“CAN 无通讯”PC 端服务工具连不上控制器故障灯要么全亮两秒后熄灭要么干脆不亮。现场第一反应常是换 ECM血泪经验是先把 120Ω 终端电阻、屏蔽层接地和 250K 波特率量一遍。这类故障适合刚接手 CAN 集成的开发者也适合被“偶发丢帧”折腾过的熟手。下面按读不到故障码、闪码对不上、清不掉故障、现场布线翻车几个场景拆开讲每个场景都给可照做的定位顺序。2. 读不到故障码J1939 与 J1587 两路串行口先分清再谈诊断诊断工具连不上不等于控制器坏了。很多现场把 J1939 和 J1587 当成同一路 CAN 来处理结果工具能亮灯、却读不到任何故障码。该系列控制器设计了两路独立串行通信口一路是 250 kbit/s 的 J1939另一路是 9600 baud 的 J1587二者在钥匙开关打开时都处于激活状态但物理层、波特率、节点数和诊断报文完全不是一回事。先把这两路分清后面的抓包、读码、清码才有意义。2.1 两个独立串口250K 与 9600 的物理层差异J1939 这边技术包里写得很明确J1939-11 物理层使用带 drain 线的屏蔽双绞线差分驱动总线速率 250 kbit/s最大总线长度 40 米同时最多 30 个节点连接J1587 基于 J1708速率 9600 baud最多 20 个节点连接。现场最常见的误用是把 J1587 的两根线接到 CAN 口上或者用 250K 的 CAN 接口去收 9600 的 J1587 数据最后看到“总线关闭”“错误帧暴涨”“一帧都收不到”就误判为 ECM 不响应。先确认接口类型和波特率比换任何件都快。项目J1939J1587速率250 kbit/s9600 baud物理层基础J1939-11屏蔽双绞线带 drainJ1708 基础最大节点数3020最大总线长度40 米按 J1708 布线限制现场以技术包拓扑为准诊断口J1939-13 规定的 9 针诊断口可提供 J1939同一诊断口也提供 J1587典型用途高速控制、信息共享、诊断、多路复用信息共享、诊断、专有通信清故障相关DM1 当前故障、DM4 历史/快照、DM11 清活动故障PID 与故障码读取按源地址和报文定义处理先把 CAN 口按 250K 拉起看看控制器本身有没有进入错误状态。下面这几条命令适合在 Linux 现场机上快速确认接口是否正常不涉及任何诊断仪私有配置。# 现场先把 CAN 口按 J1939 的 250 kbit/s 拉起 sudo ip link set can0 down sudo ip link set can0 type can bitrate 250000 restart-ms 100 sudo ip link set can0 up # 看状态、错误计数和是否进入 bus-off ip -details -statistics link show can0bitrate 250000对应 J1939 的高速网络restart-ms 100表示总线关闭后 100 毫秒尝试自动恢复方便现场观察是不是持续 bus-offip -details -statistics link show can0重点看 state 是否ERROR-ACTIVE以及 bus-error、error-warning、error-passive 是否在涨。如果接口一拉起就 bus-off先回到线束和终端电阻不要继续读码。注意J1587 不是 CAN不能用这条命令去“收 J1587”它只能帮你确认 J1939 这一路有没有被正确配置。2.2 用最小抓包脚本确认波特率、源地址和 PGN接口状态正常但仍然读不到目标控制器的故障码下一步不是猜而是看总线上到底有没有扩展帧、源地址是多少、PGN 是不是诊断报文。现场我一般会用 python-can 写一个最小抓包脚本只做三件事过滤扩展帧、解出源地址、按 J1939 的 PDU1/PDU2 规则还原 PGN。这个脚本不依赖诊断仪能快速判断“总线是死的”还是“报文有、但源地址不对”。import can def j1939_pgn(arb_id: int) - int: # 29 位 J1939 标识符优先级 26-28DP 24PF 16-23PS 8-15源地址 0-7 dp (arb_id 24) 0x01 pf (arb_id 16) 0xFF ps (arb_id 8) 0xFF if pf 240: # PDU1PS 是目标地址PGN 不包含 PS return (dp 16) | (pf 8) # PDU2PS 是组扩展PGN 包含 PS return (dp 16) | (pf 8) | ps bus can.Bus(interfacesocketcan, channelcan0, bitrate250000) for msg in bus: if not msg.is_extended_id: continue pgn j1939_pgn(msg.arbitration_id) src msg.arbitration_id 0xFF print(fPGN{pgn:06X} SRC{src:02X} DLC{msg.dlc} DATA{msg.data.hex( )})这段代码的channelcan0要换成现场实际接口名bitrate250000必须与 J1939 一致is_extended_id过滤掉标准帧避免把无关 CAN 帧混进来j1939_pgn()里按 PF 是否小于 240 区分 PDU1 和 PDU2PDU1 的 PS 是目标地址不能算进 PGN。运行后如果一帧扩展帧都没有先查 CAN_H/CAN_L、终端电阻和控制器供电如果有大量报文但没有目标源地址查节点地址冲突、诊断口错线或控制器是否真的上电。这个脚本只做现场粗筛真正清故障前还要按技术包里的报文表和源地址表核对。2.3 9 针诊断口线序与“能上电但读不到”的常见错线J1939-13 规定的 9 针诊断口会同时提供 J1939、J1587 以及第二路 CAN 网络的连接能力现场最容易出问题的地方是“工具灯亮、就是读不到”。常见错线有三类第一CAN_H 和 CAN_L 接反某些收发器在短距离下还能勉强通信但一旦线长增加或节点变多就开始丢帧第二把屏蔽层当成信号地或者屏蔽层两端都接地形成地环路表现为加油门、开大灯、启停大负载时通信时好时坏第三诊断口取电导致地偏移工具指示灯亮但差分电平已经偏离读码超时。解决顺序很简单断电量两个 120Ω 终端电阻并联值是否接近 60Ω按技术包拓扑图核对 9 针诊断口定义确认屏蔽层和 drain 线处理方式再单独给诊断工具供电复测。不要凭线色猜线色在不同线束厂之间并不可靠。3. 故障灯闪码对不上闪码节奏、灯策略和故障快照的坑闪码读出来是 244故障码表里却查不到对应部件或者明明只闪了一个码清完故障第二天又出现。这类问题多半不是故障码表印错了而是闪码节奏、灯策略和当前/历史状态混在一起看了。该系列控制器的在线诊断会在钥匙开关打开、机器运行过程中检测故障故障激活时写入内存并记录发动机参数快照同时按严重程度点亮警告灯、停机灯、维护灯或水油分离灯。读闪码之前先确认自己进的是诊断模式而不是在看上电自检或维护提醒。3.1 闪码进入条件钥匙 ON、发动机不转、踏板 0-100% 三次技术包给出的进入条件很具体钥匙开关打开发动机不运转。使用诊断开关进入时开关打开后 ECM 会自动闪出第一个故障码诊断增量/减量开关用来向前或向后切换活动故障使用油门踏板进入时踏板要从 0 到 100% 循环三次进入诊断模式后继续循环踏板可以向前切换活动故障。闪码本身是三位十进制按百位、十位、个位分组闪组与组之间有停顿循环重复。比如故障码 244 记录为 2 次、4 次、4 次故障码 112 记录为 1 次、1 次、2 次。现场翻车最多的情况是发动机已经启动、踏板没踩到 100%、或者把组间长停顿也数成了一次闪。def decode_flash(groups): # groups 是手工记录的三组连续闪灯次数例如 [2, 4, 4] - 244 if len(groups) ! 3: raise ValueError(闪码应按百位、十位、个位记录三组) if any(n 0 or n 9 for n in groups): raise ValueError(每组只能是 0-9 次闪烁) return groups[0] * 100 groups[1] * 10 groups[2] print(decode_flash([2, 4, 4])) # 244 print(decode_flash([1, 1, 2])) # 112这个函数只负责把人工记录的三组闪烁次数转成十进制故障码不替你判断当前故障还是历史故障。groups必须按百位、十位、个位顺序填组内连续闪、组间停顿不算数字如果记录到 10 次以上说明停顿判断错了重新进诊断模式再读。现场最好两个人配合一个人看灯一个人按“组间停顿”分隔记录读完后让闪码循环两遍再确认避免把自检闪烁或维护灯闪烁混进故障码。3.2 灯策略差异警告灯、停机灯、维护灯/发动机保护灯、两灯策略该系列控制器最多使用五个指示灯其中维护灯和发动机保护灯在不同机型上二选一。警告灯是琥珀色提示需要及时关注的操作员消息也参与故障码闪出停机灯是红色提示需要立即处理的关键消息同样参与闪码等待启动灯表示进气预热正在进行水油分离灯提示燃油里有水需要放水维护灯在上电时闪可能是换机油提醒运行时点亮也可能是低优先级故障发动机保护灯在保护故障时点亮部分机型可以通过布线把保护故障映射到红色停机灯形成两灯策略。两灯策略只改故障灯布线不改软件或校准但现场如果没核对布线就会把保护故障当成普通停机故障。灯作用容易误判的点警告灯重要操作员消息参与闪码看到警告灯亮就只查闪码忽略当前故障条件停机灯关键消息要求立即响应参与闪码把保护故障映射过来的红灯当成普通停机故障维护灯/发动机保护灯不同机型二选一维护灯可能提示换油把上电时维护灯闪当成故障码等待启动灯进气预热进行中冷启动时误判为故障灯水油分离灯燃油含水只清码不排水故障反复出现看到红灯不要直接下结论先按机型核对灯策略是原生停机灯还是保护灯通过布线映射到红灯维护灯闪是上电换油提醒还是运行时低优先级故障水油分离灯亮时先排水再清码。技术包里提到如果发动机保护灯信号还去控制其他功能比如车辆推进电路需要在线路里加二极管这类改线如果没做灯亮和实际保护动作可能对不上。3.3 闪码读数脚本/记录表把闪烁转成 DTC闪码读出来后不要只记一个数字。现场真正有用的是“故障码 灯类型 当前/历史 快照参数”。技术包里的故障检测会在故障激活时记录发动机参数快照这些参数是后面复现问题的黑匣子。我的做法是手边放一张固定记录表每读到一个码就填一行清码前先拍照或抄下来清码后路试复现再对比快照里的转速、油温、油压、电压和负载。时间灯类型三组闪烁故障码当前/历史快照关键参数清码后是否复现上电后停机灯2/4/4244当前转速、油温、油压、电压路试 10 分钟复现怠速警告灯1/1/2112历史转速、电压清码后未复现记录时把“当前”和“历史”分开当前故障说明条件仍在历史故障可能是间歇性线束或接插件问题。清码后立刻复现的不要反复清先查故障条件清码后跑一段时间才复现的重点查线束走向、接插件锁止、屏蔽层和搭铁。故障码表要按机型、校准版本和年份匹配同一串数字在不同版本表里可能指向不同部件拿旧表查新控制器最后只会把自己带进沟里。4. J1939 报文能收但清不掉故障DM4/DM11 与源地址不匹配抓包能看到 DM1诊断仪也能显示当前故障但一按清故障就超时或者清完立刻又跳出来。这个场景在整机厂联调时很常见根因通常不在“清故障按钮坏了”而在源地址、报文类型和总线负载。J1939 诊断报文不是广播一声“大家把故障都清掉”清活动故障需要目标控制器认可源地址和报文内容DM4 承载的是历史故障和冻结帧信息清掉当前故障不等于历史记录消失总线负载高时诊断报文还会延迟甚至丢帧。4.1 清故障不是广播源地址、目标地址和 DM4 的关系先分清三类报文DM1 用来报当前活动故障DM4 用来报历史故障和冻结帧DM11 用来清活动故障。技术包在“通过数据链路清故障的支持消息和源地址”一节里专门强调了源地址现场如果用一个不被目标控制器认可的源地址发清故障请求表现就是发得出去、没有响应。常见做法是先抓 DM1记下报文的源地址和目标地址再看诊断工具或网关用的是哪个源地址清故障时用匹配的源地址发 DM11清完让钥匙开关循环一次再读 DM1 确认是否真的清掉。清完立即复现的说明当前故障条件还在不要把它当成清码失败。报文PGN十进制用途现场注意DM165226当前活动故障先看它判断故障是否仍在DM465229历史故障/冻结帧清活动故障不等于清历史记录DM1165235清活动故障源地址要匹配清后钥匙循环再读注意清故障前先确认 DM1 是否仍为活动状态。当前条件没消失时清码成功也会马上复现反复清只会掩盖根因。4.2 PGN 过滤先看 DM1 当前故障再看 DM4 历史现场抓包不要把所有报文都打出来250K 总线上诊断报文和高频广播混在一起肉眼很容易看漏。下面这段脚本只保留 DM1 和 DM4并把源地址一起打出来方便对照技术包里的源地址表。import can DM1 0xFECA # 65226当前活动故障 DM4 0xFECD # 65229历史故障/冻结帧 def j1939_pgn(arb_id: int) - int: dp (arb_id 24) 0x01 pf (arb_id 16) 0xFF ps (arb_id 8) 0xFF if pf 240: return (dp 16) | (pf 8) return (dp 16) | (pf 8) | ps bus can.Bus(interfacesocketcan, channelcan0, bitrate250000) for msg in bus: if not msg.is_extended_id: continue pgn j1939_pgn(msg.arbitration_id) if pgn in (DM1, DM4): src msg.arbitration_id 0xFF print(fPGN{pgn:06X} SRC{src:02X} DATA{msg.data.hex( )})DM1和DM4用十六进制常量表示过滤时只保留这两类诊断报文j1939_pgn()仍然按 PDU1/PDU2 还原 PGN避免把目标地址误算进 PGNSRC是源地址必须和清故障时使用的源地址对照。运行后如果只看到 DM1、没有 DM4说明该控制器当前没有历史故障或冻结帧不代表清码失败如果 DM1 一直有、DM11 发出去没反应重点查源地址和总线负载不要先怀疑故障码表。4.3 网络负载与多路复用250K 总线被塞满时的表现J1939 是 250 kbit/s 的高速网络最大 30 个节点技术包里专门有网络利用率章节还区分了非多路复用和多路复用报文。现场加节点、加高频广播、加多路复用诊断消息之后总线负载上来表现不一定是完全断线而是诊断报文延迟、清故障超时、DM1 偶尔丢一帧。遇到这种“时好时坏”先抓 10 秒统计帧率和错误计数再看是否有大量非诊断报文占着总线如果是多路复用报文核对技术包里的复用表和发送周期别把高频广播当普通状态量一直发。现象可能原因验证方式DM1 偶尔丢一帧总线负载高或错误帧干扰看 error-warning/error-passive 是否增长清故障超时源地址不匹配或总线忙抓 DM11 请求和响应核对源地址加节点后间歇离线节点数超限、支线过长、终端位置不对统计节点数断电量 60Ω查支线多路复用参数跳变复用表或发送周期不匹配对照技术包网络利用率章节5. 集成现场最容易翻车的五件事避坑清单这一章不按报文讲按现场踩过的坑讲。每个坑都按“现象、原因、解决”记录方便下次上机前逐条排除。很多问题不是控制器固件造成的而是线束、接地、节点数、诊断口取电和故障码表版本这些看起来不起眼的地方。5.1 终端电阻量到 60Ω 就放心带电测量和支线过长会骗你现象断电量两个 120Ω 终端电阻并联值接近 60Ω上电后还是偶发丢帧诊断仪隔几分钟掉一次。原因60Ω 只说明直流终端大致正常不能说明支线长度、节点数、屏蔽层处理和终端电阻位置都正确带电测量还会把收发器内部电路并联进来读数看着对实际 topology 已经不对。解决断电测量确认两个终端电阻分别装在总线两端统计节点数不超过 30总线长度不超过 40 米支线尽量短上电后用接口错误计数看是否持续增长而不是只看能不能收一帧。5.2 屏蔽层多点接地drain 线不是随便接现象怠速通信正常一加油门或开大灯就开始丢帧故障码时有时无。原因屏蔽层两端接地形成地环路或者把屏蔽层当信号地、当电源地使用drain 线处理不符合技术包拓扑干扰直接耦合到差分对上。解决按技术包里的典型拓扑核对屏蔽层和 drain 线确认搭铁点干净、无漆、无虚接不要用屏蔽层替代地线诊断口和控制器地之间的压差要量超过合理范围先查搭铁和供电不要继续清码。5.3 节点数和支线长度30 节点不是随便挂现象原来网络正常增加一个节点后整车网络间歇性离线诊断仪偶尔能连、偶尔超时。原因J1939 最多 30 个节点、最大 40 米J1587 最多 20 个节点节点数超限、支线过长、终端电阻不在两端都会让信号反射和边沿变差。解决画一张实际拓扑图统计每个节点的支线长度和终端位置超过节点数就加网关分流不要硬挂支线过长就改线束走向改完后用错误计数和 DM1 连续性验证不要只测静态电阻。5.4 诊断口取电与地偏移工具能亮但读不到现象诊断工具插上后指示灯亮软件一直提示连接超时换一个工具还是读不到。原因诊断口取电导致地偏移或者诊断口地线虚接、保险接触不良工具电源灯亮但差分接收已经失效。解决先单独给诊断工具供电复测量诊断口地与控制器地之间的压差检查保险和接插件锁止按 J1939-13 的 9 针定义核对 J1939、J1587 和第二路 CAN 的引脚不要凭线色猜。工具能亮不代表物理层正常能收到一帧也不代表能稳定清码。5.5 故障码表版本与机型不匹配同一个码两种解释现象闪码读出来是 244查表指向的部件和实际症状对不上清码后复现换一张表又变成另一种解释。原因故障码表按机型、年份和校准版本区分技术包里的故障码表只是对应范围内的版本现场拿旧表查新控制器或者把历史故障当当前故障都会得出错误结论。解决用机型铭牌和校准信息匹配故障码表先读 DM本文还有配套的精品资源点击获取