串口封装

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;
}

 

posted @ 2018-08-24 16:17  朱小勇  阅读(696)  评论(1编辑  收藏  举报