用QT写CAN分析软件3--多线程接收数据

 

今天利用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

用QT写CAN分析软件3--多线程接收数据_第1张图片

下步进行DBC文件的读取与数据解析。

你可能感兴趣的:(QT,can,qt)