• 串口封装


    1、头文件

    #ifndef MYSERIAL_H
    #define MYSERIAL_H#include <QSerialPort>
    #include "mymethod.h"
    class MySerial : public QSerialPort
    {
        Q_OBJECT
    
    public:
        MySerial(QObject *parent);
        ~MySerial();
    
    private:
        QSerialPort* serialPort = NULL;//串口对象
        QByteArray HEAD;//报文头
        void init();//初始化private slots:
        void openSlot(SerialPortInfo serialPortInfo);//连接函数
        void rcvSlot();//接收数据槽函数
        void sendSlot(QByteArray ba);//发送数据槽函数
        void closeSlot();//关闭槽函数
    
    signals:
        void serialStateSignal(QString info);//向外发出的调试信息
        void getPacketSignal(int type, QByteArray ba);//tcp将不同的包发出去
    };
    
    #endif // MYSERIAL_H

    2、源文件

    #include "myserial.h"
    
    MySerial::MySerial(QObject *parent)
    : QSerialPort(parent)
    {
        this->init();
    }
    
    MySerial::~MySerial()
    {
    
    }
    
    
    /*****************************************************************/
    //作者:朱小勇
    //函数名称:初始化
    //函数参数:NULL
    //函数返回值:NULL
    //函数作用:NULL
    //备注:NULL
    /*****************************************************************/
    void MySerial::init()
    {
        HEAD.resize(2); HEAD[0] = 0x55; HEAD[1] = 0xAA;
    }
    
    /*****************************************************************/
    //作者:朱小勇
    //函数名称:打开串口
    //函数参数:NULL
    //函数返回值:NULL
    //函数作用:NULL
    //备注:NULL
    /*****************************************************************/
    void MySerial::openSlot(SerialPortInfo serialPortInfo)
    {
        if (NULL == serialPort)
        {
            serialPort = new QSerialPort();
            QObject::connect(serialPort, SIGNAL(readyRead()), this, SLOT(rcvSlot()));
        }
        if (serialPort->isOpen())
        {
            return;
        }
        serialPort->setPortName(serialPortInfo.portName);
        serialPort->setBaudRate(serialPortInfo.baudRate, QSerialPort::AllDirections);
        serialPort->setDataBits(serialPortInfo.dataBits);//数据位
        serialPort->setParity(serialPortInfo.parity);//校验位
        serialPort->setStopBits(serialPortInfo.stopBits);//停止位
        serialPort->setFlowControl(QSerialPort::NoFlowControl);//流控制
        if (serialPort->open(QIODevice::ReadWrite))//打开串口
        {
            emit serialStateSignal("串口打开成功...");
        }
        else
        {
            emit serialStateSignal("串口打开失败!!!");
        }
    }
    
    /*****************************************************************/
    //作者:朱小勇
    //函数名称:接收数据
    //函数参数:NULL
    //函数返回值:NULL
    //函数作用:NULL
    //备注:NULL
    /*****************************************************************/
    void MySerial::rcvSlot()
    {
        static QByteArray allBa;//用来存所有文件
        allBa.append(serialPort->readAll());//读取数据
        int head = allBa.indexOf(HEAD);//报文头的位置
        uint16_t length = 0;//存长度字节
        QByteArray currentBa;
        int id = 0;
        while (-1 != head)
        {
            allBa = allBa.mid(head);//去掉报头之前的
            memcpy(&length, allBa.data() + 2, 2);
            if (allBa.size() >= length)//长度够,进行解析
            {
                currentBa = allBa.mid(0, length);//获取当前完成包
                id = Mymethod::getPacketType(currentBa);
                if (-1 != id)
                {
                    emit getPacketSignal(id, currentBa);
                }
                allBa = allBa.mid(2);
            }
            else
            {
                break;
            }
            head = allBa.indexOf(HEAD);//刷新报文头的位置
        }
    }
    
    /*****************************************************************/
    //作者:朱小勇
    //函数名称:发送
    //函数参数:NULL
    //函数返回值:NULL
    //函数作用:NULL
    //备注:NULL
    /*****************************************************************/
    void MySerial::sendSlot(QByteArray ba)
    {
        if (NULL == serialPort)
        {
            emit serialStateSignal("串口未初始化!!!");
            return;
        }
        if (!serialPort->isOpen())
        {
            emit serialStateSignal("串口未打开!!!");
            return;
        }
        if (ba.size() != serialPort->write(ba))
        {
            emit serialStateSignal("指令发送失败!!!");
        }
        else
        {
            emit serialStateSignal("发送指令成功...");
        }
    }
    
    /*****************************************************************/
    //作者:朱小勇
    //函数名称:关闭
    //函数参数:NULL
    //函数返回值:NULL
    //函数作用:NULL
    //备注:NULL
    /*****************************************************************/
    void MySerial::closeSlot()
    {
        if (NULL == serialPort)
        {
            return;
        }
        serialPort->close();
        emit serialStateSignal("已关闭串口...");
    }

    3、自定义函数,获取报文类型

    int Mymethod::getPacketType(const QByteArray& ba)
    {
        int result = -1;
        uint16_t length = 0;
        if ((ba[0] == (char)0x55) && (ba[1] == (char)0xAA))//报文头正确
        {
            memcpy(&length, ba.data() + 2, 2);
            if (length == ba.size())//长度正确
            {
                QByteArray tempBa; tempBa.resize(ba.size() - 1);
                memcpy(tempBa.data(), ba.data(), ba.size() - 1);
                char crc = Mymethod::CRC(tempBa);
                if (crc == ba[ba.size() - 1])//CRC正确
                {
                    result = (int)ba[4];
                }
            }
        }
        return result;
    }
  • 相关阅读:
    三元运算
    sys and os
    print.format
    while loop
    线段树模板
    Round #431 (Div.2)
    D. Make a Permutation!
    Round #411 (Div.2)
    Round #432 (Div.2)
    Round #433 (Div.2)
  • 原文地址:https://www.cnblogs.com/judes/p/9530522.html
Copyright © 2020-2023  润新知