专栏名称: 嵌入式微处理器
关注这个时代最火的嵌入式微处理器,你想知道的都在这里。
目录
相关文章推荐
十点读书  ·  DeepSeek火爆全网:人和人最大的差距, ... ·  昨天  
BioArt  ·  Genome Research | ... ·  昨天  
生物制品圈  ·  阿斯利康抗PD-L1单抗癌症新药新适应症在华 ... ·  2 天前  
51好读  ›  专栏  ›  嵌入式微处理器

手把手DBC文件编写教程

嵌入式微处理器  · 公众号  ·  · 2024-12-20 12:00

正文

CAN在嵌入式领域是非常重要的一种总线通讯方式,基于CAN有着各种各样的协议。在实际调试的时候,如果没有开发好上位机,那么工程师只能看着总线上的大量报文傻眼。有时候是不是希望这些报文都能被解释成文字类信息,变更超级直观?所以,这类脑洞应用就被做出来了,那就是DBC文件。


DBC全称是Database CAN,大家可以理解为DBC文件就是工程师提前把CAN的协议内容设定好,然后加载到CAN上位机,上位机就会根据DBC文件将裸报文解析成对应的文字描述。DBC文件内容构成是按照一定的编码规则的,理论上你拿着TXT就能写,但这duck不必。


现在比较知名的编写DBC的工具就是Vector公司出品的CANdb++,下载地址详见另一篇文章《 让嵌入式工程师欲罢不能的10个小网站(软件篇) 》,本篇将会手把手详细介绍如何使用CANdb++编写一个DBC文件。

1、范例帧ID

如图是我们这次练手用的帧ID,主要的目的是让大家知道如何在一个帧ID,通过某个字节的内容,可进一步的拆分子项。这个报文的目的就是根据Byte0的内容不同,后面的字节将代表不同含义。当BYTE0为0是,则后面的字节信息都是代表电压的类型和相关信息;为1时则为电流类信息。

2、创建DBC工程

打开CANdb++,点击菜单栏的File->Create Database。这个时候会出现一张database类型表,我们这里选择 CANTemplate.dbc 即可,然后你就完成了一个DBC文件的初步创建。

在侧边栏里有 ECUs/Network nodes/Messages/signals ,其中前两项暂不关注,主要集中在Message和Signal中,初步的解释一下Message就是报文,在这里面编辑报文内容的;Signal就可以理解为要用到各个变量,例如看目标帧ID中的电压值、控制指令啥的都算是signal,会在此处添加并编辑。

3、创建报文信息

在Message中右击鼠标,点击new即可添加一条新报文。如下图所示,我们创建了一条标准帧CAN报文,帧ID为0x123,报文长度为8,并且命名为DEMO(注意:命名只能使用英文,汉字会报错)

如果对报文内容有更多的说明,可以在Comment中添加更多描述,这里支持中文,所以可以尽情编写。

4、创建信号变量

如上面所得,信号就是这条报文中涉及到的信息变量。此处将示范创建信息类型信号,首先直接在signal中点击new,创建一个信号。

如图所示界面,首先给这个信号命名MSG_TYPE,然后这个信号使用的bit数为8。

byte oder中有intel型(小端模式)与Motorola型(大端模式),根据实际需求自行选择,本范例选择Intel型。

Unit中填写单位,这里是文本,根据实际情况填写就好,没有单位的话空着就行。

Value Type是有符号还是无符号自行选取。

Factor和Offset的作用就是把裸数据处理成显示数据,公式的话是 显示数据=Factor*裸数据+offset ,没有应用需求的话空着就好。Value Table的关联后面会讲到,其作用就是解释数值,类似于型号类型中0数值代表这是电压类,1代表这是电流类,而这个数值解释则需要人为设定后完成再在信号这里完成关联即可。这样一来,这条信号中的数值则会解析为对应目标文本。如果这个信号仅仅是数值类,不需要解析,那无需关联value table。

5、创建Value Table

点击View->Value Tables,即可打开数值表界面,右键单击new即可添加一条描述,给完成给命名后主要选择后面的数值描述,在数值描述中点击添加,则会按照0/1/2/3……的顺序添加,然后点击各个数值后面的描述,标注各个值的含义即可。

如图所示,0代表电压类信息,1代表电流类信息,2代表控制类信息。完成编辑后信号就可以选择创建的Value Table了。

6、完善报文信息

依葫芦画瓢完成全部变量的定义后,就需要把这个变量塞进报文里面了。可以双击已建立的报文,然后再signal中选择添加,将所有创建的信号一股脑都完成添加。这个时候发现添加进去的信号前面有警告标识,报文只有8个字节数据数据域,在还没分组的时候它认为塞进来的信号已经超出了承载范围了,所以下一步是分类报文

我们都知道,所有的报文是根据byte0的不同内容进行分类的,所以我们需要在message界面中双击添加的MSG_TYPE信号,则会出现配置界面,在Multiplexortype中将其选为Multiplexor Signal,这样就确定了这个字节将作为后续分组的依据 (注意:每个Message只能有一个Multiplexor Signal类型信号)。

子分组的信号则将信号类型选择为Multiplexed Signal,不同的是会多一个Multiplex Value,意思就是要分到哪一组中,例如电压类则为0,电流类则为1,控制类则为2。

完成分组后可能还存在告警,是因为当时信号是一股脑塞进来,可能存在字节位定义重叠问题。所以,我们还需要进一步规整数据域内容。

双击创建的DEMO,在打开的界面的中选择layout,则可以看到当前数据域报文的BYTE位配置情况,因为上面已经完成了分组,所以依次将各个分组内的数据顺序排列好即可。这样我们的一条报文就创建完毕了。

7、效果查看

本例选用ZCANPRO来解析DBC文件,选用报文发送,选择DBC发送,然后再选择我们设定好的DBC文件即可完成解析。这样以后的报文收发就可以如下图所示的操作了,远比手动组帧和看裸报文解析便捷直观。

8、源码展示

下面是DBC的格式描述,大家可以保存到txt文件中,再将后缀修改为dbc,然后导入到上位机中查看效果。感兴趣的朋友们,还是亲自试一遍这个过程吧!

VERSION ""


NS_ :
NS_DESC_
CM_
BA_DEF_
BA_
VAL_
CAT_DEF_
CAT_
FILTER
BA_DEF_DEF_
EV_DATA_
ENVVAR_DATA_
SGTYPE_
SGTYPE_VAL_
BA_DEF_SGTYPE_
BA_SGTYPE_
SIG_TYPE_REF_
VAL_TABLE_
SIG_GROUP_
SIG_VALTYPE_
SIGTYPE_VALTYPE_
BO_TX_BU_
BA_DEF_REL_
BA_REL_
BA_DEF_DEF_REL_
BU_SG_REL_
BU_EV_REL_
BU_BO_REL_
SG_MUL_VAL_

BS_:

BU_:
VAL_TABLE_ MSG_TYPE 2 "控制类" 1 "电流类" 0 "电压类" ;
VAL_TABLE_ CTRL_CMD_TYPE 1 "开启" 0 "关闭" ;
VAL_TABLE_ CTRL_DEF 2 "预充继电器" 1 "负极继电器" 0 "正极继电器" ;
VAL_TABLE_ Cur_Val_Def 1 "输出电流" 0 "输入电流" ;
VAL_TABLE_ Vol_Val_Def 2 "逆变器电压" 1 "电网电压" 0 "电池电压" ;


BO_ 291 DEMO: 4 Vector__XXX
SG_ DEMO_VOL_CALSS m0 : 8|8@1+ (1,0) [0|0] "" Vector__XXX
SG_ DEMO_CUR_CLASS m1 : 8|8@1- (1,0) [0|0] "" Vector__XXX
SG_ DEMO_CTRL_CLASS m2 : 8|8@1+ (1,0) [0|0] "" Vector__XXX
SG_ MSG_TYPE M : 0|8@1+ (1,0) [0|0] "" Vector__XXX
SG_ VOL_VAL m0 : 16|16@1+ (1,0) [0|0] "V" Vector__XXX
SG_ CUR_VAL m1 : 16|16@1- (1,0) [0|0] "A" Vector__XXX
SG_ CTRL_CMD m2 : 16|8@1+ (1,0) [0|0] "" Vector__XXX



CM_ BO_ 291 "范例DEMO";
CM_ SG_ 291 DEMO_VOL_CALSS "电压类信息类型";
CM_ SG_ 291 DEMO_CUR_CLASS "电流类信息类型";
CM_ SG_ 291 DEMO_CTRL_CLASS "控制类信息类型";






请到「今天看啥」查看全文