今天利用QT多线程来接收CAN的数据
1、首先新建一个candatabase的类来表示CAN到 的每一个帧数据
#ifndef CANDATABASE_H
#define CANDATABASE_H
#include
#include
class CanDataBase : public QObject
{
Q_OBJECT
public:
explicit CanDataBase(QObject *parent = 0);
QDateTime Time;
uint Id;
unsigned char *Data;
QString StrData;
int Len;
bool IsSend;
bool IsExtendFrame;
bool IsRemoteFrame;
void SetTime(QDateTime time);
void SetIsSend(bool send);
void SetData(uint id,unsigned char * data,int len,bool extend = false,bool remote = false);
void GetStringData();
signals:
public slots:
};
#endif // CANDATABASE_H
#include "candatabase.h"
CanDataBase::CanDataBase(QObject *parent) : QObject(parent)
{
IsSend = false;
IsExtendFrame = false;
IsRemoteFrame = false;
}
void CanDataBase::SetTime(QDateTime time)
{
this->Time = time;
}
void CanDataBase::SetIsSend(bool send)
{
this->IsSend = send;
}
void CanDataBase::SetData(uint id,unsigned char * data,int len,bool extend,bool remote)
{
this->Id = id;
this->Data =data;
this->IsExtendFrame = extend;
this->IsRemoteFrame = remote;
this->Len = len;
}
void CanDataBase::GetStringData()
{
QString str ;
for(int i=0;iLen;i++)
{
str += QString("%1 ").arg( this->Data[i],2,16,QLatin1Char('0'));
}
this->StrData = str;
// return str;
}
2、再新建个类,cansetmodel来处理收收的数据
void CanSetModel::DataReceive()
{
ZCAN_Receive_Data can_data[100];
ZCAN_ReceiveFD_Data canfd_data[100];
UINT len;
while(isStart)
{
if (len = ZCAN_GetReceiveNum(chHandle, TYPE_CAN))
{
len = ZCAN_Receive(chHandle, can_data, 100, 50);
AddData(can_data, len);
}
if (len = ZCAN_GetReceiveNum(chHandle, TYPE_CANFD))
{
len = ZCAN_ReceiveFD(chHandle, canfd_data, 100, 50);
AddData(canfd_data, len);
}
}
}
void CanSetModel::AddData(const ZCAN_Receive_Data *data, UINT len)
{
QString item;
for (UINT i = 0; i < len; ++i)
{
const ZCAN_Receive_Data& can = data[i];
const canid_t& id = can.frame.can_id;
CanDataBase *cdb = new CanDataBase();
cdb->SetData(GET_ID(id),(unsigned char*)can.frame.data,can.frame.can_dlc,IS_EFF(id),IS_RTR(id));
AddData(cdb);
}
}
void CanSetModel::AddData(const ZCAN_ReceiveFD_Data *data, UINT len)
{
QString item;
for (UINT i = 0; i < len; ++i)
{
const ZCAN_ReceiveFD_Data& canfd = data[i];
const canid_t& id = canfd.frame.can_id;
CanDataBase *cdb = new CanDataBase();
cdb->SetData(GET_ID(id),(unsigned char*)canfd.frame.data,canfd.frame.len,IS_EFF(id),IS_RTR(id));
AddData(cdb);
}
}
void CanSetModel::AddData(CanDataBase *cdb)
{
cdb->SetTime(QDateTime::currentDateTime());
cdb->GetStringData();
// qDebug()<<"ID:" <Id<<"数据:"<StrData;
emit this->DataUpdata(cdb);
}
3、在主程序.h文件中定义线程变量
CanSetModel *CanSet;
QThread *myThread;
signals:
void StartDataReceive();
4、在主程序,c文件初始化函数的加入
CanSet = new CanSetModel;
myThread = new QThread(this);
CanSet->moveToThread(myThread);
connect(this,&MainWindow::StartDataReceive,CanSet,&CanSetModel::DataReceive);
connect(this,&MainWindow::destroyed,this,&MainWindow::CloseWin);
connect(CanSet,&CanSetModel::DataUpdata,this,&MainWindow::UpdataReceive);
5、在can的连接函数的加入启动线程的启动接收
ui->btnConnect->setText("断开连接");
myThread->start();
emit this->StartDataReceive();
6、处理接收到的数据在界面上显示出来
void MainWindow::UpdataReceive(CanDataBase *cdb)
{
QString str;
str += cdb->IsSend?"发送 ":"接收 ";
// str += QString::number(cdb->sTime / 1000000.0,'f',6);
str += cdb->Time.toString("HH:mm:ss.zzz");
str += " ID:0x";
str += QString::number(cdb->Id,16);
str += cdb->IsExtendFrame?" 扩展帧 ":" 标准帧 ";
str += " 数据:";
str += cdb->StrData;
QListWidgetItem *item = new QListWidgetItem(str);
if(cdb->IsSend)
item->setForeground(Qt::red);
ui->lwDataDisplay->addItem(item);
ui->lwDataDisplay->scrollToBottom();
if( ui->lwDataDisplay->count() >= 50)
ui->lwDataDisplay->removeItemWidget( ui->lwDataDisplay->takeItem(0));
}
现在就可以完整的接收与发送CAN数据了
使用的是周立功USBCANFD_200U
下步进行DBC文件的读取与数据解析。