qt串口类实现

/*********************************************************************
 * 内容摘要: 串口类
 * 其它说明: 无
 * 当前版本: V1.0
 * 作    者: 
 * 完成日期: 2022/12/29
 **********************************************************************/
#ifndef SERIALPORTDATAPARSE_H
#define SERIALPORTDATAPARSE_H

#include <QObject>
#include <QSerialPort>
#include <QVariantMap>
#include <QTimer>
#include <QMutex>
#include <thread>
#include <QSharedPointer>

typedef struct SerialFrameStru
{
    uint16_t    frameHead;
    uint16_t    frameLen;
    uint8_t     slaveAddr;
    uint16_t    frameNo;
    uint8_t     frameCmd;
    QByteArray  realData;
    uint16_t    crc16;

} SerialFrame;

Q_DECLARE_METATYPE(SerialFrame)

class SerialPortDataParse : public QObject
{
    Q_OBJECT
public:
    explicit SerialPortDataParse(QObject *parent = nullptr);

    ~SerialPortDataParse();

    static SerialPortDataParse *getInstance();

    void writeData(const QVariantMap &vMap);

    // 主板OTA权限下发
    void otaPermissionSet(uint16_t &data);

    // 主板OTA消息通知
    void startSlaveUpgrade(QVariantMap &vMap);

    // 主板发送数据
    void sendUpgradeData(uint16_t frameNo, QByteArray &byteArray);

    // 主板请求升级结果
    void getUpgradeResult();

    void sendData();

signals:
    void sig_startTimer();
    void sig_write(const SerialFrame &);
    void sig_parseCmd0x01Frame(QVariantMap &vMap);
    void sig_parseCmd0x02Frame(QVariantMap &vMap);
    void sig_parseCmd0x03Frame(QVariantMap &vMap);
    void sig_parseCmd0xA0Frame(QVariantMap &vMap);
    void sig_parseCmd0xA3Frame(QVariantMap &vMap);
    void sig_parseCmd0xA4Frame(QVariantMap &vMap);
    void sig_parseCmd0xA5Frame(QVariantMap &vMap);
public slots:
    void readData();

private:
    void parseSerialData(QByteArray &data);
    void retry();
    void write(const SerialFrame &);
    bool isReplyFrame(SerialFrame &);
    // 接收采集器主动上报传感器数据01
    void parseCmd0x01Frame(SerialFrame &frame);
    // 回复采集器
    void replyCmd0x01Frame(uint8_t);
    // 接收采集器发送软件版本号
    void parseCmd0x02Frame(SerialFrame &frame);
    // 回复采集器
    void replyCmd0x02Frame();
    // 接收采集器上报工作状态
    void parseCmd0x03Frame(SerialFrame &frame);
    // 回复采集器
    void replyCmd0x03Frame();
    // 采集器权限管理回复
    void parseCmd0xA0Frame(SerialFrame &frame);
    // 接收采集器OTA回复
    void parseCmd0xA3Frame(SerialFrame &frame);
    // 接收采集器OTA发送数据回复
    void parseCmd0xA4Frame(SerialFrame &frame);
    // 主板请求升级结果回复
    void parseCmd0xA5Frame(SerialFrame &frame);
private:
    QMutex m_mutex;
    QMutex m_retryMutex;
    QList<SerialFrame> m_serialData;
    QList<SerialFrame> m_retryList;
    QSharedPointer<QSerialPort> m_serialPort{nullptr};
    bool retryFlag{false};
    SerialFrame m_currSendFrame;              // 当前发送Map
    QTimer m_timer;
    QSharedPointer<std::thread> m_sendThread{nullptr};
};

#endif // SERIALPORTDATAPARSE_H
/*********************************************************************
 * 内容摘要: 串口类
 * 其它说明: 无
 * 当前版本: V1.0
 * 作    者: 
 * 完成日期: 2022/12/29
 **********************************************************************/
#include "serialportdataparse.h"
#include <QSerialPortInfo>
#include <QtEndian>
#include <QThread>
#include <QDebug>

static bool flag = true;

static uint16_t crc16Check(uint8_t *buf, uint16_t len)
{
    uint8_t crc16L = 0xff;
    uint8_t crc16H = 0xff;
    uint8_t saveL, saveH;
    for (uint16_t i = 0; i < len; ++i) {
        crc16L = crc16L ^ (*(buf+i));
        for (uint16_t j = 0; j < 8; ++j) {
            saveH = crc16H;
            saveL = crc16L;
            crc16H >>= 1;
            crc16L >>= 1;
            if ((saveH & 1) == 1) {
                crc16L |= 0x80;
            }

            if ((saveL & 1) == 1) {
                crc16H ^= 0xa0;
                crc16L ^= 1;
            }
        }
    }

    return (crc16H << 8) | crc16L;
}

/**********************************************************************
 * 功能描述: 默认构造函数
 * 输入参数: parent:父类
 * 输出参数: 无
 * 返 回 值: 无
 * 其它说明: 无
 ***********************************************************************/
SerialPortDataParse::SerialPortDataParse(QObject *parent) : QObject(parent)
{
    m_serialData.clear();
    m_retryList.clear();
    m_timer.setInterval(1000);

    connect(&m_timer, &QTimer::timeout, this, &SerialPortDataParse::retry);
    // 定时器不能从别的线程中开启
    connect(this, &SerialPortDataParse::sig_startTimer, this, [&](){m_timer.start();});

    m_serialPort = QSharedPointer<QSerialPort>(new QSerialPort);
    if (m_serialPort.isNull()) {
        return;
    }

    QList<QSerialPortInfo> serialPortList = QSerialPortInfo::availablePorts();
    foreach (QSerialPortInfo info, serialPortList) {
        if (info.portName().isEmpty()) {
            continue;
        }

        m_serialPort->setPort(info);
        m_serialPort->setBaudRate(QSerialPort::QSerialPort::Baud115200);
        m_serialPort->setDataBits(QSerialPort::Data8);
        m_serialPort->setFlowControl(QSerialPort::NoFlowControl);
        m_serialPort->setParity(QSerialPort::NoParity);
        m_serialPort->setStopBits(QSerialPort::OneStop);
        if (m_serialPort->open(QIODevice::ReadWrite)) {
            qRegisterMetaType<SerialFrame>("SerialFrame");
            connect(m_serialPort.data(), &QIODevice::readyRead, this, &SerialPortDataParse::readData);
            connect(this, &SerialPortDataParse::sig_write, this, &SerialPortDataParse::write);
            m_sendThread = QSharedPointer<std::thread>(new std::thread(&SerialPortDataParse::sendData, this));
            break;
        }
    }
}

/**********************************************************************
 * 功能描述: 析构函数
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 无
 * 其它说明: 无
 ***********************************************************************/
SerialPortDataParse::~SerialPortDataParse()
{
    flag = false;
    if (!m_serialPort.isNull() && m_serialPort->isOpen()) {
        m_serialPort->close();
    }

    if (!m_sendThread.isNull() && m_sendThread->joinable()) {
        m_sendThread->join();
    }
}

/**********************************************************************
 * 功能描述: 获取单例
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 无
 * 其它说明: 无
 ***********************************************************************/
SerialPortDataParse *SerialPortDataParse::getInstance()
{
    static SerialPortDataParse serialPortDataParse;
    return &serialPortDataParse;
}

/**********************************************************************
 * 功能描述: 读取串口数据
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 无
 * 其它说明: 无
 ***********************************************************************/
void SerialPortDataParse::readData()
{
    QByteArray data = m_serialPort->readAll();
    parseSerialData(data);
}

void SerialPortDataParse::parseSerialData(QByteArray &data)
{
    qDebug()<<"______recv__________"<<data.toHex(' ');
    int size = data.size();
    if (size < 10 || size > 1024) {
        QString err = QString("Recv Serial Data Error! Size: %1").arg(size);
        qDebug()<<__func__<<__LINE__<<err;
        return;
    }

    SerialFrame frame;
    frame.frameHead = (data[0] << 8) + data[1];
    frame.frameLen = (data[2] << 8) + data[3];
    frame.slaveAddr = data[4];
    frame.frameNo = (data[5] << 8) + data[6];
    frame.frameCmd = data[7];
    frame.realData = data.mid(8, size-10);
    frame.crc16 = (data[size-2] << 8) + data[size-1];
    uint16_t crc16 = crc16Check((uint8_t *)data.data(), size-2);
    if (frame.frameHead != 0xAA55 || crc16 != frame.crc16) {
        QString err = QString("Recv Serial Data Crc16 Check Failed! FrameHead: %x%1, Crc16: 0x%2 != 0x%3")
                .arg(QString::number(frame.frameHead, 16).toUpper())
                .arg(QString::number(crc16, 16).toUpper())
                .arg(QString::number(frame.crc16, 16).toUpper());
        qDebug()<<__func__<<__LINE__<<err;
        return;
    }

    // 收到回复
    if (frame.frameCmd == m_currSendFrame.frameCmd) {
        retryFlag = false;
        m_timer.stop();
    }

    if (frame.frameCmd == 0x01) {   // 采集器主动上报传感器数据
        if (frame.realData.size() < 26) {
            QString err = QString("Recv Serial Cmd: 0x%1, DataLen: %2 Error")
                    .arg(QString::number(frame.frameCmd, 16).toUpper()).arg(frame.realData.size());
            qDebug()<<__func__<<__LINE__<<err;
            return;
        }

        parseCmd0x01Frame(frame);
    } else if (frame.frameCmd == 0x02) {    // 采集器发送软件版本号
        if (frame.realData.size() < 4) {
            QString err = QString("Recv Serial Cmd: 0x%1, DataLen: %2 Error")
                    .arg(QString::number(frame.frameCmd, 16).toUpper()).arg(frame.realData.size());
            qDebug()<<__func__<<__LINE__<<err;
            return;
        }

        parseCmd0x02Frame(frame);
    } else if (frame.frameCmd == 0xA3) {    // 采集器OTA回复
        if (frame.realData.size() < 1) {
            QString err = QString("Recv Serial Cmd: 0x%1, DataLen: %2 Error")
                    .arg(QString::number(frame.frameCmd, 16).toUpper()).arg(frame.realData.size());
            qDebug()<<__func__<<__LINE__<<err;
            return;
        }

        parseCmd0xA3Frame(frame);
    } else if (frame.frameCmd == 0xA4) {    // 采集器OTA发送数据回复
        if (frame.realData.size() < 1) {
            QString err = QString("Recv Serial Cmd: 0x%1, DataLen: %2 Error")
                    .arg(QString::number(frame.frameCmd, 16).toUpper()).arg(frame.realData.size());
            qDebug()<<__func__<<__LINE__<<err;
            return;
        }

        parseCmd0xA4Frame(frame);
    } else if (frame.frameCmd == 0xA5) {    // 采集器OTA升级结果回复
        if (frame.realData.size() < 1) {
            QString err = QString("Recv Serial Cmd: 0x%1, DataLen: %2 Error")
                    .arg(QString::number(frame.frameCmd, 16).toUpper()).arg(frame.realData.size());
            qDebug()<<__func__<<__LINE__<<err;
            return;
        }

        parseCmd0xA5Frame(frame);
    } else if (frame.frameCmd == 0xA0) { // 采集器OTA权限回复
        if (frame.realData.size() < 2) {
            QString err = QString("Recv Serial Cmd: 0x%1, DataLen: %2 Error")
                    .arg(QString::number(frame.frameCmd, 16).toUpper()).arg(frame.realData.size());
            qDebug()<<__func__<<__LINE__<<err;
            return;
        }

        parseCmd0xA0Frame(frame);
    } else if (frame.frameCmd == 0x03) { // 采集器上报工作状态
        if (frame.realData.size() < 2) {
            QString err = QString("Recv Serial Cmd: 0x%1, DataLen: %2 Error")
                    .arg(QString::number(frame.frameCmd, 16).toUpper()).arg(frame.realData.size());
            qDebug()<<__func__<<__LINE__<<err;
            return;
        }

        parseCmd0x03Frame(frame);
    }
}

void SerialPortDataParse::retry()
{
    static int cnt = 0;
    if (cnt < 2) {
        cnt++;
        QMutexLocker locker(&m_retryMutex);
        m_retryList.append(m_currSendFrame);
    } else {
        cnt = 0;
        retryFlag = false;
        m_timer.stop();
    }
}

void SerialPortDataParse::write(const SerialFrame &frame)
{
    QByteArray byteArray;
    char arr[4];
    // 帧头
    uint8_t len = sizeof(frame.frameHead);
    qToBigEndian(frame.frameHead, arr);
    byteArray.append(arr, len);
    // 帧长度
    len = sizeof(frame.frameLen);
    qToBigEndian(frame.frameLen, arr);
    byteArray.append(arr, len);
    // 从机地址
    byteArray.append(frame.slaveAddr);
    // 帧序号
    len = sizeof(frame.frameNo);
    qToBigEndian(frame.frameNo, arr);
    byteArray.append(arr, len);
    // 帧命令
    byteArray.append(frame.frameCmd);
    // 数据
    byteArray.append(frame.realData);
    // crc16
    uint16_t crc16 = crc16Check((uint8_t *)byteArray.data(), byteArray.size());
    len = sizeof(crc16);
    qToBigEndian(crc16, arr);
    byteArray.append(arr, len);

    m_serialPort->write(byteArray);
    qDebug()<<"_____write________"<<byteArray.toHex(' ');
}

bool SerialPortDataParse::isReplyFrame(SerialFrame &frame)
{
    if (frame.frameCmd == 0x01 || frame.frameCmd == 0x02) {
        return true;
    }

    return false;
}

void SerialPortDataParse::parseCmd0x01Frame(SerialFrame &frame)
{
    QVariantMap vMap;
    int16_t s16Ntc1 = (frame.realData[0] << 8) + frame.realData[1];
    qreal fNtc1 = s16Ntc1*0.1;
    vMap.insert("fNtc1", QString::number(fNtc1, 'f', 1));
    int16_t s16Ntc2 = (frame.realData[2] << 8) + frame.realData[3];
    qreal fNtc2 = s16Ntc2*0.1;
    vMap.insert("fNtc2", QString::number(fNtc2, 'f', 1));
    int16_t s16Ntc3 = (frame.realData[4] << 8) + frame.realData[5];
    qreal fNtc3 = s16Ntc3*0.1;
    vMap.insert("fNtc3", QString::number(fNtc3, 'f', 1));
    int16_t s16Ntc4 = (frame.realData[6] << 8) + frame.realData[7];
    qreal fNtc4 = s16Ntc4*0.1;
    vMap.insert("fNtc4", QString::number(fNtc4, 'f', 1));
    int16_t s16Ntc5 = (frame.realData[8] << 8) + frame.realData[9];
    qreal fNtc5 = s16Ntc5*0.1;
    vMap.insert("fNtc5", QString::number(fNtc5, 'f', 1));
    int16_t s16HS3002_1_1 = (frame.realData[10] << 8) + frame.realData[11];
    qreal fHS3002_1_1 = s16HS3002_1_1*0.1;
    vMap.insert("fHS3002_1_1", QString::number(fHS3002_1_1, 'f', 1));
    int16_t s16HS3002_1_2 = (frame.realData[12] << 8) + frame.realData[13];
    qreal fHS3002_1_2 = s16HS3002_1_2*0.1;
    vMap.insert("fHS3002_1_2", QString::number(fHS3002_1_2, 'f', 1));
    int16_t s16HS3002_2_1 = (frame.realData[14] << 8) + frame.realData[15];
    qreal fHS3002_2_1 = s16HS3002_2_1*0.1;
    vMap.insert("fHS3002_2_1", QString::number(fHS3002_2_1, 'f', 1));
    int16_t s16HS3002_2_2 = (frame.realData[16] << 8) + frame.realData[17];
    qreal fHS3002_2_2 = s16HS3002_2_2*0.1;
    vMap.insert("fHS3002_2_2", QString::number(fHS3002_2_2, 'f', 1));
    uint16_t u16STK33_1 = (frame.realData[18] << 8) + frame.realData[19];
    vMap.insert("u16STK33_1", QString::number(u16STK33_1));
    uint16_t u16STK33_2 = (frame.realData[20] << 8) + frame.realData[21];
    vMap.insert("u16STK33_2", QString::number(u16STK33_2));
    int16_t s16ATC = (frame.realData[22] << 8) + frame.realData[23];
    qreal fATC = s16ATC*0.1;
    vMap.insert("fATC", QString::number(fATC, 'f', 1));
    int16_t s16AHC = (frame.realData[24] << 8) + frame.realData[25];
    qreal fAHC = s16AHC*0.1;
    vMap.insert("fAHC", QString::number(fAHC, 'f', 1));

    emit sig_parseCmd0x01Frame(vMap);
    replyCmd0x01Frame(1);
}

void SerialPortDataParse::replyCmd0x01Frame(uint8_t ret)
{
    SerialFrame frame;
    frame.frameHead = 0xAA55;
    frame.frameLen = 10+1;
    frame.slaveAddr = 0x01;
    frame.frameNo = 0x0001;
    frame.frameCmd = 0x01;
    frame.realData.append(ret);
    frame.crc16 = 0;
    QMutexLocker locker(&m_mutex);
    m_serialData.append(frame);
}

void SerialPortDataParse::parseCmd0x02Frame(SerialFrame &frame)
{
    QVariantMap vMap;
    int version = (frame.realData[1] << 16) + (frame.realData[2] << 8) + frame.realData[3];
    vMap.insert("version", version);
    emit sig_parseCmd0x02Frame(vMap);

    replyCmd0x02Frame();
}

void SerialPortDataParse::replyCmd0x02Frame()
{
    SerialFrame frame;
    frame.frameHead = 0xAA55;
    frame.frameLen = 10;
    frame.slaveAddr = 0x01;
    frame.frameNo = 0x0001;
    frame.frameCmd = 0x02;
    frame.crc16 = 0;
    QMutexLocker locker(&m_mutex);
    m_serialData.append(frame);
}

void SerialPortDataParse::parseCmd0x03Frame(SerialFrame &frame)
{
    QVariantMap vMap;
    int screen = (frame.realData[0] << 8) + frame.realData[1];
    vMap.insert("screen", screen);
    emit sig_parseCmd0x03Frame(vMap);

    replyCmd0x03Frame();
}

void SerialPortDataParse::replyCmd0x03Frame()
{
    SerialFrame frame;
    frame.frameHead = 0xAA55;
    frame.frameLen = 10;
    frame.slaveAddr = 0x01;
    frame.frameNo = 0x0001;
    frame.frameCmd = 0x03;
    frame.crc16 = 0;
    QMutexLocker locker(&m_mutex);
    m_serialData.append(frame);
}

void SerialPortDataParse::parseCmd0xA0Frame(SerialFrame &frame)
{
    uint16_t data = (frame.realData[0] << 8) + frame.realData[1];
    QVariantMap vMap;
    vMap.insert("permission", data);
    emit sig_parseCmd0xA0Frame(vMap);
}

void SerialPortDataParse::startSlaveUpgrade(QVariantMap &vMap)
{
    uint8_t location = vMap.value("location").toUInt();
    uint identify = vMap.value("identify").toUInt();
    QByteArray md5 = vMap.value("md5").toByteArray();
    uint crc32 = vMap.value("crc32").toUInt();
    uint fileSize = vMap.value("fileSize").toUInt();
    uint version = vMap.value("version").toUInt();

    SerialFrame frame;
    frame.frameHead = 0xAA55;
    frame.frameLen = 10+50;
    frame.slaveAddr = 0x01;
    frame.frameNo = 0x0001;
    frame.frameCmd = 0xA3;
    frame.realData.append(0x01);
    frame.realData.append(location);
    identify = qToBigEndian(identify);
    frame.realData.append((const char *)&identify, sizeof(identify));
    frame.realData.append(md5);
    crc32 = qToBigEndian(crc32);
    frame.realData.append((const char *)&crc32, sizeof(crc32));
    fileSize = qToBigEndian(fileSize);
    frame.realData.append((const char *)&fileSize, sizeof(fileSize));
    version = qToBigEndian(version);
    frame.realData.append((const char *)&version, sizeof(version));
    frame.crc16 = 0;
    QMutexLocker locker(&m_mutex);
    m_serialData.append(frame);
}

void SerialPortDataParse::parseCmd0xA3Frame(SerialFrame &frame)
{
    QVariantMap vMap;
    // flag: 0 不允许升级  1:允许升级
    uint8_t flag = frame.realData[0];
    vMap.insert("flag", flag);
    emit sig_parseCmd0xA3Frame(vMap);
}

void SerialPortDataParse::sendUpgradeData(uint16_t frameNo, QByteArray &byteArray)
{
    SerialFrame frame;
    frame.frameHead = 0xAA55;
    frame.frameLen = 10+byteArray.size();
    frame.slaveAddr = 0x01;
    frame.frameNo = frameNo;
    frame.frameCmd = 0xA4;
    frame.realData = byteArray;
    frame.crc16 = 0;
    QMutexLocker locker(&m_mutex);
    m_serialData.append(frame);
}

void SerialPortDataParse::parseCmd0xA4Frame(SerialFrame &frame)
{
    QVariantMap vMap;
    // flag: 0:失败  1:成功
    uint8_t flag = frame.realData[0];
    uint16_t frameNo = frame.frameNo;
    vMap.insert("flag", flag);
    vMap.insert("frameNo", frameNo);
    emit sig_parseCmd0xA4Frame(vMap);
}

void SerialPortDataParse::getUpgradeResult()
{
    SerialFrame frame;
    frame.frameHead = 0xAA55;
    frame.frameLen = 10;
    frame.slaveAddr = 0x01;
    frame.frameNo = 0x0001;
    frame.frameCmd = 0xA5;
    frame.crc16 = 0;
    QMutexLocker locker(&m_mutex);
    m_serialData.append(frame);
}

void SerialPortDataParse::parseCmd0xA5Frame(SerialFrame &frame)
{
    QVariantMap vMap;
    // flag: 0:升级失败  1:升级成功
    uint8_t flag = frame.realData[0];
    vMap.insert("flag", flag);
    emit sig_parseCmd0xA5Frame(vMap);
}

// 将界面下发参数转化为串口数据
void SerialPortDataParse::writeData(const QVariantMap &vMap)
{

}

void SerialPortDataParse::otaPermissionSet(uint16_t &data)
{
    SerialFrame frame;
    frame.frameHead = 0xAA55;
    frame.frameLen = 10+2;
    frame.slaveAddr = 0x01;
    frame.frameNo = 0x0001;
    frame.frameCmd = 0xA0;
    data = qToBigEndian(data);
    frame.realData.append((const char *)&data, sizeof(data));
    frame.crc16 = 0;
    QMutexLocker locker(&m_mutex);
    m_serialData.append(frame);
}

void SerialPortDataParse::sendData()
{
    while (flag) {
        QThread::msleep(60);
        if (m_serialData.isEmpty()) {
            continue;
        }

        SerialFrame frame;
        if (retryFlag) {
            if (!m_retryList.isEmpty()) {
                QMutexLocker locker(&m_retryMutex);
                frame = m_retryList.takeFirst();
                locker.unlock();
                emit sig_write(frame);
            }
        } else {
            QMutexLocker locker(&m_mutex);
            frame = m_serialData.takeFirst();
            locker.unlock();
            // 非回复帧
            if (!isReplyFrame(frame)) {
                retryFlag = true;
                m_currSendFrame = frame;
                emit sig_startTimer();
                QMutexLocker locker(&m_retryMutex);
                m_retryList.clear();
            }

            emit sig_write(frame);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
void Widget::Select() //查询 { QString name = ui->lineEdit->text(); model->setFilter(QObject::tr("id = '%1'").arg(name)); //根据姓名进行筛选 model->select(); //显示结果 } void Widget::Delect() //删除当前行 { int curRow = ui->tableView->currentIndex().row(); //获取选中的行 model->removeRow(curRow); //删除该行 int ok = QMessageBox::warning(this,tr("删除当前行!"),tr("你确定" "删除当前行吗?"), QMessageBox::Yes,QMessageBox::No); if(ok == QMessageBox::No) { model->revertAll(); //如果不删除,则撤销 } else model->submitAll(); //否则提交,在数据库中删除该行 } void Widget::Add() //插入记录 { int rowNum = model->rowCount(); //获得表的行数 int id = 10; model->insertRow(rowNum); //添加一行 model->setData(model->index(rowNum,0),id); //model->submitAll(); //可以直接提交 } void Widget::Back() //返回全表 { model->setTable("student"); //重新关联表 model->setHeaderData(0, Qt::Horizontal, "Time"); model->setHeaderData(1, Qt::Horizontal, "Temperature"); model->select(); //这样才能再次显示整个表的内容 } void Widget::Amend() //提交修改 { model->database().transaction(); //开始事务操作 if (model->submitAll()) { model->database().commit(); //提交 } else { model->database().rollback(); //回滚 QMessageBox::warning(this, tr("tableModel"), tr("数据库错误: %1").arg(model->lastError().text())); } } void Widget::Get_time() { QString string; QTime current_time = QTime::currentTime(); int hour = current_time.hour(); int minute = current_time.minute(); int second = current_time.second(); // int msec = current_time.msec(); string=QString("%1").arg(hour)+":"+QString("%1").arg(minute) +":"+QString("%1").arg(second); ui->Receive->append(string); //qDebug() <rowCount(); //获得表的行数 // int id = 10; model->insertRow(rowNum); //添加一行 model->setData(model->index(rowNum,0),string); model->submitAll(); } void Widget::readMyCom() { QByteArray temp = myCom->readAll(); if(temp.size()!=0) { QString string; QTime current_time = QTime::currentTime(); int hour = current_time.hour(); int minute = current_time.minute(); int second = current_time.second(); // int msec = current_time.msec(); string=QString("%1").arg(hour)+":"+QString("%1").arg(minute) +":"+QString("%1").arg(second); ui->Receive->append(string); //qDebug() <rowCount(); //获得表的行数 // int id = 10; model->insertRow(rowNum); //添加一行 model->setData(model->index(rowNum,0),string); model->setData(model->index(rowNum,1),temp); model->submitAll(); data_light=temp.toInt(); } ui->Receive->append(temp); } void Widget::openCom() { QString portName = ui->portNameComboBox->currentText(); myCom = new Win_QextSerialPort(portName,QextSerialBase::EventDriven); myCom ->open(QIODevice::ReadWrite); if(ui->baudRateComboBox->currentText()==tr("9600")) myCom->setBaudRate(BAUD9600); else if(ui->baudRateComboBox->currentText()==tr("115200")) myCom->setBaudRate(BAUD115200); myCom->setFlowControl(FLOW_OFF); myCom->setTimeout(500); connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom())); ui->openMyComBtn->setEnabled(false); ui->closeMyComBtn->setEnabled(true); ui->baudRateComboBox->setEnabled(false); ui->portNameComboBox->setEnabled(false); }
以下是使用QT串口助手实现协议解析的步骤: 1.打开QT串口助手,连接串口设备。 2.在串口助手中设置协议解析规则,例如:以“#”作为帧头,“\r\n”作为帧尾,第1-2个字节表示数据长度,第3个字节表示命令型,第4-5个字节表示数据内容。 3.在串口助手中接收到数据后,根据协议解析规则进行解析,提取出数据内容并进行处理。 4.将处理后的数据显示在串口助手的界面上或者发送给其他设备。 下面是一个简单的QT串口助手协议解析的示例代码: ```python # 导入必要的模块 from PyQt5.QtCore import QIODevice, QByteArray from PyQt5.QtSerialPort import QSerialPort, QSerialPortInfo # 定义协议解析规则 FRAME_HEAD = b'#' FRAME_TAIL = b'\r\n' DATA_LEN_INDEX = 0 CMD_TYPE_INDEX = 2 DATA_CONTENT_INDEX = 3 # 定义串口助手 class SerialHelper: def __init__(self): self.serial = QSerialPort() self.serial.readyRead.connect(self.receive_data) # 打开串口 def open_serial(self, port_name, baud_rate): self.serial.setPortName(port_name) self.serial.setBaudRate(baud_rate) self.serial.setDataBits(QSerialPort.Data8) self.serial.setParity(QSerialPort.NoParity) self.serial.setStopBits(QSerialPort.OneStop) self.serial.setFlowControl(QSerialPort.NoFlowControl) if self.serial.open(QIODevice.ReadWrite): return True else: return False # 关闭串口 def close_serial(self): self.serial.close() # 发送数据 def send_data(self, data): self.serial.write(data) # 接收数据 def receive_data(self): data = self.serial.readAll() if data: self.parse_data(data) # 解析数据 def parse_data(self, data): frame_head_pos = data.indexOf(FRAME_HEAD) frame_tail_pos = data.indexOf(FRAME_TAIL) if frame_head_pos != -1 and frame_tail_pos != -1 and frame_tail_pos > frame_head_pos: data_len = data[DATA_LEN_INDEX:CMD_TYPE_INDEX] cmd_type = data[CMD_TYPE_INDEX] data_content = data[DATA_CONTENT_INDEX:frame_tail_pos] # 处理数据内容 print(data_content) ``` 相关问题:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值