【matlab专题】脚本(2)DBC--EXCEL--模型:DBC生成EXCEL表格(一)

在有特殊需要时(通过DBC–模型)实现建模高效化,这个时候就需要我们将需求的DBC文件中的信号写成模型的输入出信号,在建模过程中会出现大量的复制工作,当数量到达一定程度时候,就会造成时间上的浪费,且不一定保证数据的准确性,所以在这里找了个脚本,供大家参考:

% 将CAN矩阵DBC文件转换为excel文件

% 用途:
% 将CAN矩阵(Database)DBC文件转换为excel文件,便于查找报文中的信号
%canDatabase()读入DBC文件,xlswrite()写入excel文件


% 读入DBC文件名
[infile,path] = uigetfile({'*.dbc','CANdb Network'},'选择要转换的CAN Database文件');
if isequal(infile,0)
    warndlg('没有选择任何文件,不会转换任何文件!','文件选取警告','modal');
else
    DBCfile = [path,infile];
    candb = canDatabase(DBCfile);
    [messageRow, ~] = size(candb.MessageInfo);
    
    
    % 获取DBC文件转换成xlsx表后的总行数(报文和信号的总行数),xlsx最大支持1048576行
    signalRowCount = 0;
    for messageIndex = 1:messageRow
        [signalRow, ~] = size(candb.MessageInfo(messageIndex).SignalInfo);
        signalRowCount = signalRowCount + signalRow;
    end
    msgTableRowMax = messageRow + signalRowCount;
    
    xlsRowMax = 65536;
    % 预留一行给表格标题(表格标题需要占用一行)
    if msgTableRowMax > xlsRowMax-1
        opts = struct('WindowStyle','modal','Interpreter','tex');
        warmsg = ['\fontsize{10}转换后的表格长度超过',xlsRowMax,'行!',newline,...
            '请注意选择保存的文件格式:',newline,...
            '.xls文件最多支持65536行',newline,...
            '.xlsx文件最多支持1048576行',newline...
            '而.csv、.txt 或 .dat(带分隔符的文本文件)文件则没有限制'];
        warndlg(warmsg,'文件长度警告',opts);
    end
    
    % candb文件转换成Table
    messageTable = candbc2excel(candb);

    % 创建报文结构体
% 因结构体增加行比表要方便故采用结构体数据结构
messageStruct = struct('MsgName',{}, 'ID_HEX',{},'DLC_Byte',{}, 'TxNode',{},'RxNodes',{},'CycleTime',{} ,'Tx_Method',{} ,'FrameFormat',{},'ProtocolMode',{},...
     'SignalName',{}, 'ByteOrder',{}, 'StartBit',{}, 'BitLength',{},'Factor',{},'Class',{},'Offset',{},'Initial_Value',{},'Units',{},  'ValueTable',{},...
    'Minimum',{}, 'Maximum',{}, 'SignalComment',{},'SignalNumble',{},'ValueType',{},'ValueTableNumbles',{});

[messageRow, ~] = size(candb.MessageInfo);
tableIndex = 1;     % 结构体行号
 
for messageIndex = 1:messageRow
   
    messageStruct(tableIndex).MsgName = candb.MessageInfo(messageIndex).Name;
%     messageStruct(tableIndex).ID_Decimal = candb.MessageInfo(messageIndex).ID;
    messageStruct(tableIndex).ID_HEX = ['0x',dec2hex(candb.MessageInfo(messageIndex).ID)];
    
    if candb.MessageInfo(messageIndex).Extended
        messageStruct(tableIndex).FrameFormat = 'Extended';
    else
        messageStruct(tableIndex).FrameFormat = 'Standard';
    end
    messageStruct(tableIndex).ProtocolMode=candb.MessageInfo(messageIndex).ProtocolMode;
%     if isequal(messageStruct(tableIndex).ProtocolMode{1},'J1939PG')==1 %如果是J1939P格式
%         messageStruct(tableIndex).
%     end

    messageStruct(tableIndex).DLC_Byte = candb.MessageInfo(messageIndex).DLC;
    
    % 将TxNodes的值(字符串元胞)合并到一行,便于填充到表格中
    [TxNodesRow, TxNodesCol] = size(candb.MessageInfo(messageIndex).TxNodes);
    TxNodes = '';
    for TxNodesRowIndex = 1:TxNodesRow
        for TxNodesColIndex = 1:TxNodesCol
            TxNodes =[TxNodes, candb.MessageInfo(messageIndex).TxNodes{TxNodesRow,TxNodesCol}];
            if (TxNodesRow>1 || TxNodesCol>1) && (TxNodesRowIndex < TxNodesRow || TxNodesColIndex < TxNodesCol)
                TxNodes =[TxNodes,', '];
            end
        end
    end
    messageStruct(tableIndex).TxNode = TxNodes;
  % 将RxNodes的值(字符串元胞)合并到一行,便于填充到表格中  % %这个里面应从每个message里去取RxNodes,而不是从每个signal里去取
   [RxNodesRow, RxNodesCol] = size(candb.MessageInfo(messageIndex).SignalInfo(1).RxNodes);
    RxNodes = '';
    for RxNodesRowIndex = 1:RxNodesRow
        for RxNodesColIndex = 1:RxNodesCol
            RxNodes =[RxNodes, candb.MessageInfo(messageIndex).SignalInfo(1).RxNodes{RxNodesRowIndex,RxNodesColIndex}];
            if (RxNodesRow>1 || RxNodesCol>1) && (RxNodesRowIndex < RxNodesRow || RxNodesColIndex < RxNodesCol)
                RxNodes =[RxNodes,', '];
            end
        end
    end
    messageStruct(tableIndex).RxNodes = RxNodes;%%
   
    MessageX=candb.MessageInfo(messageIndex).AttributeInfo;
    MsgAttribuinfIndex=1;
    for MsgAttribuinfIndex=1:size(MessageX,1)
      if isequal('GenMsgSendType',MessageX(MsgAttribuinfIndex).Name)
         messageStruct(tableIndex).Tx_Method=candb.MessageInfo(messageIndex).AttributeInfo(MsgAttribuinfIndex).Value;
      end
      if isequal('GenMsgCycleTime',MessageX(MsgAttribuinfIndex).Name)
         messageStruct(tableIndex).CycleTime=candb.MessageInfo(messageIndex).AttributeInfo(MsgAttribuinfIndex).Value;
      end
    end
    
    messageStruct(tableIndex).SignalNumble =length(candb.MessageInfo(messageIndex).Signals);
    
    tableIndex = tableIndex + 1;
    sigSize = size(candb.MessageInfo(messageIndex).SignalInfo);
    for signalIndex = 1:sigSize
        messageStruct(tableIndex).TxNode = TxNodes;
        messageStruct(tableIndex).RxNodes = RxNodes;%%
        messageStruct(tableIndex).SignalName = candb.MessageInfo(messageIndex).SignalInfo(signalIndex).Name;
        messageStruct(tableIndex).SignalComment = candb.MessageInfo(messageIndex).SignalInfo(signalIndex).Comment;
        messageStruct(tableIndex).StartBit = candb.MessageInfo(messageIndex).SignalInfo(signalIndex).StartBit;
        messageStruct(tableIndex).BitLength = candb.MessageInfo(messageIndex).SignalInfo(signalIndex).SignalSize;
        
        % 将valueTable的值(字符串元胞)合并到一行,便于填充到表格中
        [valueTableRow, ~] = size(candb.MessageInfo(messageIndex).SignalInfo(signalIndex).ValueTable);
        messageStruct(tableIndex).ValueTableNumbles = valueTableRow;%每一个signal都有VALUE table ,这里定义value tabel大小
        valueTable = '';
        for valueTableIndex = 1:valueTableRow
            valueTable = [valueTable, candb.MessageInfo(messageIndex).SignalInfo(signalIndex).ValueTable(valueTableIndex).Text,'=',...
                num2str(candb.MessageInfo(messageIndex).SignalInfo(signalIndex).ValueTable(valueTableIndex).Value)];
            if (valueTableRow > 1) && (valueTableIndex < valueTableRow)
                valueTable = [valueTable,', '];
            end
        end
        
        messageStruct(tableIndex).ValueTable = valueTable;
        
        if candb.MessageInfo(messageIndex).SignalInfo(signalIndex).Signed
            messageStruct(tableIndex).ValueType = 'Signed';
        else
            messageStruct(tableIndex).ValueType = 'Unsigned';
        end
        
        messageStruct(tableIndex).Factor = candb.MessageInfo(messageIndex).SignalInfo(signalIndex).Factor;
        messageStruct(tableIndex).Class = candb.MessageInfo(messageIndex).SignalInfo(signalIndex).Class;
   
        messageStruct(tableIndex).Offset = candb.MessageInfo(messageIndex).SignalInfo(signalIndex).Offset;
        messageStruct(tableIndex).Minimum = candb.MessageInfo(messageIndex).SignalInfo(signalIndex).Minimum;
        messageStruct(tableIndex).Maximum = candb.MessageInfo(messageIndex).SignalInfo(signalIndex).Maximum;
        messageStruct(tableIndex).Units = candb.MessageInfo(messageIndex).SignalInfo(signalIndex).Units;
        % FIND the signal initial value 
        SignalsX=candb.MessageInfo(messageIndex).SignalInfo(signalIndex);
        SignalsXIndex=1;
        for SignalsXIndex=1:size(SignalsX.AttributeInfo,1)
            if isequal('GenSigStartValue' ,SignalsX.AttributeInfo(SignalsXIndex).Name)      
               messageStruct(tableIndex).Initial_Value=candb.MessageInfo(messageIndex).SignalInfo(signalIndex).AttributeInfo(SignalsXIndex).Value;
            end
        end
        if strcmpi((candb.MessageInfo(messageIndex).SignalInfo(signalIndex).ByteOrder),'BigEndian')
            messageStruct(tableIndex).ByteOrder = 'Motorola';
        elseif strcmpi((candb.MessageInfo(messageIndex).SignalInfo(signalIndex).ByteOrder),'LittleEndian')
            messageStruct(tableIndex).ByteOrder = 'Intel';
        else
            messageStruct(tableIndex).ByteOrder = candb.MessageInfo(messageIndex).SignalInfo(signalIndex).ByteOrder;
        end
        tableIndex=tableIndex+1;
    end
end

% 报文结构体转换成表
messageTable = struct2table(messageStruct);

end

    % 写入xls文件
    filter = {'*.xlsx','Excel 工作簿'; '*.xls','Excel 97-2003 工作簿'; '.xlsb','Excel 二进制工作簿';...
        '*.csv; .txt; .dat','带分隔符的文本文件'};
    filename = removeExt(infile);

 %   function filenameNonExt = removeExt(filename)
filenamelength = length(filename);
for index = filenamelength:-1:1
    if filename(index) ~= '.'
        filename(index) = '';
    else
        filename(index) = '';
        break;
    end
end
filenameNonExt = filename;

    [outfile,path,indx] = uiputfile(filter,'选择保存文件',filename);
    
    if isequal(outfile,0)
        warndlg('没有输入要保存的文件,将不会保存任何文件!','文件保存警告','modal');
    else
        writetable(messageTable,[path,outfile]);
    end

有疑问或错误的地方欢迎留言,我们共同探讨

  • 4
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值