目录
在现代工程和通信领域中,数据交换和共享是至关重要的。Controller Area Network(CAN)是一种广泛应用于汽车和工业领域的通信协议,而CAN数据库(DBC)是CAN网络中的关键组件,用于描述网络上的消息、信号和节点。
一、转化原理
CAN网络中的DBC文件包含了网络中所有消息和信号的定义、布局和属性。转化EXCEL表格为DBC文件的基本思想是将EXCEL表格中的数据映射到DBC文件中的消息和信号定义中。具体而言,需要处理以下内容:
-
消息定义:在EXCEL表格中,每一行可以表示一个CAN消息,包括消息ID、消息名称、发送周期等信息。
-
信号定义:每一行中的信号定义也包括信号名称、起始位、长度、因子等信息。
-
节点定义:CAN网络中的节点也需要在DBC文件中定义,包括节点名称、节点类型等信息。
二、实现过程
通过MATLAB将EXCEL表格转化为DBC数据库的实现过程可以分为以下几个步骤:
-
读取EXCEL数据:使用MATLAB的内置函数(如
xlsread
)读取EXCEL表格中的数据,包括消息、信号和节点信息。 -
创建DBC文件:使用MATLAB创建一个文本文件,作为最终的DBC文件。
-
写入消息定义:将从EXCEL读取的消息信息写入DBC文件中,按照DBC文件的格式进行排列。
-
写入信号定义:将信号信息写入DBC文件中,也需要按照规定的格式进行排列。
-
写入节点定义:将节点信息写入DBC文件中,同样需要遵循规定的格式。
-
保存DBC文件:保存生成的DBC文件,即完成了EXCEL转化为DBC的过程。
DBC(DataBase Container)数据库是一种用于存储数据的文件格式,主要用于存储CAN(Controller Area Network)总线网络中的通信参数和信息。CAN总线是一种广泛应用于汽车、工业控制等领域的通信协议,用于在不同的电子控制单元(ECU)之间进行数据交换。
以下是关于DBC数据库的详细介绍:
1. 数据格式: DBC数据库以文本格式存储,通常是一个拓展名为“.dbc”的文件。虽然它可以被文本编辑器打开和查看,但通常需要特定的工具来创建、编辑和解析。
2. CAN通信参数: DBC数据库主要用于存储CAN通信参数,包括CAN信号的定义、消息的结构以及信号在消息中的位置和位长度等信息。这些信息对于解析CAN消息以及从CAN网络中读取和写入数据至关重要。
3. 信号定义: 在DBC文件中,每个CAN信号都有其定义,包括信号的名称、起始位、长度、数据类型、信号的单位、缩放因子、偏移量等。这些定义允许接收方正确地解释来自CAN总线的原始数据。
4. 消息结构: DBC文件描述了每个CAN消息的结构,包括消息的ID、长度、发送者和接收者等信息。它还指定了消息中包含的信号和它们在消息中的位置。
5. 物理值和原始值的转换: DBC文件还提供了物理值和原始值之间的转换公式,使接收方能够将从CAN总线接收到的原始数据转换为实际的物理值,例如速度、温度、压力等。
6. 工具支持: 有许多CAN总线分析工具和编程库支持DBC文件。这些工具可以使用DBC文件来解析CAN消息,将原始数据转换为物理值,并在CAN网络中模拟和生成消息。
7. 应用领域: DBC数据库广泛用于汽车行业、工业自动化和嵌入式系统中。在汽车行业中,ECUs使用DBC文件来理解CAN网络中的通信,以实现车辆内部和车辆与外部设备之间的数据交换。
总之,DBC数据库是一种重要的文件格式,用于描述CAN总线通信参数和信息。它在车辆控制、工业自动化和嵌入式系统等领域中扮演着关键角色,帮助实现不同设备之间的高效通信和数据交换。
三、应用领域
将EXCEL表格转化为DBC数据库在CAN通信领域有着重要的应用:
-
汽车领域:在汽车中,CAN网络是车辆电子控制单元(ECU)之间的主要通信方式,将车辆参数、状态信息等转化为DBC文件可方便系统开发和集成。
-
工业自动化:在工业自动化中,CAN网络广泛应用于控制系统中,将工业设备的控制信息通过DBC文件进行定义和传输,便于系统集成和维护。
-
物联网:随着物联网的发展,越来越多的设备和传感器使用CAN网络进行通信,将设备数据转化为DBC文件有助于数据传输和处理。
-
航空航天:在航空航天领域,CAN网络用于飞行器中的数据传输和通信,将飞行器参数转化为DBC文件有助于飞行控制和监测。
通过MATLAB将EXCEL表格转化为DBC数据库是一种在CAN通信领域中实现数据转换和共享的重要方法。它有助于车辆控制、工业自动化、物联网和航空航天等领域中的数据传输和通信。通过简单的数据处理和文件生成,实现了不同数据格式之间的无缝连接,提升了工程开发效率和数据交换的便捷性。
四、核心程序
....................................................................
% 打开要写入的DBC文件
fid = fopen(dbcfile_info,'w');
fprintf(fid, 'VERSION ""\n\n\n');
fprintf(fid, 'NS_ :\n');% ...(省略一些NS_的格式定义)
fprintf(fid, ' NS_DESC_\n');
fprintf(fid, ' CM_\n');
fprintf(fid, ' BA_DEF_\n');
fprintf(fid, ' BA_\n');
fprintf(fid, ' VAL_\n');
fprintf(fid, ' CAT_DEF_\n');
fprintf(fid, ' CAT_\n');
fprintf(fid, ' FILTER\n');
fprintf(fid, ' BA_DEF_DEF_\n');
fprintf(fid, ' EV_DATA_\n');
fprintf(fid, ' ENVVAR_DATA_\n');
fprintf(fid, ' SGTYPE_\n');
fprintf(fid, ' SGTYPE_VAL_\n');
fprintf(fid, ' BA_DEF_SGTYPE_\n');
fprintf(fid, ' BA_SGTYPE_\n');
fprintf(fid, ' SIG_TYPE_REF_\n');
fprintf(fid, ' VAL_TABLE_\n');
fprintf(fid, ' SIG_GROUP_\n');
fprintf(fid, ' SIG_VALTYPE_\n');
fprintf(fid, ' SIGTYPE_VALTYPE_\n');
fprintf(fid, ' BO_TX_BU_\n');
fprintf(fid, ' BA_DEF_REL_\n');
fprintf(fid, ' BA_REL_\n');
fprintf(fid, ' BA_DEF_DEF_REL_\n');
fprintf(fid, ' BU_SG_REL_\n');
fprintf(fid, ' BU_EV_REL_\n');
fprintf(fid, ' BU_BO_REL_\n');
fprintf(fid, ' SG_MUL_VAL_\n\n');
fprintf(fid, 'BS_:\n\n');
................................................................
for column_index = 1:(column_num -2)
[~,~,Message_Text] = xlsread(file_name,'CANMatrix',['A',num2str(column_index+2),':R',num2str(column_index+2)]);
% 从Excel中读取消息的相关信息
if isnan(cell2mat(Message_Text(1,1)))% 如果读取到的消息ID为空,终止循环
break;
end
% 保存消息的相关信息
MessageID(message_num) = Message_Text(1,1);
if ~((message_num > 1) && isequal(MessageID{message_num},MessageID{message_num - 1}))
MessageName(message_num) = Message_Text(1,2);
MessageType(message_num) = Message_Text(1,3);
MessageCycle(message_num) = Message_Text(1,4);
SignalName = Message_Text(1:end,5);
SignalName1 = Message_Text(1:end,5);
ByteOrder = Message_Text(1:end,6);
DateType = Message_Text(1:end,7);
ByteNum = Message_Text(1:end,8);
BitNum = Message_Text(1:end,9);
Length = Message_Text(1:end,10);
StartBit = Message_Text(1:end,11);
Offset = Message_Text(1:end,12);
Factor = Message_Text(1:end,13);
Max = Message_Text(1:end,14);
Min = Message_Text(1:end,15);
Unit = Message_Text(1:end,16);
ValueDesc = Message_Text(1:end,17);
Comment = Message_Text(1:end,18);
fprintf(fid, '\nBO_ ');
fprintf(fid, MessageID{message_num});
fprintf(fid, ' ');
fprintf(fid, MessageName{message_num});
fprintf(fid, ': 8 Vector__XXX\n');
[signal_num,~] = size(SignalName);
for index = 1:signal_num % 遍历消息的每个信号
fprintf(fid, [' SG_ ',SignalName{index},' : ']);% 将信号相关信息写入DBC文件
fprintf(fid,num2str(StartBit{index}));
fprintf(fid,'|');
fprintf(fid,num2str(Length{index}));
fprintf(fid,'@');
if isequal(ByteOrder{index}, 'Motorola')
fprintf(fid,'0');
else
fprintf(fid,'1');
end
if isequal(DateType{index}, 'signed')
fprintf(fid,'- ');
else
fprintf(fid,'+ ');
end
fprintf(fid,'(');
fprintf(fid,num2str(Factor{index}));
fprintf(fid,',');
fprintf(fid,num2str(Offset{index}));
fprintf(fid,') [');
fprintf(fid,num2str(Max{index}));
fprintf(fid,'|');
fprintf(fid,num2str(Min{index}));
fprintf(fid,'] "" Vector__XXX');
fprintf(fid, '\n');
% 如果有ValueDesc,保存到Val_ID和Val_SignalName中
if ~isnan(ValueDesc{index})
Val_ID(val_num) = MessageID(message_num);
Val_SignalName(val_num) = SignalName(index);
Val_SignalVal(val_num) = ValueDesc(index);
val_num = val_num + 1;
end
% 如果有Comment,保存到Val_ID1和Val_SignalName1中
if ~isnan(Comment{index})
Val_ID1(val_num1) = MessageID(message_num);
Val_SignalName1(val_num1) = SignalName(index);
Val_Comment(val_num1) = Comment(index);
val_num1 = val_num1 + 1;
end
end
message_num = message_num + 1;
end
end
...................................................................
% 关闭文件
fclose all;
clear;
disp('DBC exchange ok')
up2190