前言:
? ? ? ? 在做工程機械CAN協議相關的軟件開發與調試時,經常接觸到DBC的使用,可以在CAN分析儀中加載DBC文件從而快速查看某條CAN報文或信號的含義,以及使用圖形化的調試。
? ? ? ? 而編輯DBC文件,正常是用CANDB++來一條條添加,比較費時費力。其實可以直接使用文本編輯器打開dbc文件,通過復制粘貼以及修改的方法快速添加報文和信號。
? ? ? ? 很多文本編輯器都能打開dbc文件,但是比如記事本等是沒有關鍵字高亮顯示的功能的,因此最好是用notepad++和VScode,由于我本身就安裝了VScode。所以我就用VScode來實現。
????????VScode需要安裝一個插件,在插件搜索欄中輸入“DBC”,第一個就是DBC language Syntax,安裝即可。實際使用發現能自動高亮,并且某些錯誤還能自動波浪線提醒。還比較好用。
? ? ? ? 搜索了一下,目前網上的資料較少,還是自己測試整理后分享給大家吧。
一、創建一個基礎的DBC文件。
? ? ? ? 1)這里還是得用CANDB++,我直接用的1939模板。
? ? ? ? 2)dbc文件中隨意輸入1個message和2個信號,并將信號掛在到message中
二、用文本編輯器修改
2.1 vscode打開保存的DBC文件:
????????
VERSION ""NS_ : NS_DESC_CM_BA_DEF_BA_VAL_CAT_DEF_CAT_FILTERBA_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_:BO_ 2364539904 Engin_state: 8 Vector__XXXSG_ Engin_MA : 20|12@1+ (1,-2000) [-2000|63535] "mA" Vector__XXXSG_ Engin_RPM : 8|8@1+ (1,0) [0|0] "rpm" Vector__XXXBA_DEF_ BO_ "TpJ1939VarDlc" ENUM "No","Yes";
BA_DEF_ SG_ "SigType" ENUM "Default","Range","RangeSigned","ASCII","Discrete","Control","ReferencePGN","DTC","StringDelimiter","StringLength","StringLengthControl";
BA_DEF_ SG_ "GenSigEVName" STRING ;
BA_DEF_ SG_ "GenSigILSupport" ENUM "No","Yes";
BA_DEF_ SG_ "GenSigSendType" ENUM "Cyclic","OnWrite","OnWriteWithRepetition","OnChange","OnChangeWithRepetition","IfActive","IfActiveWithRepetition","NoSigSendType";
BA_DEF_ BO_ "GenMsgFastOnStart" INT 0 100000;
BA_DEF_ SG_ "GenSigInactiveValue" INT 0 0;
BA_DEF_ BO_ "GenMsgCycleTimeFast" INT 0 3600000;
BA_DEF_ BO_ "GenMsgNrOfRepetition" INT 0 1000000;
BA_DEF_ SG_ "GenSigStartValue" INT 0 2147483647;
BA_DEF_ BO_ "GenMsgDelayTime" INT 0 1000;
BA_DEF_ BO_ "GenMsgILSupport" ENUM "No","Yes";
BA_DEF_ BO_ "GenMsgStartDelayTime" INT 0 100000;
BA_DEF_ BU_ "NodeLayerModules" STRING ;
BA_DEF_ BU_ "ECU" STRING ;
BA_DEF_ BU_ "NmJ1939SystemInstance" INT 0 15;
BA_DEF_ BU_ "NmJ1939System" INT 0 127;
BA_DEF_ BU_ "NmJ1939ManufacturerCode" INT 0 2047;
BA_DEF_ BU_ "NmJ1939IndustryGroup" INT 0 7;
BA_DEF_ BU_ "NmJ1939IdentityNumber" INT 0 2097151;
BA_DEF_ BU_ "NmJ1939FunctionInstance" INT 0 7;
BA_DEF_ BU_ "NmJ1939Function" INT 0 255;
BA_DEF_ BU_ "NmJ1939ECUInstance" INT 0 3;
BA_DEF_ BU_ "NmJ1939AAC" INT 0 1;
BA_DEF_ BU_ "NmStationAddress" INT 0 255;
BA_DEF_ BO_ "GenMsgSendType" ENUM "cyclic","NotUsed","IfActive","NotUsed","NotUsed","NotUsed","NotUsed","NotUsed","noMsgSendType";
BA_DEF_ BO_ "GenMsgRequestable" INT 0 1;
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 3600000;
BA_DEF_ SG_ "SPN" INT 0 524287;
BA_DEF_ "DBName" STRING ;
BA_DEF_ "BusType" STRING ;
BA_DEF_ "ProtocolType" STRING ;
BA_DEF_ BO_ "VFrameFormat" ENUM "StandardCAN","ExtendedCAN","reserved","J1939PG";
BA_DEF_DEF_ "TpJ1939VarDlc" "No";
BA_DEF_DEF_ "SigType" "Default";
BA_DEF_DEF_ "GenSigEVName" "Env@Nodename_@Signame";
BA_DEF_DEF_ "GenSigILSupport" "Yes";
BA_DEF_DEF_ "GenSigSendType" "NoSigSendType";
BA_DEF_DEF_ "GenMsgFastOnStart" 0;
BA_DEF_DEF_ "GenSigInactiveValue" 0;
BA_DEF_DEF_ "GenMsgCycleTimeFast" 0;
BA_DEF_DEF_ "GenMsgNrOfRepetition" 0;
BA_DEF_DEF_ "GenSigStartValue" 0;
BA_DEF_DEF_ "GenMsgDelayTime" 0;
BA_DEF_DEF_ "GenMsgILSupport" "Yes";
BA_DEF_DEF_ "GenMsgStartDelayTime" 0;
BA_DEF_DEF_ "NodeLayerModules" "";
BA_DEF_DEF_ "ECU" "";
BA_DEF_DEF_ "NmJ1939SystemInstance" 0;
BA_DEF_DEF_ "NmJ1939System" 0;
BA_DEF_DEF_ "NmJ1939ManufacturerCode" 0;
BA_DEF_DEF_ "NmJ1939IndustryGroup" 0;
BA_DEF_DEF_ "NmJ1939IdentityNumber" 0;
BA_DEF_DEF_ "NmJ1939FunctionInstance" 0;
BA_DEF_DEF_ "NmJ1939Function" 0;
BA_DEF_DEF_ "NmJ1939ECUInstance" 0;
BA_DEF_DEF_ "NmJ1939AAC" 0;
BA_DEF_DEF_ "NmStationAddress" 254;
BA_DEF_DEF_ "GenMsgSendType" "noMsgSendType";
BA_DEF_DEF_ "GenMsgRequestable" 1;
BA_DEF_DEF_ "GenMsgCycleTime" 0;
BA_DEF_DEF_ "SPN" 0;
BA_DEF_DEF_ "DBName" "";
BA_DEF_DEF_ "BusType" "CAN";
BA_DEF_DEF_ "ProtocolType" "J1939";
BA_DEF_DEF_ "VFrameFormat" "J1939PG";
BA_ "DBName" "J1939";
BA_ "VFrameFormat" BO_ 2364539904 3;
2.2 其中可以找到跟ID相關的兩行文本:
????????????????BO_ 2364539904 Engin_state: 8 Vector__XXX
?????????????????SG_ Engin_MA : 20|12@1+ (1,-2000) [-2000|63535] "mA" Vector__XXX
?????????????????SG_ Engin_RPM : 8|8@1+ (1,0) [0|0] "rpm" Vector__XXX
????????????????BA_ "VFrameFormat" BO_ 2364539904 3;//這行在最后
2.3 message報文格式說明
? ? ? ? 注意:最后一行(BA_....)中的報文ID與BO_ 這一行的報文ID必須對應,即一個報文對應這兩行。
message id的說明:
BO_ <MessageID> <MessageName>: <DLC> <SenderNode>
- 參數說明:
<MessageID>
:消息 ID(10 進制或 16 進制,16 進制需加0x
前綴)。<MessageName>
:消息名稱(自定義,如 “Engine_Status”)。<DLC>
:數據長度(Data Length Code,0~8 字節,即 0~8)。<SenderNode>
:發送節點(需在NODE_
中定義過,如 “ECU_Engine”)。
2.4 信號說明
????????? ? ? ?
SG_ <SignalName> : <StartBit>|<BitLength>@<ByteOrder><ValueType> (<Factor>,<Offset>) [<Min>|<Max>] "<Unit>" <ReceiverNode>
- 參數說明:
<SignalName>
:信號名稱(如 “Engine_Speed”)。<StartBit>
:起始位(消息數據域中的起始位置,0~63,從最低位 0 開始計數)。<BitLength>
:位長度(信號占用的位數,1~64)。<ByteOrder>
:字節序(0
= 小端模式 Little-Endian,1
= 大端模式 Big-Endian)。<ValueType>
:數據類型(+
= 無符號 unsigned,-
= 有符號 signed)。<Factor>,<Offset>
:縮放因子和偏移量(物理值 = 原始值 ×Factor + Offset)。<Min>|<Max>
:物理值范圍(可選,如0|8000
表示 0~8000)。<Unit>
:物理單位(可選,如 “rpm”“km/h”)。<ReceiverNode>
:接收節點(多個節點用逗號分隔,如 “ECU_Display,Sensor_Brake”)。
2.5 按照這個格式添加新的報文ID和對應的信號
? ? ? ? ? ? ? ? 例如:
????????????????
.....BO_ 2364539904 Engin_state: 8 Vector__XXXSG_ Engin_MA : 20|12@1+ (1,-2000) [-2000|63535] "mA" Vector__XXXSG_ Engin_RPM : 8|8@1+ (1,0) [0|0] "rpm" Vector__XXX
BO_ 2364539903 QQ_state: 8 Vector__XXXSG_ QQ_MA : 20|12@1+ (1,-2000) [-2000|63535] "mA" Vector__XXXSG_ QQ_RPM : 8|8@1+ (1,0) [0|0] "rpm" Vector__XXX......BA_ "VFrameFormat" BO_ 2364539904 3;
BA_ "VFrameFormat" BO_ 2364539903 3;
? ? ? ? ? ? ? ? 保存后用CANDB++打開效果:
????????? ? ? ? ? ? ? ??
注意:
最后一行(BA_)最后的3表示報文格式,即行內VFrameFormat對應的枚舉:搜索可以查到枚舉定義:
BA_DEF_ BO_ ?"VFrameFormat" ENUM ?"StandardCAN","ExtendedCAN","reserved","J1939PG";
因此,3就表示J1939PG,如果想添加其他格式的報文則需要修改這個,即標準幀為0,這個可以在candb++中添加對應類型的報文來驗證:
三、添加注釋
3.1 使用//
這種方法只能在編輯器中可以看到,確實可行,但需要注意這種方式做好的DBC文件,如果使用CANDB++再保存一下以后,注釋內容會消失掉,因此不推薦
3.2 使用CM_
這種方法不如//直接,只能在所有的報文定義后面寫,即BA_DEF_前面緊挨著。
而且只能內容必須與ID、signal、節點等一起。
而且填寫的內容會出現在CANDB++的comment中
示例:
BO_ 2364539903 QQ_state: 8 Vector__XXXSG_ QQ_MA : 20|12@1+ (1,-2000) [-2000|63535] "mA" Vector__XXXSG_ QQ_RPM : 8|8@1+ (1,0) [0|0] "rpm" Vector__XXX//其他的報文定義CM_ BO_ 2565931047 "hhhh";//只能寫在這里
BA_DEF_ BO_ "TpJ1939VarDlc" ENUM "No","Yes";