最近需要实现基于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已传