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

DBC文件详解

  • 一、摘要
    • 1.描述
    • 2.关键字
  • 二、为什么要了解DBC文件
  • 三、DBC文件构成
    • 1.版本
    • 2.新符号
    • 3.波特率
    • 4.网络节点
    • 5.报文消息
    • 6.信号消息
    • 7.注释
    • 8.自定义属性
    • 9.数值表
  • 四、DBC文件解析
    • 1.解析版本
    • 2.解析报文消息
    • 3.解析信号消息
    • 4.解析注释
    • 5.解析自定义属性描述
    • 6.解析自定义属性默认值
    • 7.解析自定义属性值
    • 8.解析数值表
  • 五、MatrixCreat工具
  • 六、其他
  • 七、参考

一、摘要

1.描述

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

2.关键字

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

二、为什么要了解DBC文件

DBC文件在汽车行业应用十分广泛,如果编辑DBC文件我们都使用Vector工具CANdb++ Editor去编辑,那效率将会是十分的低下,当我们了解了DBC文件的构成后,我们可以通过其他方式进行解析,可以大大的提高工作的效率,我们可以通过记事本或者其他工具打开DBC文件。
DBC转Excel;DBC转位定义;Excel转DBC;Excel转位定义;MatrixCreat(三)之DBC文件详解_第1张图片

三、DBC文件构成

1.版本

关键字:VERSION
格式:VERSION "version"
version就是版本信息,版本信息可以为空,但是不能省略""符。
例如:VERSION "V1.0"代表版本号为V1.0。
DBC转Excel;DBC转位定义;Excel转DBC;Excel转位定义;MatrixCreat(三)之DBC文件详解_第2张图片

2.新符号

关键字:NS_:
DBC生成后都会自动生成新符号,所以这一部分的信息我们无需过多留意,一般默认即可,如果是通过其他方式去生成DBC文件时,可以直接复制该信息即可。
DBC转Excel;DBC转位定义;Excel转DBC;Excel转位定义;MatrixCreat(三)之DBC文件详解_第3张图片

3.波特率

关键字:BS_:
格式:BS_:[baudrate:BTR1,BTR2]
其中[ ]内容表示为可选部分,可以省略,但关键字”BS_:”必须存在,省略会出错。
DBC转Excel;DBC转位定义;Excel转DBC;Excel转位定义;MatrixCreat(三)之DBC文件详解_第4张图片

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。
    DBC转Excel;DBC转位定义;Excel转DBC;Excel转位定义;MatrixCreat(三)之DBC文件详解_第5张图片

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

1.解析版本

       /***********************************************
          * Name    :AnalysisDBCVersion
          * Author  :WangHu
          * Function:***
          * Version :V1.0.0
          * Data    :2020.4.15
        ***********************************************/
        internal static bool AnalysisDBCVersion(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)
                    {
                        string version = array[1];
                    }
                    return true;
                } 
            }
            return true;
        }

2.解析报文消息

       /***********************************************
          * Name    :AnalysisDBCMessagePattern
          * Author  :WangHu
          * Function:***
          * Version :V1.0.0
          * Data    :2020.4.15
        ***********************************************/
        internal static bool AnalysisDBCMessagePattern(List<Message> messages, string data)
        {
            string pattern = "BO_[ ]+(\\d+)[ ]+(\\w+):(([ ]+)|)(\\d+)[ ]+(\\w+)";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                string[] array = match.Value.Split(new string[] { " ", ":" }, StringSplitOptions.RemoveEmptyEntries);
                Message message = FindCanMsg(messages, (uint)ConvertToInt(array[1]));
                if (message != null)
                {
                    ShowMsg(@"Find line """ + match.Value + @""" message fault", ShowEnum.Fault);
                    return false;
                }
                message = new Message();
                message.ID = (uint)ConvertToInt(array[1]);
                message.Name = ConvertToName(array[2]);
                message.DLC = ConvertToInt(array[3]);
                message.Transmitter = array[4].Replace(" ", "") == "Vector__XXX" ? null : array[4].Replace(" ", "");
                message.CycleTime = message.CycleTimeFast = message.NrOfRepetition = message.DelayTime = -1;
                messages.Add(message);
            }
            return true;
        }

3.解析信号消息

       /***********************************************
          * Name    :AnalysisDBCSignalPattern
          * Author  :WangHu
          * Function:***
          * Version :V1.0.0
          * Data    :2020.4.15
        ***********************************************/
        internal static bool AnalysisDBCSignalPattern(List<Message> messages, string data)
        {
            string pattern = "SG_[ ]+(\\w+)(([ ]+)|)(((m)(\\d+[ ]+))|(M[ ]+))?:(([ ]+)|)(\\d+)(([ ]+)|)\\|(([ ]+)|)(\\d+)(([ ]+)|)@(([ ]+)|)([0|1])(([ ]+)|)([+|-])(([ ]+)|)+\\((([ ]+)|)(-?\\d+(\\.\\d+)?)(([ ]+)|),(([ ]+)|)(-?\\d+(\\.\\d+)?)(([ ]+)|)\\)(([ ]+)|)\\[(([ ]+)|)(-?\\d+(\\.\\d+)?)(([ ]+)|)\\|(([ ]+)|)(-?\\d+(\\.\\d+((E\\+\\d+)|))?)(([ ]+)|)\\](([ ]+)|)\"((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*)\"(([ ]+)|)(\\w+(,[ ]*\\w+)*)";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                Signal signal = new Signal();
                string strPre = data.Substring(0, data.IndexOf(match.Value));
                pattern = "BO_[ ]+(\\d+)[ ]+(\\w+):(([ ]+)|)(\\d+)[ ]+(\\w+)";
                MatchCollection mc = Regex.Matches(strPre, pattern);
                if (mc.Count == 0)
                {
                    ShowMsg(@"Find line """ + match.Value + @""" message fault", ShowEnum.Fault);
                    return false;
                }
                string[] arr = mc[mc.Count - 1].Value.Split(new string[] { " ", ":" }, StringSplitOptions.RemoveEmptyEntries);
                uint id = (uint)ConvertToInt(arr[1]);
                Message message = FindCanMsg(messages, id);
                if (message == null)
                {
                    ShowMsg(@"Find line """ + match.Value + @""" message fault", ShowEnum.Fault);
                    return false;
                }
                string str = match.Value.Replace("+", " +").Replace("-", " -");
                string[] array1 = str.Split(new string[] { @"""" }, StringSplitOptions.None);
                string[] array2 = array1[0].Split(new string[] { " ", ":", ",", "|", "@", "(", ")", "[", "]" }, StringSplitOptions.RemoveEmptyEntries);
                int startbit = ConvertToInt(array2[2]);
                int bitlenth = ConvertToInt(array2[3]);
                int sigbyte = (startbit / 8 + (bitlenth - 1) / 8 + ((startbit % 8 + 1 - ((bitlenth % 8) == 0 ? 8 : (bitlenth % 8))) >= 0 ? 0 : 1));
                int sigbit = (startbit + 1 - bitlenth % 8) % 8;
                int siglsb = sigbyte * 8 + sigbit;
                signal.Name = ConvertToName(array2[1]);
                signal.Startbit = array2[4] == "0" ? siglsb : ConvertToInt(array2[2]);
                signal.Length = ConvertToInt(array2[3]);
                signal.ByteOrder = (ByteOrderEnum)ConvertToInt(array2[4]);
                signal.DataType = array2[5] == "-" ? DataTypeEnum.Signed : DataTypeEnum.Unsigned;
                signal.Factor = ConvertToDouble(array2[6]);
                signal.Offst = ConvertToDouble(array2[7]);
                signal.MinValuePhy = ConvertToDouble(array2[8]);
                signal.MaxValuePhy = ConvertToDouble(array2[9]);
                signal.Unit = array1[1].Replace(" ", "");
                signal.Receivers = array1[2].Replace(" ", "") == "Vector__XXX" ? null : array1[2].Replace(" ", "");
                signal.InitValue = signal.InvalidValue = signal.InvalidValue = signal.InactiveValue = signal.MinValue = signal.MaxValue = -1;
                message.Signals.Add(signal);
            }
            return true;
        }

4.解析注释

       /***********************************************
          * Name    :AnalysisDBCCommentsPattern
          * Author  :WangHu
          * Function:***
          * Version :V1.0.0
          * Data    :2020.4.15
        ***********************************************/
        internal static bool AnalysisDBCCommentsPattern(List<Message> messages, string data)
        {
            string pattern = "CM_[ ]+((((BU_)|(BO_)|(SG_))[ ]+(\\d+)[ ]+(\\w+)(([ ]+)|))|)\"((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*)\"(([ ]+)|);";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                bool result = false;
                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] == "SG_")
                    {
                        uint id = (uint)ConvertToInt(array2[2]);
                        string name = ConvertToName(array2[3]);
                        foreach (var message in messages)
                        {
                            if (id == message.ID)
                            {
                                foreach (var signal in message.Signals)
                                {
                                    if (name == signal.Name)
                                    {
                                        result = true;
                                        signal.Comments = array1[1];
                                        break;
                                    }
                                }
                            }
                        }
                        if (!result)
                        {
                            ShowMsg(@"Find line """ + match.Value + @""" message fault", ShowEnum.Fault);
                            return false;
                        }
                    }
                }
            }
            return true;
        }

5.解析自定义属性描述

       /***********************************************
          * Name    :AnalysisDBCAttributeDefinitionPattern
          * Author  :WangHu
          * Function:***
          * Version :V1.0.0
          * Data    :2020.4.15
        ***********************************************/
        internal static bool AnalysisDBCNatureDefinitionPattern(List<Nature> natures, string data)
        {
            string pattern = "BA_DEF_[ ]+((BU_)|(BO_)|(SG_)|(EV_))?(([ ]+)|)\"(\\w+)\"(([ ]+)|)(((INT)[ ]+([+|-]?\\d+)[ ]+([+|-]?\\d+))|((HEX)[ ]+([+|-]?\\d+)[ ]+([+|-]?\\d+))|((FLOAT)[ ]+([+|-]?\\d+.?\\d*)[ ]+([+|-]?\\d+.?\\d*))|(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);
                foreach (Nature nature in natures)
                {
                    if ((nature.Family == array1[1]) && (nature.Name == array1[2]))
                    {
                        ShowMsg(@"Find line """ + match.Value + @""" message fault", ShowEnum.Fault);
                        return false;
                    }
                }
                Nature nat = new Nature();
                nat.Family = array1[1];
                nat.Name = ConvertToName(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 = ConvertToName(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 = array2[1].Replace(" ", "").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.解析自定义属性默认值

       /***********************************************
          * Name    :AnalysisDBCNatureDefaultPattern
          * Author  :WangHu
          * Function:***
          * Version :V1.0.0
          * Data    :2020.4.15
        ***********************************************/
        internal static bool AnalysisDBCNatureDefaultPattern(List<Message> messages, List<Nature> natures, string data)
        {
            string pattern = "BA_DEF_DEF_[ ]+\"(\\w+)\"(([ ]+)|)\"?(([+|-]?\\d*.?\\d*)|((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*))\"?(([ ]+)|);";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                bool result = false;
                string str = match.Value.Replace(@""" ", @"""").Replace(@" """, @"""").Trim(';');
                string[] array = str.Split(new string[] {@""""}, StringSplitOptions.RemoveEmptyEntries);
                string name = ConvertToName(array[1]);
                string init = 2 >= array.Length ? "" : array[2];
                foreach (Nature nature in natures)
                {
                    if (nature.Name == name)
                    {
                        foreach (Message message in messages)
                        {
                            switch (name)
                            {
                                case "GenMsgCycleTime":
                                    message.CycleTime = ConvertToInt(init);
                                    break;
                                case "GenMsgCycleTimeFast":
                                    message.CycleTimeFast = ConvertToInt(init);
                                    break;
                                case "GenMsgNrOfRepetition":
                                    message.NrOfRepetition = ConvertToInt(init);
                                    break;
                                case "GenMsgDelayTime":
                                    message.DelayTime = ConvertToInt(init);
                                    break;
                                case "NmMessage":
                                    message.Type = init;
                                    break;
                                case "GenMsgSendType":
                                    message.SendType = init;
                                    break;
                                default:
                                    break;
                            }
                            foreach (Signal signal in message.Signals)
                            {
                                switch (name)
                                {
                                    case "GenSigStartValue":
                                        signal.InitValue = ConvertToInt(init);
                                        break;
                                    case "GenSigTimeoutValue":
                                        signal.InvalidValue = ConvertToInt(init);
                                        break;
                                    case "GenSigInactiveValue":
                                        signal.InactiveValue = ConvertToInt(init);
                                        break;
                                    case "GenSigSendType":
                                        signal.SendType = init;
                                        break;
                                    case "GenSigMinValue":
                                        signal.MinValue = ConvertToInt(init);
                                        break;
                                    case "GenSigMaxValue":
                                        signal.MaxValue = ConvertToInt(init);
                                        break;
                                    default:
                                        break;
                                }
                            }
                        }
                        nature.InitValue = init;
                        result = true;
                    }
                }
                if (!result)
                {
                    ShowMsg(@"Find line """ + match.Value + @""" message fault", ShowEnum.Fault);
                    return false;
                }
            }
            return true;
        }

7.解析自定义属性值

       /***********************************************
          * Name    :AnalysisDBCNatureValuePattern
          * Author  :WangHu
          * Function:***
          * Version :V1.0.0
          * Data    :2020.4.15
        ***********************************************/
        internal static bool AnalysisDBCNatureValuePattern(List<Message> messages, List<Nature> natures, 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))
            {
                bool result = false;
                string str = match.Value.Trim(';');
                string[] array = str.Split(new string[] { " ", @"""" }, StringSplitOptions.RemoveEmptyEntries);
                string name = ConvertToName(array[1]);
                uint id = array.Length <= 3 ? 0 : (uint)ConvertToInt(array[3]);
                foreach (Nature nature in natures)
                {
                    if (nature.Name == name)
                    {
                        foreach (Message message in messages)
                        {
                            if (message.ID == id)
                            {
                                if (array[2] == "BO_")
                                {
                                    switch (name)
                                    {
                                        case "GenMsgCycleTime":
                                            message.CycleTime = ConvertToInt(array[4]);
                                            break;
                                        case "GenMsgCycleTimeFast":
                                            message.CycleTimeFast = ConvertToInt(array[4]);
                                            break;
                                        case "GenMsgNrOfRepetition":
                                            message.NrOfRepetition = ConvertToInt(array[4]);
                                            break;
                                        case "GenMsgDelayTime":
                                            message.DelayTime = ConvertToInt(array[4]);
                                            break;
                                        case "NmMessage":
                                            message.Type = nature.data[ConvertToInt(array[4])];
                                            break;
                                        case "GenMsgSendType":
                                            message.SendType = nature.data[ConvertToInt(array[4])];
                                            break;
                                        default:
                                            break;
                                    }
                                    result = true;
                                }
                                else if (array[2] == "SG_")
                                {
                                    foreach (Signal signal in message.Signals)
                                    {
                                        if (signal.Name == array[4])
                                        {
                                            switch (name)
                                            {
                                                case "GenSigStartValue":
                                                    signal.InitValue = ConvertToInt(array[5]);
                                                    break;
                                                case "GenSigTimeoutValue":
                                                    signal.InvalidValue = ConvertToInt(array[5]);
                                                    break;
                                                case "GenSigInactiveValue":
                                                    signal.InactiveValue = ConvertToInt(array[5]);
                                                    break;
                                                case "GenSigSendType":
                                                    signal.SendType = nature.data[ConvertToInt(array[5])];
                                                    break;
                                                case "GenSigMinValue":
                                                    signal.MinValue = ConvertToInt(array[5]);
                                                    break;
                                                case "GenSigMaxValue":
                                                    signal.MaxValue = ConvertToInt(array[5]);
                                                    break;
                                                default:
                                                    break;
                                            }
                                            result = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        result = true;
                    }
                }
                if (!result)
                {
                    ShowMsg(@"Find line """ + match.Value + @""" message fault", ShowEnum.Fault);
                    return false;
                }
            }
            return true;
        }

8.解析数值表

       /***********************************************
          * Name    :AnalysisDBCSignalValueDescriptionPattern
          * Author  :WangHu
          * Function:***
          * Version :V1.0.0
          * Data    :2020.4.15
        ***********************************************/
        internal static bool AnalysisDBCSignalValueDescriptionPattern(List<Message> messages, string data)
        {
            string pattern = "VAL_[ ]+(\\d+)[ ]+(\\w+)[ ]+(((\\d+.?\\d*)(([ ]+)|)\"((([^\"\\s])|([\\s\\u4e00-\\u9fa5]))*)\"[ ]*)*)+(([ ]+)|);";
            foreach (Match match in Regex.Matches(data, pattern))
            {
                bool result = false;
                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 = (uint)ConvertToInt(array2[1]);
                string name = ConvertToName(array2[2]);
                foreach (var message in messages)
                {
                    if (message.ID == id)
                    {
                        foreach (var signal in message.Signals)
                        {
                            if (signal.Name == name)
                            {
                                result = true;
                                signal.ValueDescrptions = "";
                                for (int i = 0; i < (array1.Length)/2; i++)
                                {
                                    if (signal.ValueDescrptions == "")
                                    {
                                        signal.ValueDescrptions += "0x" + ConvertToInt(array2[3]).ToString("X") + ":" + array1[1];
                                    }
                                    else
                                    {
                                        signal.ValueDescrptions += " \r\n0x" + ConvertToInt(array1[2 * i]).ToString("X") + ":" + array1[2 * i + 1];
                                    }
                                }
                                break;
                            }
                        }
                    }
                }
                if (!result)
                {
                    ShowMsg(@"Find line """ + match.Value + @""" message fault", ShowEnum.Fault);
                    return false;
                }
            }
            return true;
        }

五、MatrixCreat工具

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

六、其他

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

七、参考

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

你可能感兴趣的:(MatrixCreat,DBC,dbc,DBC,编辑器,DBC,CAN,dbc,CAN,互转工具,Excel,通讯协议,DBC,EXCEL,转换)