QT PEAK-CAN通信编程

本文档展示了如何使用QT库的QCanBus模块与PEAK-CAN USB设备进行交互,包括连接设备、设置波特率、接收和处理CAN总线帧,并处理设备错误。代码中包含了设备连接、帧读取、错误处理等关键步骤,适用于嵌入式系统或车辆网络通信的开发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

工程添加模块:

QT += serialbus

引用头文件:

#include <QCanBus>
#include <QCanBusFrame>
#include <QCanBusDevice>
#include <QCanBusDeviceInfo>

private slots:
    // TODO:CanBus Signals
    void processErrors(QCanBusDevice::CanBusError) const;
    void processReceivedFrames();
    //void processWritten(qint64 framesCount) const;
    //void processStateChanged(QCanBusDevice::CanBusDeviceState state) const;
    
private:
bool mIsOpened;		// PEAK-CAN 打开状态
bool mIsConnected;  // PEAK-CAN 连接状态
QCanBusDevice *mCanDevice = nullptr;
QList<QCanBusDeviceInfo> mCanDeviceInfo;

代码实现:



void MainWindow::msleep(uint msec)
{
    QTime sleepTime = QTime::currentTime().addMSecs(msec);
    while(QTime::currentTime() < sleepTime) {
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }
}

void MainWindow::on_actionConnect_triggered()
{
    qDebug("Connect triggered");
    QString errString;

    if (QCanBus::instance()->plugins().contains(QStringLiteral("peakcan"))) {
        qDebug("peakcan plugin available");
    } else {
        qDebug("peakcan plugin not available");
    }

    mCanDeviceInfo = QCanBus::instance()->availableDevices("peakcan");
    if (!mCanDeviceInfo.isEmpty()) {
        qDebug("%s", mCanDeviceInfo.begin()->name().toStdString().c_str());
    } else {
        qDebug("Can not find available peakcan device");
    }



    mCanDevice = QCanBus::instance()->createDevice(QStringLiteral("peakcan"), QStringLiteral("usb0"), &errString);
    if (!mCanDevice) {
        qDebug("ErrString:%s", errString.toStdString().c_str());
    } else {

        connect(mCanDevice, &QCanBusDevice::errorOccurred, this, &MainWindow::processErrors);
        connect(mCanDevice, &QCanBusDevice::framesReceived, this , &MainWindow::processReceivedFrames);

        //connect(m_canDevice, &QCanBusDevice::framesReceived, this, &MainWindow::processReceivedFrames);
        //connect(m_canDevice, &QCanBusDevice::framesWritten, this, &MainWindow::processFramesWritten);


        mCanDevice->setConfigurationParameter(QCanBusDevice::BitRateKey, QVariant(250000)); // 波特率
        //mCanDevice->setConfigurationParameter(QCanBusDevice::ErrorFilterKey, QVariant(0x1ffffff));

        mIsConnected = mCanDevice->connectDevice();
        if (mIsConnected) {
            qDebug("CanDevice connect ok.");
        } else {
            qDebug("CanDevcie connect error.");
        }

    }
}

void MainWindow::processReceivedFrames()
{
    if (!mCanDevice) {
        return;
    }

    while(mCanDevice->framesAvailable()) {
        const QCanBusFrame frame = mCanDevice->readFrame();
        QString view;

        if (frame.frameType() == QCanBusFrame::ErrorFrame) {
            view = mCanDevice->interpretErrorFrame(frame);
        } else {
            view = frame.toString();
        }

        const QString time = QString::fromLatin1("%1.%2  ")
                                 .arg(frame.timeStamp().seconds(), 10, 10, QLatin1Char(' '))
                                 .arg(frame.timeStamp().microSeconds()/100, 4, 10, QLatin1Char('0'));

        QString flags = QLatin1String(" --- ");
        if (frame.hasBitrateSwitch()) {
            flags[1] = QLatin1Char('B');
        }
        if (frame.hasErrorStateIndicator()) {
            flags[2] = QLatin1Char('E');
        }
        if (frame.hasLocalEcho()) {
            flags[3] = QLatin1Char('L');
        }

        QByteArray payload = frame.payload();
        //qDebug("0x%x  0x%x", frame.frameId(), (char)payload[0]);
        qDebug("%s  %s  %s",time.toStdString().c_str(), flags.toStdString().c_str(), view.toStdString().c_str());

    }

}
// 
void MainWindow::processErrors(QCanBusDevice::CanBusError error) const
{
    switch (error) {
    case QCanBusDevice::ReadError:
    case QCanBusDevice::WriteError:
    case QCanBusDevice::ConnectionError:
    case QCanBusDevice::ConfigurationError:
    case QCanBusDevice::UnknownError:
        qDebug("Error:%s", mCanDevice->errorString().toStdString().c_str());
        //m_status->setText(m_canDevice->errorString());
        break;
    default:
        break;
    }
}

// 发送报文
void MainWindow::sendCaptureDeviceMsg(int canId)
{
    //qDebug("canId:%d", canId);
    QCanBusFrame frame;
    uint StdId, ExtId;
    QByteArray payload;
    payload.resize(8);

    ExtId = 0x18EF80C8|(canId<<8);
    payload[0]= 0x70;
    payload[1]= 0xFF;
    payload[2]= 0xFF;
    payload[3]= 0xFF;
    payload[4]= 0xFF;
    payload[5]= 0xFF;
    payload[6]= 0xFF;
    payload[7]= 0xFF;

    frame.setFrameType(QCanBusFrame::DataFrame);
    frame.setExtendedFrameFormat(true); //
    frame.setTimeStamp(QDateTime::currentMSecsSinceEpoch());

    frame.setFrameId(ExtId);
    frame.setPayload(payload);

    if (mIsConnected) {
        mCanDevice->writeFrame(frame);
        msleep(25);
    }

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SongYuLong的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值