今天进行DBC文件的读取,ui界面如下
1、先新建singal类
.h
#ifndef DBCSINGALBASE_H
#define DBCSINGALBASE_H
#include <QObject>
class dbcsingalbase
{
public:
dbcsingalbase();
QString Name; //名称
int Start; //启始位
int Number; //位长度
int End; // 结束位
double Rate; //分辩率
double Offset; //偏移
QString Unit; //单位
QString Note; //备注
double MaxValue; //最小值
double MinValue; //最大值
double Value; //实际值
QString StrValue; //显示值
bool isSigned; //有符号
bool isMoto; //是否摩托罗拉格式
bool isEnum; //
quint8 multiplexer_type; //see 'multiplexer type' above
quint8 val_type; //0:integer, 1:float, 2:double
quint32 multiplexer_value;
void GetMaxMinValue();
};
#endif // DBCSINGALBASE_H
2、新建message类
.h
#ifndef DBCMESSAGEBASE_H
#define DBCMESSAGEBASE_H
#include <QObject>
#include <QList>
#include "dbcsingalbase.h"
#include "candatabase.h"
class DbcMessageBase
{
public:
DbcMessageBase();
QList<dbcsingalbase> SingalList;
QString Name;
bool IsSend;
quint32 SendCycle;
QString SendNodeName;
CanDataBase Can;
bool isMoto;
void SetMoto(bool moto);
};
#endif // DBCMESSAGEBASE_H
3、新建个处理DBC的类
.h
#ifndef DBCANALYSISMODEL_H
#define DBCANALYSISMODEL_H
#include <QObject>
#include <QList>
#include "dbcmessagebase.h"
#include "IDBCManager.h"
class DbcAnalysisModel : public QObject
{
Q_OBJECT
private:
DBCHandle m_hDBC;
public:
explicit DbcAnalysisModel(QObject *parent = 0);
~DbcAnalysisModel();
QString Name;
quint32 BaudRate;
qint16 Address;
QList<DbcMessageBase> MsgList;
bool GetList(QString filename);
signals:
public slots:
};
#endif // DBCANALYSISMODEL_H
4、编写DBC读取函数
bool DbcAnalysisModel::GetList(QString filename)
{
QFile file(filename);
file.open(QIODevice::ReadOnly|QIODevice::Text);
MsgList.clear();
while(!file.atEnd())
{
QByteArray line = file.readLine();
QString str1 = QTextCodec::codecForName("GBK")->toUnicode(line);
// qDebug()<< str1;
if (str1.mid(0, 4) == "BO_ ")
{
QStringList strs1 = str1.trimmed().split(" ");
DbcMessageBase fdb;
fdb.Can.Id = strs1[1].toULong() & 0x1FFFFFFF;
if (fdb.Can.Id > 0x7FF)
fdb.Can.IsExtendFrame = true;
fdb.Name = strs1[2].mid(0, strs1[2].length() - 1);
//fdb.SendCycle = 0;
if (strs1[strs1.length() - 1] != "Vector__XXX")
{
fdb.SendNodeName = strs1[strs1.length() - 1];
}
this->MsgList.append(fdb);
}
else if (str1.mid(0, 5) == " SG_ ")
{
dbcsingalbase dtb ;
int index1 = str1.indexOf("SG_");
int index2 = str1.indexOf(":");
QString name = str1.mid(index1 + 3, index2 - index1 - 3).trimmed();
dtb.Name = name;
QStringList strs1 = str1.mid(index2 + 1, str1.length() - index2 - 1).split(" ");
int i1 = strs1[1].indexOf('|');
int i2 = strs1[1].indexOf('@');
int start = (strs1[1].mid(0, i1).toInt());
int number = (strs1[1].mid(i1 + 1, i2 - i1 - 1).toInt());
int format = (strs1[1].mid(i2 + 1, 1).toInt());
QString vtype = strs1[1].mid(i2 + 2, 1);
if (vtype == "-")
dtb.isSigned = true;
dtb.Number = number;
if (format == 1)
{
dtb.Start = start;
dtb.isMoto = false;
}
else
{
int offset = 0;
int end = 0;
for (int j = 0; j < number; j++)
{
end = start - j;
if ((end % 8 == 0) && (j != number - 1))
offset += 16;
end += offset;
}
dtb.Start = end;
dtb.isMoto = true;
}
dtb.GetEnd();
MsgList.back().SetMoto( dtb.isMoto);
QStringList strs2 = strs1[2].replace("(", "").replace(")", "").split(",");
dtb.Rate = strs2[0].toDouble();
dtb.Offset = strs2[1].toDouble();
QStringList strs3 = strs1[3].replace("[", "").replace("]", "").split("|");
dtb.MinValue = (strs3[0].toDouble());
dtb.MaxValue = (strs3[1].toDouble());
if (dtb.MinValue == 0 && dtb.MinValue == dtb.MaxValue)
{
dtb.GetMaxMinValue();
}
dtb.Unit = strs1[4].replace("\"", "");
MsgList.back().SingalList.append(dtb);
}
}
}
5、打开DBC按钮处理
void MainWindow::on_btnOpenDbc_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
"./",
tr("DBC文件 (*.dbc)"));
ui->lbFilename->setText( fileName);
if(this->Dbc->GetList(fileName))
{
ui->tbMsg->setColumnCount(5);
ui->tbMsg->setRowCount(Dbc->MsgList.size());
for(int i = 0;i<Dbc->MsgList.size();i++)
{
DbcMessageBase mb = Dbc->MsgList.at(i);
QTableWidgetItem *tbi1 = new QTableWidgetItem(mb.Name);
ui->tbMsg->setItem(i,0,tbi1);
QTableWidgetItem *tbi2 = new QTableWidgetItem(QString::number(mb.Can.Id,16));
ui->tbMsg->setItem(i,1,tbi2);
QTableWidgetItem *tbi3 = new QTableWidgetItem(mb.isMoto?"Motorola":"Intel");
ui->tbMsg->setItem(i,2,tbi3);
QTableWidgetItem *tbi5 = new QTableWidgetItem(QString::number(mb.SendCycle));
ui->tbMsg->setItem(i,3,tbi5);
QTableWidgetItem *tbi6 = new QTableWidgetItem(mb.SendNodeName);
ui->tbMsg->setItem(i,4,tbi6);
}
}
}
6、点南message表格显示对应的singal
void MainWindow::on_tbMsg_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn)
{
static int row = -1;
if(currentRow != row)
{
row = currentRow;
DbcMessageBase mb = Dbc->MsgList.at(row);
ui->tbSingal->setColumnCount(10);
ui->tbSingal->setRowCount(mb.SingalList.size());
for(int i=0;i<mb.SingalList.size();i++)
{
dbcsingalbase sb = mb.SingalList.at(i);
QTableWidgetItem *tbi1 = new QTableWidgetItem(sb.Name);
ui->tbSingal->setItem(i,0,tbi1);
QTableWidgetItem *tbi2 = new QTableWidgetItem(sb.Note);
ui->tbSingal->setItem(i,1,tbi2);
QTableWidgetItem *tbi3 = new QTableWidgetItem(QString::number(sb.Start));
ui->tbSingal->setItem(i,2,tbi3);
QTableWidgetItem *tbi4 = new QTableWidgetItem(QString::number(sb.Number));
ui->tbSingal->setItem(i,3,tbi4);
QTableWidgetItem *tbi5 = new QTableWidgetItem(QString::number(sb.End));
ui->tbSingal->setItem(i,4,tbi5);
QTableWidgetItem *tbi6 = new QTableWidgetItem(sb.isEnum?"枚举":"整形");
ui->tbSingal->setItem(i,5,tbi6);
QTableWidgetItem *tbi7 = new QTableWidgetItem(QString::number(sb.Rate));
ui->tbSingal->setItem(i,6,tbi7);
QTableWidgetItem *tbi8 = new QTableWidgetItem(QString::number( sb.Offset));
ui->tbSingal->setItem(i,7,tbi8);
QTableWidgetItem *tbi9 = new QTableWidgetItem(sb.Unit);
ui->tbSingal->setItem(i,8,tbi9);
QTableWidgetItem *tbi10 = new QTableWidgetItem(QString::number(sb.Value));
ui->tbSingal->setItem(i,9,tbi10);
}
}
}
读取DBC文件完成