J1939协议解析

关于对J1939的一点理解,有错误的话请指正。

缩写定义

在这里插入图片描述
在这里插入图片描述

PGN

在CAN数据帧的数据域中需要指明参数群时,PGN是表示成24位。PGN是一个24位的值,包括以下要素:保留位、数据页位、PDU格式域(8位)和群扩展域(8位)。各个位转化到PGN的过程如下。若PF值小于240(F016),PGN的低字节置0。
PF共8位,0-255,当PF<240时,说明是点对点通信,向特定目标通信,这时PS用于表示目标地址,不用于构成PGN,PGN后8位补0。当PF>=240时,采用广播式通信,这时PS用于构成PGN。
在这里插入图片描述

关于帧ID解析

在这里插入图片描述
在这里插入图片描述

0x18:是优先级,组成:P+R+DP 二进制为110 +0 +0 转为16进制为0x18.
0XFA40:为PGN,详情看上边
0x49:为外部设备地址
PF (PDU格式):
PF大小为8bit,于确定分配到数据域的PGN,有两种不同标识的参数PDU格式,分别为PDU1,PDU2,当PF<240为PDU1格式,当PF≥240且PF≤255, 为PDU2格式。PDU1用于将数据传递至特定的目标地址,也就是某个确定的ECU; PDU2用于将数据传递至扩展参数组,类似于局部广播。

举例:
终端设备请求: 转速:请求帧:0x18EA00F9 0x04 0xF0 0x00 0x00 0x00 0x00 0x00 0x00

车子回复: 回复帧 0x18F00400 0x00 0x00 0x00 0x12 0x34 0x00 0x00 0x00
前边地址就不介绍了直接看数据
那么0X04 0XF0,组合到一起就是F004(CAN报文里面最前面的为低字节)
在SAEJ1939-71文档里面直接搜索F004,即可定位到该参数组编号定义的位置。F004即为PGN,通过该详细介绍,我们可以看到第4,5字节代表转速。
在这里插入图片描述
最后总结一下:0x18EA00F9 0x04 0xF0 0x00 0x00 0x00 0x00 0x00 0x00这条请求报文的整体含义是:外部设备地址为F9的车外诊断服务工具请求车辆发动机转速,转速的参数组编号为F004,也正是该F004参数组编号决定了这条报文是请求的发动机转速。

0x18F00400的含义

18代表优先级和保留位以及数据页,这个无需过多讲解。

F004这个转速所在的参数组的编号,意思是这个报文是F004参数组编号的数据项。

0x18F00400 0x00 0x00 0x00 0x12 0x34 0x00 0x00 0x00整体含义解析
那么具体这2个字节对应的转速解析算法如何计算呢?我们看后面的一栏,SPN栏,转速对应的SPN为190,接着我们再去搜索SPN190对应的解析。
在这里插入图片描述
该项很清楚的写到了,每一个bit位代表的是0.125转。也就是说车子回复的报文里面的第4,第5字节,组合到一起就是0X3412(报文的低字节在前,高字节在后),对应的十进制为是0X3412=13330,再结合每一个bit代表0.125转,所以13330对应的实际转速值为:13330*0.125=1666.25转每分钟。

### J1939 协议报文解析方法 #### 报文结构概述 J1939协议规定了一种标准化的数据交换方式,在车辆内部网络中广泛应用。每一条CAN报文中包含了多个字段,用于描述消息的目的地、优先级和其他控制信息[^2]。 #### PGN (Parameter Group Number) 的作用 PGN是理解J1939报文的关键部分之一。它由SPNs(Specific Parameter Numbers)组成,用来表示特定类型的参数集合。例如,在给定的例子中`0x18EA00F9 0x04 0xF0 ...`里,“F004”作为PGN指示了这是关于发动机转速的信息请求[^4]。 #### 数据域分析 对于具体数值的提取,通常需要参照相应的标准文档来确定哪些位代表什么意义。比如上述例子中的第四个和第五个字节(0x12, 0x34),它们共同构成了实际测量得到的发动机转速值。要将其转换成可读的形式,则需按照SAE J1939-71或其他相关文件中给出的方法进行计算。 #### 地址分配原则 源地址(Source Address) 和目标地址(Destination Address) 是识别发送者与接收者的依据。像样例里的`0x18EA00F9`开头几个字节就指明了一个来自外部诊断工具(F9)向车内某个组件发出查询命令的情况。 ```python def parse_j1939_frame(frame_hex_string): """ 解析单条J1939 CAN帧 参数: frame_hex_string : str 表示一整条CAN帧内容的十六进制字符串形式 返回: dict: 包含解析后的各项信息 """ # 将输入字符串分割成列表以便处理各个字节 bytes_list = [frame_hex_string[i:i+2] for i in range(0, len(frame_hex_string), 2)] result = { 'priority': int(bytes_list[0][0], 16), 'pgn': hex(int(''.join(reversed(bytes_list[1:4])), 16)), 'source_address': hex(int(bytes_list[-1], 16)) } data_bytes = ''.join(bytes_list[8:]) spns = [] if result['pgn'] == '0xf004': rpm_high_byte = int(data_bytes[:2], 16) rpm_low_byte = int(data_bytes[2:4], 16) engine_rpm = ((rpm_high_byte << 8) | rpm_low_byte) * 0.125 spns.append({ "name": "Engine Speed", "value": f"{engine_rpm:.2f} RPM" }) result["spns"] = spns return result example_frame = "18EA00F904F0000000000000" parsed_data = parse_j1939_frame(example_frame) print(f"Parsed Data:\n{parsed_data}") ```
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值