基于C#的整车CAN通讯DBC文件编程

最近需要实现基于Excel的发动机台架自动化测量系统,需要用到dbc通讯文件,特著此文,给需要的人
程序运行效果图

首先要定义存放DBC数据的结构体:首先是 信号类和报文类 定义。
此定义需遵循变量从属关系(一个DBC文件内有多个BO_,一个BO_下有多个SG_)
可以参考此文章,https://www.vecll.com/news/10.html,作者提供的思路比较清晰,本文所述代码基于此思路进行详细开发

//信号类
    public class Typedef_SG
    {
        public string Name;
        public int StartBit;
        public int Length;
        public int CodeType; //0=motorola,1=intel
        public string DataType; //-表示有符号型
        public double Factor;
        public double Offset;
        public double MinValue;
        public double MaxValue;
        public string Unit;
    }
    //报文类
    public class Typedef_BO
    {
        public uint ID;
        public string Name;
        public uint Length;
        public List<Typedef_SG> SG = new List<Typedef_SG>();
    }

全局变量声明与定义

	private bool IsEdited = false;
	public static Dictionary<string, string> dictDBC = new Dictionary<string, string>(); //根据信号名称反查,方便后续使用<SG.Name,BO.ID+BO[]+SG[]>
	List<Typedef_BO> BO_List = new List<Typedef_BO>(); //将报文类构建成一个报文列表
	Typedef_BO BO;

接下来定义了打开DBC文件的函数,

private void LoadDBCFile()
        {
            dictDBC.Clear();
            BO_List.Clear();
            DialogResult dialogResult = OpenDBCFile.ShowDialog();
            if (dialogResult == DialogResult.OK)
            {
                string DBCFilePath = OpenDBCFile.FileName;
                BottomLabel1.Text = DBCFilePath;
                Stopwatch sw = new Stopwatch();
                sw.Restart();                                                                //按行读取
                using (var reader = new StreamReader(DBCFilePath))
                {
                    int i = 0;
                    int SG_index = 0;
                    int BO_index = 0;                                                        //
                    string str_Line = "";
                    while ((str_Line = reader.ReadLine()) != null)                           //带数据行
                    {
                        i++;
                        Regex regexSG = new Regex(@"^ SG_ [.]*");                            //SG
                        Regex regexBO = new Regex(@"^BO_ \d+");                              //BO
                        try
                        {
                            if (regexSG.IsMatch(str_Line))                                       //SG length=9
                            {
                                //MessageBox.Show("in SG_ ,line="+i);
                                string[] SG_Line = str_Line.Split(' ');
                                if (SG_Line.Length != 9) throw new Exception("数据格式错误,Line=" + i);
                                Typedef_SG SG = new Typedef_SG();
                                SG.Name = SG_Line[2];                                            //Name
                                string[] SG4 = SG_Line[4].Split(new char[2] { '|', '@' });       //StartBit,Length,CodeType,DataType
                                SG.StartBit = Convert.ToInt16(SG4[0]);
                                SG.Length = Convert.ToInt16(SG4[1]);
                                SG.CodeType = Convert.ToInt16(SG4[2].Substring(0, 1));
                                SG.DataType = SG4[2].Substring(1, 1);
                                string[] SG5 = SG_Line[5].Split(new char[3] { '(', ',', ')' }); //Factor,Offset
                                SG.Factor = Convert.ToDouble(SG5[1]);
                                SG.Offset = Convert.ToDouble(SG5[2]);
                                string[] SG6 = SG_Line[6].Split(new char[3] { '[', '|', ']' }); //MinValue,MaxValue,Unit
                                SG.MinValue = Convert.ToDouble(SG6[1]);
                                SG.MaxValue = Convert.ToDouble(SG6[2]);
                                SG.Unit = SG_Line[7];                                           //Unit
                                BO.SG.Add(SG);                                                  //SG to List BO.SG
                                dictDBC.Add(SG.Name, BO.ID+ "," + (BO_index - 1) + "," + SG_index);                     //添加元素key,value同步加入字典,实现根据SG.Name反查出(BO.ID, BO[BO_index], SG[SG_index])
                                SG_index++;
                            }
                            if (regexBO.IsMatch(str_Line))                                      //BO length=5
                            {
                                BO = new Typedef_BO();                                          //BO实例化
                                SG_index = 0;
                                string[] BO_Line = str_Line.Split(' ');
                                if (BO_Line.Length != 5) throw new Exception("数据格式错误,Line=" + i);
                                BO.ID = Convert.ToUInt16(BO_Line[1]);
                                BO.Name = BO_Line[2];
                                BO.Length = Convert.ToUInt16(BO_Line[3]);
                                BO_List.Add(BO);
                                BO_index++;
                                //MessageBox.Show("in BO_ ,line=" + i+ " ,name=" + BO.Name);
                            }
                        }
                        catch (Exception ex)
                        { MessageBox.Show(ex.Message); }
                    }
                }
                sw.Stop();
            }
        }

根据信号名称查询dbc文件对应行BO_及SG_信息 函数定义如下

public static string dictDBCSearch(String SGname)
        {
            string Result = "";
            if (!dictDBC.ContainsKey(SGname))               //假如不存在元素
                Result = SGname + ",不存在";
            else
                Result = SGname + "的 BO[BO_index] ,SG[SG_index] = " + dictDBC[SGname];
            return Result;
        }

源码链接:https://download.csdn.net/download/qqwertccc/13764355
pudn已传

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值