找回密码
 会员注册
查看: 24|回复: 0

Python解析CAN报文

[复制链接]

2万

主题

0

回帖

7万

积分

超级版主

积分
71083
发表于 2024-9-9 20:18:40 | 显示全部楼层 |阅读模式
Python的CAN总线库Python处理CAN总线的库主要有python-can和cantools。这里我的CAN总线数据保存为asc格式,database保存为dbc格式。fromcanimportASCReaderfromcantools.databaseimportload_file#我的数据asc_path='xx.asc'dbc_path='xx.dbc'#读取dbc文件database=load_file(dbc_path)#变量database的数据类型cantools.db.can.database.Database效果相同的读取方法第一种:cantools.db.can.database.add_dbc_file(filename:StringPathLike,                             encoding:str='cp1252')->None:             >>>db=cantools.database.Database()  >>>db.add_dbc_file('foo.dbc')   第二种:cantools.db.can.database.add_dbc_string(string:str)->None:  >>>db=cantools.database.Database()  >>>withopen('foo.dbc','r')asfin:  ...  db.add_dbc_string(fin.read())   值得注意的是,以上两种方法可以在原有database上增加,如:   >>>db=cantools.database.Database()   >>>db.add_dbc_file('foo1.dbc')   >>>db.add_dbc_file('foo2.dbc')这里的db就包含了'foo1.dbc'和'foo2.dbc'两个dbc文件的信息。如果两个dbc有ID相同的报文,则后面添加的dbc会覆盖前面id相同的报文。cantools.db.can.database.Database包含CAN网络的所有报文、信号和定义,是我们经常会用到的一个类。cantools.db.can.database.Database常用的类属性有messages,nodes和buses,分别返回所有报文的list,所有节点的list和所有总线的list。如果想查看某个报文,则可以使用.get_message_by_frame_id()或.get_message_by_name()>>>dbc_path='xx.dbc'>>>db=cantools.database.load_file(dbc_path)>>>db.messages[message('msg1',0x18ffffff,True,8,None),message('smg2',0x18000000,True,8,None)]#通过id检索>>>db.get_message_by_frame_id(0x18ffffff)message('msg1',0x18ffffff,True,8,None)#通过名称检索>>>db.get_message_by_name('msg1')message('msg1',0x18ffffff,True,8,None)解析CAN报文的字节数据defhex_bin(hex_data):byte_li=[]forhex_strinrange(0,len(hex_data),2):data=hex_data[hex_str:hex_str+2]binary_str=bin(int(data,16))[2:]iflen(binary_str)max_interval:max_interval=intervalifinterval>1:interval_morethan1_1_count+=1print(interval)print('time:{},channel:{},data:{}\n'.format(message.timestamp,message.channel,message.data))#读取字节数组的具体数值,秒在第28个字节,纳秒在32个字节bytearray=message.dataprint('数组长度:{},秒:{},纳秒:{}\n'.format(len(message.data),bytearray[28],bytearray[32]))#遍历数组数据print('读取的数据:\n')forbyteinbytearray:#打印每个字节的十六进制表示(可选添加前缀'0x'),输出:Byte:12,Byte:34,Byte:AB,Byte:CD#print(f"Byte:{byte:02X}")#如果你想要输出前缀'0x',可以使用format方法或字符串格式化,输出:Byte:0x12,Byte:0x34,Byte:0xab#print("Byte:",hex(byte))#输出:1234ABCD(每个字节后有一个空格)print(f"{byte:02X}",end='')previous_timestamp=message.timestampprint('\n\n0x572总帧数:{},间隔超过1s数量:{},最大间隔:{}\n'.format(frame_572_count,interval_morethan1_1_count,max_interval))#print('0x572总帧数:{},间隔超过1s数量:{},最大间隔:{}\n'.format(frame_572_count,interval_morethan1_1_count,max_interval))
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-9 05:52 , Processed in 1.027991 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表