如何通过m脚本提取dbc中信息到Excel表格

01--背景

        在项目对接的过程中,有时候因为合作关系亦或是保密协议的缘故,在合作开发一款车型时,有时候主机厂或是供应商只愿意提供dbc文件而不提供CAN矩阵,那么我们在进行信号信息的获取时只能通过读取dbc文件,非常麻烦。本文目的是在dbc的繁多信息中,提取自己所需要的信息,汇集在表格内,相当于自己制作一个CAN矩阵,该功能的实现能够大大提高后续开发的工作效率,避免一些低级错误的发生。

02--思路

        首先需要一个待测试的dbc,然后通过MATLAB的一个专用函数获取dbc内所有的信息以及属性,同时通过MATLAB创建一个表格,通过定义变量链接到获取到的dbc属性,然后把这些关联写入到表格中,最后需要调整表格的变现形式,使之稍微美观和便于进行查找。

03--脚本实现

1.先准备一个测试的dbc,并新建一个脚本文件

2.给dbc一个变量名并且把最后需要保存的Excel文件名也定义出来

clc;clear;  %清除工作区与MATLAB命令行窗口内容

dbcName = 'TestDbc.dbc';  % 此处替换成自己的dbc文件名
excelFileName = 'SigMsg.xlsx';  % 此处替换成要保存的excel文件名

3.读取dbc内的信息与属性

disp('### Reading information from dbc file...');  %显示接下来的动作
dbcdata = canDatabase(dbcName); %读取dbc内的信息与属性

这里介绍下函数canDatabase,可以通过帮助功能了解该函数的信息,

最终该函数会输出属性信息、属性、报文信息、报文、dbc名字、节点信息、节点、路径、信号信息、用户资料

我们将这几行代码运行下,

运行之后我们发现,左下角的工作区出现了我们定义的变量,

双击dbcdata,我们发现dbc内的属性已经全部被拉出来了

可以看到我们关心的是有55个报文,双击点开报文信息,MessageInfo,可以看到有信号信息,那么我们可以通过结构体引用的形式把我们需要的信息提取出来

假设我们以第2个报文为例

其报文名字为BMS1,可以看到在信号Signals这列有3个元素,所以该报文内定义了3个信号

我们点开SignalInfo,可以看到信号的详细属性

假设现在我们所需要的信息如下:

报文名字、报文ID、信号名字、信号描述、信号备注这5个信息

定义这5个信息作为Excel表头的变量

tableHead = ["MessageName","ID","SignalName","ValueDescription","Comment"];

创建一个元细胞组,使我们需要的信息能够按我们的需求填进元细胞组中

MsgInfo = cell(1,1);  % 将当前报文信息填充到数组 MsgInfo 中

如果数量较少,我们可以通过结构体引用把需要的信息填进细胞组中,但是一旦我们需要的信息比较多,比如需要dbc内的所有属性,如果使用这种手动方式效率将非常低下,在这里我们使用一个for循环直接进行遍历

for j = 1:length(dbcdata.MessageInfo(2).Signals)  %遍历该报文中的信号总数
    MsgInfo{j,1} = dbcdata.MessageInfo(2).Name;
    MsgInfo{j,2} = dbcdata.MessageInfo(2).ID;
    MsgInfo{j,3} = dbcdata.MessageInfo(2).SignalInfo(j).Name;
    MsgInfo{j,4} = dbcdata.MessageInfo(2).SignalInfo(j).ValueTable;
    MsgInfo{j,5} = dbcdata.MessageInfo(2).SignalInfo(j).Comment;  %将上述3个信号的5个信息填入到元细胞组中
end

上述代码中:

MsgInfo{j,1}代表填进第j行第1列

MessageInfo(2)代表报文中的第2个报文即  ‘BMS1’

SignalInfo(j)代表信号内的第j行

4.创建一个表格,把元细胞组转化为表格数据并写入到Excel中,并直接开

tableData = cell2table(MsgInfo,"VariableNames",tableHead);
disp('### write data to excel file...');
writetable(tableData, excelFileName);

% 创建 Excel 应用程序对象
Excel = actxserver('Excel.Application');
% 打开 Excel 应用程序
Excel.Visible = 1;
Workbooks = Excel.Workbooks;
% 打开一个工作簿
filepath = [pwd, '\', excelFileName];
Workbook = Workbooks.Open(filepath);

把所有的写好的脚本运行一下

可以发现正常生成了Excel文件并自动进行了打开

打开后的内容如下图所示:

打开后发现一个bug,那就是列ValueDescription为空白,打开属性栏,发现里面确实没有值

如果没有值,我们希望他显示一个短横杠,如果有值,能够正常显示

现在我们重新找一个报文ValueDescription是有值的

可以看到第6个报文内很多信号都有2个值

同样的代码,只需要改下数字(注意需要把刚刚生成的Excel文档关闭并删除或放到其他路径,且清除工作区间即命令行内容)

打开的结果如下:

该列仍然没有任何内容,需要在代码中创建一个函数(函数需要放在m文件的最末尾),把该列下的内容提取进来

function valueDescrip = getSigValueDescrip(sigValDescripStruct)

valueDescrip = '';

if isempty(sigValDescripStruct)
    valueDescrip = '-';
    return;
end
for i = 1:length(sigValDescripStruct)
    valueDescrip = [valueDescrip, num2str(sigValDescripStruct(i).Value), ': ', sigValDescripStruct(i).Text, '; '];
end
end

该函数的作用为:如果提取的描述信息中空白的话则用横杠表示,若有值,将把值显示出来

在对应的行中把函数进行引用

重新运行的效果:

同样的如果需要所有报文的信息,最后呈现的形式为CAN矩阵的形式,需要在上述的for循环外面再嵌套一层for循环来遍历不同的报文信号,也就是说类似于

dbcdata.MessageInfo(2).SignalInfo(j).Name;  将用

dbcdata.MessageInfo(i).SignalInfo(j).Name;来表示

即用如下的报文:

最终效果如下图:

该脚本放在附件

-→单个报文

-→全部报文

~欢迎下载!

参考【Reference】:dbc文件自动转成 excel 表格_哔哩哔哩_bilibili

作者:快乐的宇航boy

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值