4、参数组编号PGN:PGN定义、PGN计算方式、常用PGN分类与查询方法
4.1 PGN到底是什么?
好,咱们直接切入正题。PGN,全称是Parameter Group Number,参数组编号。说白了,它就是J1939协议里给每个“数据包”贴的一个身份证号。
你想想看,CAN总线上跑着那么多消息,发动机转速、车速、刹车状态……怎么区分谁是谁?靠的就是PGN。每个PGN对应一组特定的参数,比如“发动机电子控制器1”这个PGN,里面就包含了转速、扭矩、燃油率这些数据。
我个人习惯把PGN理解成“数据信封的编号”。信封里装什么内容,编号说了算。接收方一看PGN,就知道该用哪种解析方式去拆信。
核心要点:PGN是J1939协议数据标识的核心,它决定了数据的含义和结构。
4.2 PGN的计算方式
很多新手看到PGN计算就头大。其实没那么复杂,我来给你拆解一下。
PGN是29位CAN ID中的一部分。J1939的29位ID结构是这样的:
优先级(3位) | 保留位(1位) | 数据页(1位) | PDU格式(8位) | 特定PDU(8位) | 源地址(8位)
PGN由数据页(1位) + PDU格式(8位) + 特定PDU(8位)组成,共17位。但实际使用时,我们通常用6位十六进制数来表示。
计算步骤其实就两步:
- 确定PDU格式(PF)和特定PDU(PS)
- 如果PF值在0-239之间,属于PDU1格式,PS就是目标地址
- 如果PF值在240-255之间,属于PDU2格式,PS是扩展组号
- 套用公式
PGN = (数据页 << 16) | (PF << 8) | PS
举个例子。假设我们有一个CAN ID是0x0CF00400:
二进制拆解:
优先级:011 (3)
保留位:0
数据页:0
PDU格式:11110000 (0xF0 = 240)
特定PDU:00000100 (0x04)
源地址:00000000 (0x00)
PGN计算:
数据页=0,PF=0xF0,PS=0x04
PGN = (0 << 16) | (0xF0 << 8) | 0x04
= 0x00F004
= 61444 (十进制)
嗯,这里要注意。PF=240属于PDU2格式,所以PS=0x04是扩展组号,不是目标地址。这个0x00F004对应的就是“电子制动控制器1”这个参数组。
我的小技巧:在CANalyzer里,你直接在“Trace”窗口看PGN列就行,不用自己算。但理解计算过程很重要,排查问题时能帮你快速定位。
4.3 常用PGN分类
J1939协议里定义了上千个PGN,但实际项目中常用的也就那么几十个。我按功能给大家分了个类:
| 分类 | PGN范围 | 典型PGN | 说明 |
|---|---|---|---|
| 发动机相关 | 0xF000 - 0xF0FF | 0xF004 (EEC1) | 转速、扭矩、燃油率 |
| 变速箱相关 | 0xF100 - 0xF1FF | 0xF101 (TC1) | 档位、离合器状态 |
| 制动系统 | 0xF200 - 0xF2FF | 0xF201 (EBC1) | 刹车压力、ABS状态 |
| 仪表盘显示 | 0xF300 - 0xF3FF | 0xF305 (VD) | 车速、里程、故障灯 |
| 诊断相关 | 0xFE00 - 0xFEFF | 0xFECA (DM1) | 故障码、诊断信息 |
| 网络管理 | 0xEF00 - 0xEFFF | 0xEF00 (AM) | 地址声明、节点控制 |
我在项目中遇到过最频繁的就是发动机和诊断这两类。特别是DM1(0xFECA),每次做故障注入测试,都得盯着它看。
4.4 PGN查询方法
实际工作中,你不可能把所有PGN都背下来。我给大家推荐几种查询方式:
方法一:SAE J1939标准文档
最权威的来源。SAE J1939/71(应用层)和J1939/73(诊断层)里都有完整的PGN列表。不过文档很厚,查起来有点费劲。
方法二:CANalyzer内置数据库
我个人最常用的方法。在CANalyzer里:
- 打开“Simulation Setup”或“Analysis Setup”
- 右键选择“Insert Database”
- 加载J1939的DBC或ARXML文件
- 在“Database”窗口里直接搜索PGN或名称
CANalyzer会自动解析出PGN对应的所有信号,包括起始位、长度、缩放因子这些细节。
方法三:在线查询工具
有些网站提供了PGN查询功能,输入PGN十六进制值就能看到对应的参数组名称和信号列表。不过要注意,这些工具的数据可能不是最新版本。
方法四:自己建一个速查表
我建议你把自己项目里用到的PGN整理成一个表格,放在手边。比如这样:
| PGN(Hex) | 名称 | 发送节点 | 周期(ms) | 数据长度 |
|----------|------|----------|----------|----------|
| 0xF004 | EEC1 | 发动机ECU | 10 | 8字节 |
| 0xF305 | VD | 仪表盘 | 100 | 8字节 |
| 0xFECA | DM1 | 任意节点 | 事件触发 | 8字节 |
避坑指南:我曾经因为查错了PGN,把一个变速箱的PGN当成发动机的来解析,结果数据全乱套了。后来排查了半天才发现是PGN搞混了。所以,每次解析前一定要确认PGN的正确性。
4.5 实战:在CANalyzer中快速定位PGN
最后,我分享一个实战技巧。在CANalyzer的“Trace”窗口里,你可以这样快速定位PGN:
- 点击“Trace”窗口的“Filter”按钮
- 选择“Identifier Filter”
- 输入你要关注的PGN值(比如0xF004)
- 点击“OK”,Trace窗口就只显示这个PGN的消息了
另外,在“Graphics”窗口里,你可以直接把PGN拖进去,实时观察数据变化。比如把EEC1的转速信号拖进去,就能看到发动机转速的实时曲线。
嗯,关于PGN的内容就讲到这里。记住,PGN是J1939的“门牌号”,搞懂了它,后面的信号解析、网络管理、诊断这些内容就顺理成章了。
课后思考:为什么J1939要设计PDU1和PDU2两种格式?它们在实际应用中各有什么优缺点?