多线程串口通信

串口通信类似于udp通信,是无连接的,所以也要考虑编写心跳等协议

实际开发中根据给定的数据协议和给定的显示功能进行开发,制定相应的数据解析

这里我用通用的串口通信讲解如何快速搭建一个显示单片机或者其他计算机的各种信息


1.设计协议包的操作类

#ifndef AGREEMENT_H
#define AGREEMENT_H

#include <QObject>
#include <qbytearray.h>
#include <QMap>
#include <QVector>



namespace  协议名{ //可用json读取进行配置
enum Function {
    WAVE =0x01
....
};
}
#define Q_NOTZERO(x) ((x!=0))

typedef struct SendPage{    //发送包
    qint16 initial1 = 0x55;//字头
    qint16 initial2 = 0xbe;//字头
    qint16 packetlength = 0x0c;//包长
    qint16 expressCommand = 0x0;//表示命令
    qint16 function = 0x0;//功能
    ....
    qint16 checkH;//效验H
    qint16 checkL;//效验L
public:
    QString number(qint16 number);//QString::number

    void setExpressCommand(qint16 expressCommand) {
        this->expressCommand = expressCommand;
    }

    void  setFunction(qint16 function) {
        this->function = function;
    }

    void setData(QVariant data);

    SendPage(); 
    void commit( QByteArray & byte) {//根据校验方式进行校验 同样可用使用json配置

        checkH = 0;

        switch (checkL)
        {
        case 方法1:
            
        case 方法2:

            break;
        default:

            break;
        }


        QString _str = QString(number(initial1) + ' '+
                               number(initial2) + ' '+
                               number(packetlength) + ' ' +
                               number(expressCommand) + ' ' +
                               number(function) + ' ' +
                                ......
                               number(fill[0]) + ' ' +
                number(checkH) + ' ' +
                number(checkL));


        SerialPort::String2Hex(_str, byte); //转化为16进制

    }


    void setCheckL(qint16 checkL) {
        this->checkL = checkL;
    }

    void setFill(QVector<qint16> data){
        for(int i=0;i<6 && i<data.length();++i)
            this->fill[i]=data.at(i);
    }




    qint16 getInitial2() const;
    void setInitial2(const qint16 &value);
}SendPage;


namespace PageHelp //xx为默认校验
{

void set协议1(QByteArray & byte, qint16 type, QVariant data, qint16 expressCommand, qint16 checkL = xx);
void set协议2(QByteArray &byte,qint16 type, QVariant data, qint16 expressCommand , qint16 checkL = xx);
}



class Agreement :public QObject
{
    Q_OBJECT
public:
    explicit  Agreement(){

    }

    explicit Agreement(QVector<qint16> &vector,QObject *parent = nullptr):QObject(parent) {
        m_vector = vector;
    }
    explicit  Agreement(QObject *parent = nullptr):QObject(parent) {

    }
    QVector<qint16> values() const;
    void setVector(const QVector<qint16> &values);
    void append(qint16 value);

    Agreement(const Agreement & agreement){
        this->setVector(agreement.values());
    }
    qint16 indexOf(quint16 index){
        if(index>=this->m_vector.length() || index<0){
            return 0;
        }
        return m_vector[index];
    }

    void setList(QVector<qint16> & list);

    void set(qint16 index,QVariant value);

signals:
    void setupSuccess(qint16 function,qint16 value);
private:
    QVector<qint16> m_vector;
};

class 协议1:public Agreement
{
    Q_OBJECT
public:

    void  onSet(QVector<qint16> data);

    qint16 value(AMMONOX::Function function);
    协议1命名空间::Function key(qint16 value);
    协议1(QVector<qint16> &vector,QObject *parent = nullptr);
signals:
    void sendPage(QByteArray page);

private:

    QMap<协议1命名空间::Function,qint16> m_mapFunction;
};

class 协议2:public Agreement
{
    Q_OBJECT
public:

    void onSet(QVector<qint16> data);
    协议2命名空间::Function key(qint16 value);
    qint16 value(协议2::Function function);

    协议2(QVector<qint16> &vector,QObject *parent = nullptr);
signals:
    void sendPage(QByteArray page);

private:

    QMap<协议2命名空间::Function,qint16> m_mapFunction;
};

#endif //

2.设计串口消息接受发送类

实际开发过程中,PC性能一般大于下位机所有接受并不是一次就接受所有数据,而是和udp一样分片发送,所以再收发的过程中注意收发频率.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值