DBC转Excel;DBC转位定义;Excel转DBC;Excel转位定义;MatrixCreat(三)之DBC文件详解

一、摘要

1.描述

本文主要描述的是汽车行业中DBC文件的格式,如何去解析它,如何通过文本编辑器去修改它,了解DBC文件之前如果不懂DBC的请去查看我之前的博客。

2.关键字

DBC,DBC解析,DBC数据库,DBC文件,C#解析DBC文件。

二、为什么要了解DBC文件

DBC文件在汽车行业应用十分广泛,如果编辑DBC文件我们都使用Vector工具CANdb++ Editor去编辑,那效率将会是十分的低下,当我们了解了DBC文件的构成后,我们可以通过其他方式进行解析,可以大大的提高工作的效率,我们可以通过记事本或者其他工具打开DBC文件。
在这里插入图片描述

三、DBC文件构成

1.版本

关键字:VERSION
格式:VERSION “version”
version就是版本信息,版本信息可以为空,但是不能省略""符。
例如:VERSION "V1.0"代表版本号为V1.0。
在这里插入图片描述

2.新符号

关键字:NS_:
DBC生成后都会自动生成新符号,所以这一部分的信息我们无需过多留意,一般默认即可,如果是通过其他方式去生成DBC文件时,可以直接复制该信息即可。
在这里插入图片描述

3.波特率

关键字:BS_:
格式:BS_:[baudrate:BTR1,BTR2]
其中[ ]内容表示为可选部分,可以省略,但关键字”BS_:”必须存在,省略会出错。
在这里插入图片描述

4.网络节点

关键字:BU_:
格式:BU_: name1 name2 name3 …
格式中的name1 、name2 等表示定义的网络节点名字,由用户自己定义;但需保证节点命名的唯一性。
例如:BU_: GW代表网络节点有GW。

5.报文消息

关键字:BO_
格式:BO_ Msg_ID Msg_Name: Msg_Length Msg_Transmitter
Msg_ID:报文标识符,十进制表示。
Msg_Name:报文名称,命名规则和C语言变量相同。
Msg_Length :报文长度,长度范围为0-8。
Msg_Transmitter:发送节点,如果该报文没有指定发送节点,则该值需设置为” Vector__XXX”。
例如:BO_ 1024 BCM_400: 8 BCM代表报文ID为0x400,报文名称为BCM_400,长度为8一个字节,发送节点为BCM。
在这里插入图片描述

6.信号消息

关键字:SG_
格式:SG_ Signal_Name : Start_Bit|Bit_Length@Byte_Order Date_Type (Factor, Offset) [Signal_Min_Value_Phy|Signal_Max_Value_Phy] “Unit” Receivers
Signal_Name:信号名称,命名规则和C语言变量相同。
Start_Bit:信号的起始位,范围为0-63。
Bit_Length:信号的长度,范围为1-64。
Byte_Order:信号的字节顺序:0代表Motorola格式,1代表Inter格式,这儿强调一下Motorola格式下的文本存储的是Motorola Msb格式的;
Date_Type:信号的数值类型:+表示无符号数,-表示有符号数。
Factor:精度。
Offset:偏移量,Factor和Offset这两个值于该信号的原始值与物理值之间的转换,转换如下:物理值=原始值*因子+偏移量。
Signal_Min_Value_Phy:物理总线最小值。
Signal_Max_Value_Phy:物理总线最大值。
Unit:信号的单位,为字符串类型,可以省略。
Receivers:信号的接收节点,若该信号没有指定的接收节点,则必须设置为” Vector__XXX”。
例如:SG_ BCM_WakeUp : 0|1@0+ (1,0) [0|1] “%” Vector__XXX代表信号名称为BCM_WakeUp,信号起始位为0,信号长度为 1,排列格式为Motorola Msb,数据类型为无符号,精度为1,偏移量为0,单位为%,无接收节点。
在这里插入图片描述

7.注释

关键字:CM_
格式:CM_ Object Msg_ID/Signal_Name “Signal_Description;”
Object:注解的对象类型,可以是节点“BU_”、报文“BO_”、消息”SG_”。
Msg_ID:报文标识符,十进制表示。
Signal_Name:信号名称,命名规则和C语言变量相同。
Signal_Description:信号描述,为字符串类型。
例如:CM_ BO_ 1024 “网络管理报文”;代表报文ID为0x400的报文描述为网络管理报文。
CM_ SG_ 1024 BCM_WakeUp “唤醒信号”;代表报文ID为0x400的报文中信号名称为BCM_WakeUp的描述信息为唤醒信号。
在这里插入图片描述

8.自定义属性

  • 关键字:**BA_DEF_ **
    格式:BA_DEF_ Object AttributeName ValueType Min Max;”
    Object:注解的对象类型,可以是节点“BU_”、报文“BO_”、消息”SG_”、网络节点” ”(用空格表示)。
    AttributeName: 自定义属性名称,命名规则和C语言变量相同。
    ValueType:属性值的类型,可以是整型、字符串、浮点型、枚举类型等。
    Min:属性值的最小值(字符串类型没有此项)。
    Min:属性值的最大值(字符串类型没有此项)。
    例如:BA_DEF_ “ECU” STRING ;代表自定义网络节点属性名称为ECU,类型为字符串型。
    BA_DEF_ BO_ “MsgCycleTime” INT 0 1000;代表自定义报文属性名称为MsgCycleTime,类型为整型,取值范围为0-1000。

  • 关键字:**BA_DEF_DEF_ **
    格式:BA_DEF_DEF_ AttributeName DefaultValue;”
    AttributeName: 自定义属性名称,命名规则和C语言变量相同。
    DefaultValue:默认值。
    例如:BA_DEF_DEF_ “MsgCycleTime” 0;代表自定义属性名称为MsgCycleTime的默认值为0。

  • 关键字:BA_
    格式:BA_ AttributeName Object /Signal_Name Msg_ID DefaultValue;”
    AttributeName: 自定义属性名称,命名规则和C语言变量相同。
    Object:注解的对象类型,可以是节点“BU_”、报文“BO_”、消息”SG_”、网络节点” ”(用空格表示)。
    Signal_Name:信号名称,命名规则和C语言变量相同。
    Msg_ID:报文标识符,十进制表示。
    DefaultValue:默认值。
    例如:BA_ “MsgCycleTime” BO_ 1024 0;代表自定义报文ID为0x400的报文属性名称MsgCycleTime值为100。
    在这里插入图片描述

9.数值表

关键字:VAL_
格式:VAL_ Msg_ID Signal_Name N “DefineN” …… 0 “Define0”;”
Msg_ID:报文标识符,十进制表示。
Signal_Name:信号名称,命名规则和C语言变量相同。
N “DefineN” …… 0 “Define0”:表示定义的数值表内容,即该信号的有效值分别用什么符号表示。
例如:VAL_ 1024 BCM_WakeUp 1 “off” 0 “on” ;代表报文ID为0x400中的信号名称为BCM_WakeUp的值0x01代表off,0x00代表on。
在这里插入图片描述

四、DBC文件解析

通过以上描述,我相信各位对DBC文件的结构有一定的了解,但是我们如何去解析呢,很多人第一时间想到的应该是按行解析,其实DBC文件有许多容错处理,单纯按行解析我们会错过许多细节部分,例如下图其实也没有出错,如果按行解析的话报文就解析不到了。
在这里插入图片描述
还有很多类似的容错处理在里面,所以单纯按行解析是不行的,并且有的时候也是不能通过空格来分开数据的,比如带有“”的前后是可以不追加空格的。
在这里插入图片描述
经过好久的挣扎,查询资料,终于在一个博客的找到了一种解析的方式,通过正则表达式去解析,当然他其实是按行解析,其实会丢掉一些数据,我将方法进行了一些简单的优化,先读取整个文件到字符串,把多行空格转换成一行空格,然后把换行符转换成空格符,然后进行查找,然后按照标准进行拆分。我这边解析的主要使用的C#语言,因为C#语言对字符串有友好的操作,我将部分代码粘贴如下,方便大家参考学习。

1.解析版本

       /**********************************************/
        ///<summary>
        ///Name    :AnalysisVersion
        ///Author  :WangHu
        ///Function:***
        ///Version :V1.0.0
        ///Data    :2022.5.20
        ///</summary>
        /**********************************************/
        private static bool AnalysisVersion(MsgInfo_Type msgInfo, string data)
        {
            string pattern = "VERSION(([ ]+)|)\"((\\w+)|)\"";
            MatchCollection matchs = Regex.Matches(data, pattern);
            foreach (Match match in matchs)
            {
                if (matchs.Count == 1)
                {
                    string[] array = match.Value.Split(new string[] { @"""" }, StringSplitOptions.RemoveEmptyEntries);
                    if (array.Length >= 2) {  msgInfo.version = array[1]; }
                    return true;
                }
            }
            return true;
        }

2.解析报文消息

       /**********************************************/
        ///<summary>
        ///Name    :AnalysisMessagePattern
        ///Author  :WangHu
        ///Function:***
        ///Version :V1.0.0
        ///Data    :2022.5.20
        ///</summary>
        /**********************************************/
        private static bool AnalysisMessagePattern(List<Message_Type> messages, string data)
        {
            string messagePattern = "BO_[ ]+(\\d+)[ ]+(\\w+):(([ ]+)|)(\\d+)[ ]+(\\w+)[ ]*(SG_[ ]+(\\w+)(([ ]+)|)(((m)(\\d+[ ]+))|(M[ ]+))?:(([ ]+)|)(\\d+)(([ ]+)|)\\|(([ ]+)|)(\\d+)(([ ]+)|)@(([ ]+)|)([0|1])(([ ]+)|)([+|-])(([ ]+)|)+\\((([ ]+)|)((\\d|\\.|E|\\-|\\+)+)(([ ]+)|),(([ ]+)|)((\\d|\\.|E|\\-|\\+)+)(([ ]+)|)\\)(([ ]+)|)\\[(([ ]+)|)((\\d|\\.|E|\\-|\\+)+)(([ ]+)|)\\|(([ ]+)|)((\\d|\\.|E|\\-|\\+)+)(([ ]+)|)\\](([ ]+)|)\"((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*)\"(([ ]+)|)(\\w+(,[ ]*\\w+)*)[ ]*)*";
            foreach (Match messageMatch in Regex.Matches(data, messagePattern))
            {
                string msgPattern = "BO_[ ]+(\\d+)[ ]+(\\w+):(([ ]+)|)(\\d+)[ ]+(\\w+)";
                Match msgMatch = Regex.Matches(messageMatch.Value, msgPattern)[0];
                string[] array = msgMatch.Value.Split(new string[] { " ", ":" }, StringSplitOptions.RemoveEmptyEntries);
                uint? id = CommonLib.ToDec(array[1]) & 0x7FFFFFFF;
                if (id == null) { continue; }
                Message_Type message = FindMessage(messages, (uint)id);
                if (message == null)
                {
                    message = new Message_Type();
                    messages.Add(message);
                }
                message.id = CommonLib.ToDec(array[1]) & 0x7FFFFFFF;
                message.name = CommonLib.ToVar(array[2]);
                message.length = CommonLib.ToInt(array[3]);
                message.transmitter = CommonLib.ToStr(array[4]) == "Vector__XXX" ? null : CommonLib.ToStr(array[4]);
                message.cycleTime = message.cycleTimeFast = message.nrOfRepetition = message.delayTime = null;
                string signalPattern = "SG_[ ]+(\\w+)(([ ]+)|)(((m)(\\d+[ ]+))|(M[ ]+))?:(([ ]+)|)(\\d+)(([ ]+)|)\\|(([ ]+)|)(\\d+)(([ ]+)|)@(([ ]+)|)([0|1])(([ ]+)|)([+|-])(([ ]+)|)+\\((([ ]+)|)((\\d|\\.|E|\\-|\\+)+)(([ ]+)|),(([ ]+)|)((\\d|\\.|E|\\-|\\+)+)(([ ]+)|)\\)(([ ]+)|)\\[(([ ]+)|)((\\d|\\.|E|\\-|\\+)+)(([ ]+)|)\\|(([ ]+)|)((\\d|\\.|E|\\-|\\+)+)(([ ]+)|)\\](([ ]+)|)\"((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*)\"(([ ]+)|)(\\w+(,[ ]*\\w+)*)";
                foreach (Match signalMatch in Regex.Matches(messageMatch.Value, signalPattern))
                {
                    try
                    {
                        string str = signalMatch.Value.Replace("- ", " - ").Replace("+ ", " + ").Replace("-(", " -(").Replace("+(", " +(");
                        string[] array1 = str.Split(new string[] { @"""" }, StringSplitOptions.None);
                        string[] array2 = array1[0].Split(new string[] { " ", ":", ",", "|", "@", "(", ")", "[", "]" }, StringSplitOptions.RemoveEmptyEntries);
                        int startbit = (int)CommonLib.ToInt(array2[2]);
                        int bitlenth = (int)CommonLib.ToInt(array2[3]);
                        int sigbyte = (startbit / 8) + ((bitlenth - 1) / 8) + (((startbit % 8) + 1 - ((bitlenth % 8) == 0 ? 8 : (bitlenth % 8))) >= 0 ? 0 : 1);
                        int sigbit = (startbit + 8 + 1 - (bitlenth % 8)) % 8;
                        int siglsb = (sigbyte * 8) + sigbit;
                        List<string> receivers = new List<string>();
                        string[] array3 = array1[2].Split(new string[] { " ", "," }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (string receiver in array3) { if (!receiver.Equals("Vector__XXX")) { receivers.Add(receiver); } }
                        message.signals.Add(new Signal_Type
                        {
                            name = CommonLib.ToVar(array2[1]),
                            startBit = array2[4].Contains("0") ? siglsb : CommonLib.ToInt(array2[2]),
                            length = CommonLib.ToInt(array2[3]),
                            byteOrder = (ByteOrderEnum)CommonLib.ToInt(array2[4]),
                            dataType = array2[5].Contains("-") ? DataTypeEnum.SIGNED : DataTypeEnum.UNSIGNED,
                            factor = (double)CommonLib.ToDouble(array2[6]),
                            offset = (double)CommonLib.ToDouble(array2[7]),
                            minValuePhy = CommonLib.ToDouble(array2[8]),
                            maxValuePhy = CommonLib.ToDouble(array2[9]),
                            unit = CommonLib.ToStr(array1[1]),
                            receivers = receivers
                        });
                    }
                    catch { continue; }
                }
            }
            return true;
        }

3.解析节点信息

       /**********************************************/
        ///<summary>
        ///Name    :AnalysisNodes
        ///Author  :WangHu
        ///Function:***
        ///Version :V1.0.0
        ///Data    :2022.5.20
        ///</summary>
        /**********************************************/
        private static bool AnalysisNodes(MsgInfo_Type msgInfo)
        {
            if (msgInfo.messages.Count == 0) { return false; }
            foreach (Message_Type message in msgInfo.messages)
            {
                if ((message.transmitter != null) && (!msgInfo.nodes.Contains(message.transmitter))) { msgInfo.nodes.Add(message.transmitter); }
                foreach (Signal_Type signal in message.signals)
                {
                    if (signal.sendType == null) { signal.sendType = message.sendType; }
                    foreach (string receiver in signal.receivers)
                    {
                        if (msgInfo.nodes.Contains(receiver)) { continue; }
                        msgInfo.nodes.Add(receiver);
                    }
                }
            }
            msgInfo.busType = BusTypeEnum.CAN;
            return true;
        }

4.解析注释

       /**********************************************/
        ///<summary>
        ///Name    :AnalysisCommentsPattern
        ///Author  :WangHu
        ///Function:***
        ///Version :V1.0.0
        ///Data    :2022.5.20
        ///</summary>
        /**********************************************/
        private static bool AnalysisCommentsPattern(List<Message_Type> messages, string data)
        {
            string pattern = "CM_[ ]+((((BU_)|(BO_)|(SG_))[ ]+(\\d+)[ ]+(\\w*)(([ ]+)|))|)\"((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*)\"(([ ]+)|);";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                string[] array1 = match.Value.Split(new string[] { @"""" }, StringSplitOptions.None);
                string[] array2 = array1[0].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                if (array2.Length == 1) { string comments = array1[1]; }
                else
                {

                    if (array2[1] == "BO_")
                    {
                        uint? id = CommonLib.ToDec(array2[2]) & 0x7FFFFFFF;
                        if (id == null) { continue; }
                        Message_Type message = FindMessage(messages, (uint)id);
                        if (message == null) { continue; }
                        message.comments = array1[1];
                    }
                    else if (array2[1] == "SG_")
                    {
                        uint? id = CommonLib.ToDec(array2[2]) & 0x7FFFFFFF;
                        if (id == null) { continue; }
                        Message_Type message = FindMessage(messages, (uint)id);
                        if (message == null) { continue; }
                        string name = CommonLib.ToVar(array2[3]);
                        foreach (Signal_Type signal in message.signals)
                        {
                            if (name == signal.name)
                            {
                                signal.descrption = array1[1];
                                break;
                            }
                        }
                    }
                }
            }
            return true;
        }

5.解析自定义属性描述

       /**********************************************/
        ///<summary>
        ///Name    :AnalysisNatureDefinitionPattern
        ///Author  :WangHu
        ///Function:***
        ///Version :V1.0.0
        ///Data    :2022.5.20
        ///</summary>
        /**********************************************/
        private static bool AnalysisNatureDefinitionPattern(List<Nature_Type> natures, string data)
        {
            string pattern = "BA_DEF_[ ]+((BU_)|(BO_)|(SG_)|(EV_))?(([ ]+)|)\"(\\w+)\"(([ ]+)|)(((INT)[ ]+([+|-]?\\d+)[ ]+([+|-]?\\d+))|((HEX)[ ]+([+|-]?\\d+)[ ]+([+|-]?\\d+))|((FLOAT)[ ]+((\\d|\\.|E|\\-|\\+)+)[ ]+((\\d|\\.|E|\\-|\\+)+))|(STRING)|((ENUM)(([ ]+)|)(\"((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*)\"([ ]*,(([ ]+)|)\"((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*)\")*)))[ ]*(([ ]+)|);";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                string[] array1 = match.Value.Split(new string[] { " ", @"""" }, StringSplitOptions.RemoveEmptyEntries);
                Nature_Type nat = new Nature_Type();
                foreach (Nature_Type nature in natures) { if ((nature.family == array1[1]) && (nature.name == array1[2])) { nat = nature; } }
                nat.family = array1[1];
                nat.name = CommonLib.ToVar(array1[2]);
                int startNum = 3;
                if ((nat.family != "BU_") && (nat.family != "BO_") && (nat.family != "SG_") && (nat.family != "EV_"))
                {
                    startNum = 2;
                    nat.family = null;
                    nat.name = CommonLib.ToVar(array1[1]);
                }
                nat.type = array1[startNum];
                if ((nat.type == "INT") || (nat.type == "HEX") || (nat.type == "FLOAT"))
                {
                    nat.data.Add(array1[startNum + 1]);
                    nat.data.Add(array1[startNum + 1]);
                }
                else if (nat.type == "ENUM")
                {
                    string[] array2 = match.Value.Split(new string[] { "ENUM" }, StringSplitOptions.RemoveEmptyEntries);
                    string[] array3 = CommonLib.ToStr(array2[1]).Split(new string[] { ",", @"""" }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < array3.Length - 1; i++) { nat.data.Add(array3[i]); }
                }
                natures.Add(nat);
            }
            return true;
        }

6.解析自定义属性默认值

       /**********************************************/
        ///<summary>
        ///Name    :AnalysisNatureDefaultPattern
        ///Author  :WangHu
        ///Function:***
        ///Version :V1.0.0
        ///Data    :2022.5.20
        ///</summary>
        /**********************************************/
        private static bool AnalysisNatureDefaultPattern(MsgInfo_Type msgInfo, string data)
        {
            string pattern = "BA_DEF_DEF_[ ]+\"(\\w+)\"(([ ]+)|)\"?(([+|-]?\\d*.?\\d*)|((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*))\"?(([ ]+)|);";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                string str = match.Value.Replace(@""" ", @"""").Replace(@" """, @"""").Trim(';');
                string[] array = str.Split(new string[] { @"""" }, StringSplitOptions.RemoveEmptyEntries);
                string name = CommonLib.ToVar(array[1]);
                string value = 2 >= array.Length ? "" : array[2];
                foreach (Nature_Type nature in msgInfo.natures)
                {
                    if (nature.name == name)
                    {
                        if (name.Equals("BusType"))
                        {
                            msgInfo.busType = value.Equals("CAN") ? BusTypeEnum.CAN : BusTypeEnum.CANFD;
                            continue;
                        }
                        foreach (Message_Type message in msgInfo.messages)
                        {
                            switch (name)
                            {
                                case "GenMsgCycleTime":
                                    message.cycleTime = CommonLib.ToInt(value);
                                    break;
                                case "GenMsgCycleTimeFast":
                                    message.cycleTimeFast = CommonLib.ToInt(value);
                                    break;
                                case "GenMsgNrOfRepetition":
                                    message.nrOfRepetition = CommonLib.ToInt(value);
                                    break;
                                case "GenMsgDelayTime":
                                    message.delayTime = CommonLib.ToInt(value);
                                    break;
                                case "NmMessage":
                                    message.type = value.ToLower().Contains("yes") ? TypeEnum.NM : TypeEnum.NORMAL;
                                    break;
                                case "GenMsgSendType":
                                    message.sendType = value;
                                    break;
                                default:
                                    break;
                            }
                            foreach (Signal_Type signal in message.signals)
                            {
                                switch (name)
                                {
                                    case "GenSigStartValue":
                                        signal.initValue = CommonLib.ToInt(value);
                                        break;
                                    case "GenSigTimeoutValue":
                                        signal.invalidValue = CommonLib.ToInt(value);
                                        break;
                                    case "GenSigInactiveValue":
                                        signal.inactiveValue = CommonLib.ToInt(value);
                                        break;
                                    case "GenSigSendType":
                                        signal.sendType = value;
                                        break;
                                    case "GenSigMinValue":
                                        signal.minValue = CommonLib.ToInt(value);
                                        break;
                                    case "GenSigMaxValue":
                                        signal.maxValue = CommonLib.ToInt(value);
                                        break;
                                    default:
                                        break;
                                }
                            }
                        }
                        nature.initValue = value;
                    }
                }
            }
            return true;
        }

7.解析自定义属性值

       /**********************************************/
        ///<summary>
        ///Name    :AnalysisNatureValuePattern
        ///Author  :WangHu
        ///Function:***
        ///Version :V1.0.0
        ///Data    :2022.5.20
        ///</summary>
        /**********************************************/
        private static bool AnalysisNatureValuePattern(MsgInfo_Type msgInfo, string data)
        {
            string pattern = "BA_[ ]+\"(\\w+)\"(([ ]+)|)(((BU_)[ ]+(\\w+)[ ]+)|((BO_)[ ]+(\\d+)[ ]+)|((SG_)[ ]+(\\d+)[ ]+(\\w+)[ ]+)|((EV_)[ ]+(\\w+)[ ]+))?\"?(([+|-]?\\d*.?\\d*)|((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*))\"?(([ ]+)|);";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                string str = match.Value.Trim(';');
                string[] array = str.Split(new string[] { " ", @"""" }, StringSplitOptions.RemoveEmptyEntries);
                string name = CommonLib.ToVar(array[1]);
                foreach (Nature_Type nature in msgInfo.natures)
                {
                    if (nature.name == name)
                    {
                        if (name.Equals("BusType"))
                        {
                            msgInfo.busType = array[2].Equals("CAN") ? BusTypeEnum.CAN : BusTypeEnum.CANFD;
                            continue;
                        }
                        uint? id = array.Length <= 3 ? null : (CommonLib.ToDec(array[3]) & 0x7FFFFFFF);
                        if (id == null) { continue; }
                        Message_Type message = FindMessage(msgInfo.messages, (uint)id);
                        if (message == null) { continue; }
                        string type = array[2];
                        try
                        {
                            if (type == "BO_")
                            {
                                switch (name)
                                {
                                    case "GenMsgCycleTime":
                                        message.cycleTime = CommonLib.ToInt(array[4]);
                                        break;
                                    case "GenMsgCycleTimeFast":
                                        message.cycleTimeFast = CommonLib.ToInt(array[4]);
                                        break;
                                    case "GenMsgNrOfRepetition":
                                        message.nrOfRepetition = CommonLib.ToInt(array[4]);
                                        break;
                                    case "GenMsgDelayTime":
                                        message.delayTime = CommonLib.ToInt(array[4]);
                                        break;
                                    case "NmMessage":
                                        message.type = nature.data[(int)CommonLib.ToInt(array[4])].ToLower().Contains("yes") ? TypeEnum.NM : TypeEnum.NORMAL;
                                        break;
                                    case "GenMsgSendType":
                                        message.sendType = nature.data[(int)CommonLib.ToInt(array[4])];
                                        break;
                                    default:
                                        break;
                                }
                            }
                            else if (type == "SG_")
                            {
                                foreach (Signal_Type signal in message.signals)
                                {
                                    if (signal.name == array[4])
                                    {
                                        switch (name)
                                        {
                                            case "GenSigStartValue":
                                                signal.initValue = CommonLib.ToInt(array[5]);
                                                break;
                                            case "GenSigTimeoutValue":
                                                signal.invalidValue = CommonLib.ToInt(array[5]);
                                                break;
                                            case "GenSigInactiveValue":
                                                signal.inactiveValue = CommonLib.ToInt(array[5]);
                                                break;
                                            case "GenSigSendType":
                                                signal.sendType = nature.data[(int)CommonLib.ToInt(array[5])];
                                                break;
                                            case "GenSigMinValue":
                                                signal.minValue = CommonLib.ToInt(array[5]);
                                                break;
                                            case "GenSigMaxValue":
                                                signal.maxValue = CommonLib.ToInt(array[5]);
                                                break;
                                            default:
                                                break;
                                        }
                                    }
                                }
                            }
                        }
                        catch { continue; }
                    }
                }
            }
            return true;
        }

8.解析数值表

       /**********************************************/
        ///<summary>
        ///Name    :AnalysisSignalValueDescriptionPattern
        ///Author  :WangHu
        ///Function:***
        ///Version :V1.0.0
        ///Data    :2022.5.20
        ///</summary>
        /**********************************************/
        private static bool AnalysisSignalValueDescriptionPattern(List<Message_Type> messages, string data)
        {
            string pattern = "VAL_[ ]+(\\d+)[ ]+(\\w+)[ ]+(((\\d+.?\\d*)(([ ]+)|)\"((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*)\"[ ]*)*)+(([ ]+)|);";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                string str = match.Value.Replace(@""" ", @"""").Replace(@" """, @"""").Trim(';');
                string[] array1 = str.Split(new string[] { @"""" }, StringSplitOptions.RemoveEmptyEntries);
                string[] array2 = array1[0].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                uint? id = CommonLib.ToDec(array2[1]) & 0x7FFFFFFF;
                if (id == null) { continue; }
                Message_Type message = FindMessage(messages, (uint)id);
                if (message == null) { continue; }
                string name = CommonLib.ToVar(array2[2]);
                foreach (Signal_Type signal in message.signals)
                {
                    if (signal.name == name)
                    {
                        for (int i = 0; i < array1.Length / 2; i++)
                        {
                            ValueDescriptionInfoModel valueDescription = new ValueDescriptionInfoModel();
                            if (i == 0)
                            {
                                valueDescription.Value = CommonLib.ToDec(array2[3]);
                                valueDescription.Name = array1[1];
                            }
                            else
                            {
                                valueDescription.Value = CommonLib.ToDec(array1[2 * i]);
                                valueDescription.Name = array1[(2 * i) + 1];
                            }
                            signal.valueDescriptions.Add(valueDescription);
                        }
                        break;
                    }
                }
            }
            return true;
        }

五、MatrixCreat工具

这儿我只把链接放上,具体使用说明见后续章节。
DBC转Excel;DBC转位定义;Excel转DBC;Excel转位定义:https://download.csdn.net/download/weixin_44926112/86912538

六、其他

本文主要是讲解DBC文件的结构和如何解析DBC文件,有些地方可能会有描述性的错误,希望看到的朋友及时指出,我会及时更正错误,其他地方有些借鉴的描述,写此文章的目的是为了交流,非商业用途,欢迎私信讨论,感谢大家阅读。

七、参考

【1】:https://blog.csdn.net/weixin_44536482/article/details/89030152
【2】:https://blog.csdn.net/Jiang_Mr/article/details/103417163

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值