zoukankan      html  css  js  c++  java
  • <QT学习>QT中串口QSerialport类学习与使用

       QT5中已经增加了串口类QSrialPort,可以直接调用API函数进行快速开发。

      注意qmake那边:QT += serialport。要把QT += serialport在加到.pro文件中

    1. 获取串口信息

    Dialog::Dialog(QWidget *parent)
        : QDialog(parent)
    {
        const auto infos = QSerialPortInfo::availablePorts();
        for (const QSerialPortInfo &info : infos)
            serialPortComboBox->addItem(info.portName());
    }
    • QSerialPortInfo::availablePorts()

     

    函数的功能时会检测当前电脑上串行端口,并且返回系统上串行端口的信息。

    之后将获取到的信息加入Qcombobox下拉选项框中。本例中只添加了串口的名字即COM4。

    2.设置串口参数并开启串口

    void Dialog::openSerial()
    {
        if(runButton->text() == tr("开启"))
        {
            serial = new QSerialPort();
    
            //port name
            serial->setPortName(serialPortComboBox->currentText());
    
            //open
            serial->open(QIODevice::ReadWrite);
    
            serial->setBaudRate(115200);
            serial->setDataBits(QSerialPort::Data8);
            serial->setStopBits(QSerialPort::OneStop);
            serial->setFlowControl(QSerialPort::NoFlowControl);
    
         /* 一定要写,不然串口接收不到数据 */ connect(serial, SIGNAL(readyRead()),
    this, SLOT(readParam())); runButton->setText("关闭"); } else { serial->clear(); serial->close(); serial->deleteLater(); runButton->setText("开启"); } }connect(serial, SIGNAL(readyRead()), this, SLOT(readParam()));
      该函数是启动串口接收功能。即当串口有数据时,readyRead()信号就会被抛出。对应的readParam()即QT中所定义的槽就会被调用。

    注意:
      readyRead()信号是有数据就直接抛出,在实际数据交互中,往往一帧数据有很多字节。这意味着我们一帧数据数据会触发多次信号。应当在对数据进行操作时候对数据进行校验。


    3.串口发送数据
    serial->write(sendData);

    sendData为QByteArray类所创建的对象,即数据缓存区。

    4.串口接收数据
    g_RecBuf.append(serial->readAll());

      readAll函数会读取当前设备所有剩余数据,并将它作为字节数组返回。

    以上实例源码:

    dialog.cpp

    #include "dialog.h"
    #include <QDebug>
    #include <QThread>
    #include <QTimer>
    
    Dialog::Dialog(QWidget *parent)
        : QDialog(parent)
    {
        serialPortComboBox = new QComboBox();
        readParaBox = new QComboBox();
        writeParaBox = new QComboBox();
        runButton = new QPushButton(tr("开启"));
        readPara = new QPushButton(tr("读取参数"));
        writePara = new QPushButton(tr("下发参数"));
        onlyOneRead = new QPushButton(tr("一键读取"));
        onlyOneWrite = new QPushButton(tr("一键下发"));
        cmd = readFlag;
    
        timer = new QTimer();
    
        /* add comprot into combobox item */
        const auto infos = QSerialPortInfo::availablePorts();
        for (const QSerialPortInfo &info : infos)
            serialPortComboBox->addItem(info.portName());
    
        readParaBox->addItem(tr("读取参数地址1"));
        readParaBox->addItem(tr("读取参数地址2"));
        readParaBox->addItem(tr("读取参数地址3"));
        readParaBox->addItem(tr("读取参数地址4"));
        readParaBox->addItem(tr("读取参数地址5"));
    
        writeParaBox->addItem(tr("下发参数地址1"));
        writeParaBox->addItem(tr("下发参数地址2"));
        writeParaBox->addItem(tr("下发参数地址3"));
        writeParaBox->addItem(tr("下发参数地址4"));
        writeParaBox->addItem(tr("下发参数地址5"));
    
        auto mainLayout = new QGridLayout;
        mainLayout->addWidget(serialPortComboBox, 0, 0);
        mainLayout->addWidget(runButton, 0, 1);
        mainLayout->addWidget(readParaBox,1,0);
        mainLayout->addWidget(readPara, 1, 1);
        mainLayout->addWidget(writeParaBox,2,0);
        mainLayout->addWidget(writePara, 2, 1);
        mainLayout->addWidget(onlyOneRead,3,0);
        mainLayout->addWidget(onlyOneWrite,3,1);
        setLayout(mainLayout);
    
        connect(runButton, &QPushButton::clicked, this, &Dialog::openSerial);
        connect(readPara, &QPushButton::clicked, this, &Dialog::sendCmd);
        connect(writePara, &QPushButton::clicked, this, &Dialog::writeParam);
        connect(timer, SIGNAL(timeout()), this, SLOT(timerStop()));
        connect(onlyOneRead,&QPushButton::clicked,this,&Dialog::oneRead);
        connect(onlyOneWrite,&QPushButton::clicked,this,&Dialog::oneWrite);
    }
    
    void Dialog::openSerial()
    {
        if(runButton->text() == tr("开启"))
        {
            serial = new QSerialPort();
    
            //port name
            serial->setPortName(serialPortComboBox->currentText());
    
            //open
            serial->open(QIODevice::ReadWrite);
    
            serial->setBaudRate(115200);
            serial->setDataBits(QSerialPort::Data8);
            serial->setStopBits(QSerialPort::OneStop);
            serial->setFlowControl(QSerialPort::NoFlowControl);
    
            connect(serial, SIGNAL(readyRead()), this, SLOT(readParam()));
    
            runButton->setText("关闭");
        }
        else
        {
            serial->clear();
            serial->close();
            serial->deleteLater();
    
            runButton->setText("开启");
        }
    }
    
    void Dialog::writeParam(void)
    {
        QByteArray sendData;
        sendData.resize(1026);
    
        QString strWriteFile = writeParaBox->currentText();
        strWriteFile.append(".dat");
    
        if(strWriteFile == "下发参数地址1.dat")
        {
            file.setFileName("读取参数地址1.dat");
            if(file.open(QFile::ReadOnly))
            {
                sendData = file.readAll();
                serial->write(sendData);
            }
        }
        else if(strWriteFile == "下发参数地址2.dat")
        {
            file.setFileName("读取参数地址2.dat");
            if(file.open(QFile::ReadOnly))
            {
                sendData = file.readAll();
                serial->write(sendData);
            }
        }
        else if(strWriteFile == "下发参数地址3.dat")
        {
            file.setFileName("读取参数地址3.dat");
            if(file.open(QFile::ReadOnly))
            {
                sendData = file.readAll();
                serial->write(sendData);
            }
        }
        else if(strWriteFile == "下发参数地址4.dat")
        {
            file.setFileName("读取参数地址4.dat");
            if(file.open(QFile::ReadOnly))
            {
                sendData = file.readAll();
                serial->write(sendData);
            }
        }
        else if(strWriteFile == "下发参数地址5.dat")
        {
            file.setFileName("读取参数地址5.dat");
            if(file.open(QFile::ReadOnly))
            {
                sendData = file.readAll();
                serial->write(sendData);
            }
        }
        file.close();
        sendData.clear();
    }
    
    void Dialog::timerStop(void)
    {
        g_RecBuf.prepend(0xBB);
    
        timer->stop();
        {
            QByteArray leftAck = g_RecBuf.left(2);
            QByteArray rightAck = g_RecBuf.right(1);
    
            QByteArray byte1;
            QByteArray byte2;
    
            byte1.append(0xBB);
            byte1.append(0xAA);
            byte2.append(0xFF);
    
            if(g_RecBuf.size() > 30)
            {
                Dialog::saveDataToFile(g_RecBuf);
            }
            else if(leftAck == byte1 && rightAck == byte2 && cmd == writeFlag)
            {
                cmd = readFlag;
                msglabel = new QLabel();
                QMessageBox::question(this,tr("提示"),tr("下发参数成功"), QMessageBox::Ok);
            }
        }
        g_RecBuf.clear();
    }
    
    void Dialog::readParam()
    {
        timer->start(100);
        g_RecBuf.append(serial->readAll());
    }
    
    /* Function: Dialog::saveDataToFile
     * Describe: Save the data from serial into File
    */
    void Dialog::saveDataToFile(QByteArray &data)
    {
        if(cmd == readFlag)
        {
            QString strFileName = readParaBox->currentText();
    
            file.setFileName(strFileName.append(".dat"));
            if(file.open(QFile::WriteOnly))
            {
                file.write(data);
            }
            file.close();
        }
    
        if(cmd != readFlag)
        {
            switch (cmd) {
            case cmd1:
                file.setFileName("读取参数地址1.dat");
                if(file.open(QFile::WriteOnly))
                {
                    file.write(data);
                }
                file.close();
                Dialog::oneRead();
                break;
    
            case cmd2:
                file.setFileName("读取参数地址2.dat");
                if(file.open(QFile::WriteOnly))
                {
                    file.write(data);
                }
                file.close();
                Dialog::oneRead();
                break;
    
            case cmd3:
                file.setFileName("读取参数地址3.dat");
                if(file.open(QFile::WriteOnly))
                {
                    file.write(data);
                }
                file.close();
                Dialog::oneRead();
                break;
    
            case cmd4:
                file.setFileName("读取参数地址4.dat");
                if(file.open(QFile::WriteOnly))
                {
                    file.write(data);
                }
                file.close();
                Dialog::oneRead();
                break;
    
            case cmd5:
                file.setFileName("读取参数地址5.dat");
                if(file.open(QFile::WriteOnly))
                {
                    file.write(data);
                }
                file.close();
                cmd = readFlag;
                break;
            default:
                break;
            }
        }
    }
    
    void Dialog::sendCmd(void)
    {
        QByteArray sendpara;
    
        unsigned char zero = 0x00;
    
        if(readParaBox->currentText() == tr("读取参数地址1"))
        {
            sendpara.append(0xAA);
            sendpara.append(0x33);
            sendpara.append(0x01);
            sendpara.append(zero);
            sendpara.append(zero);
            sendpara.append(zero);
            sendpara.append(0xFF);
        }
        else if(readParaBox->currentText() == tr("读取参数地址2"))
        {
            sendpara.append(0xAA);
            sendpara.append(0x33);
            sendpara.append(0x02);
            sendpara.append(zero);
            sendpara.append(zero);
            sendpara.append(zero);
            sendpara.append(0xFF);
        }
        else if(readParaBox->currentText() == tr("读取参数地址3"))
        {
            sendpara.append(0xAA);
            sendpara.append(0x33);
            sendpara.append(0x03);
            sendpara.append(zero);
            sendpara.append(zero);
            sendpara.append(zero);
            sendpara.append(0xFF);
        }
        else if(readParaBox->currentText() == tr("读取参数地址4"))
        {
            sendpara.append(0xAA);
            sendpara.append(0x33);
            sendpara.append(0x04);
            sendpara.append(zero);
            sendpara.append(zero);
            sendpara.append(zero);
            sendpara.append(0xFF);
        }
        else if(readParaBox->currentText() == tr("读取参数地址5"))
        {
            sendpara.append(0xAA);
            sendpara.append(0x33);
            sendpara.append(0x05);
            sendpara.append(zero);
            sendpara.append(zero);
            sendpara.append(zero);
            sendpara.append(0xFF);
        }
    
        serial->write(sendpara);
        sendpara.clear();
    }
    
    void Dialog::oneRead(void)
    {
        QByteArray cmdArray;
        unsigned char zero = 0x00;
    
        switch (cmd) {
        case readFlag:
            cmdArray.append(0xAA);
            cmdArray.append(0x33);
            cmdArray.append(0x01);
            cmdArray.append(zero);
            cmdArray.append(zero);
            cmdArray.append(zero);
            cmdArray.append(0xFF);
            cmd = cmd1;
    
            serial->write(cmdArray);
            cmdArray.clear();
            break;
    
        case cmd1:
            cmdArray.append(0xAA);
            cmdArray.append(0x33);
            cmdArray.append(0x02);
            cmdArray.append(zero);
            cmdArray.append(zero);
            cmdArray.append(zero);
            cmdArray.append(0xFF);
            cmd = cmd2;
    
            serial->write(cmdArray);
            cmdArray.clear();
            break;
    
        case cmd2:
            cmdArray.append(0xAA);
            cmdArray.append(0x33);
            cmdArray.append(0x03);
            cmdArray.append(zero);
            cmdArray.append(zero);
            cmdArray.append(zero);
            cmdArray.append(0xFF);
            cmd = cmd3;
    
            serial->write(cmdArray);
            cmdArray.clear();
            break;
    
        case cmd3:
            cmdArray.append(0xAA);
            cmdArray.append(0x33);
            cmdArray.append(0x04);
            cmdArray.append(zero);
            cmdArray.append(zero);
            cmdArray.append(zero);
            cmdArray.append(0xFF);
            cmd = cmd4;
    
            serial->write(cmdArray);
            cmdArray.clear();
            break;
    
        case cmd4:
            cmdArray.append(0xAA);
            cmdArray.append(0x33);
            cmdArray.append(0x05);
            cmdArray.append(zero);
            cmdArray.append(zero);
            cmdArray.append(zero);
            cmdArray.append(0xFF);
            cmd = cmd5;
    
            serial->write(cmdArray);
            cmdArray.clear();
            break;
        }
    }
    
    void Dialog::oneWrite(void)
    {
        QByteArray sendData;
        sendData.resize(1026);
    
        file.setFileName("读取参数地址1.dat");
        if(file.open(QFile::ReadOnly))
        {
            sendData = file.readAll();
            serial->write(sendData);
        }
        file.close();
        sendData.clear();
    
        file.setFileName("读取参数地址2.dat");
        if(file.open(QFile::ReadOnly))
        {
            sendData = file.readAll();
            serial->write(sendData);
        }
        file.close();
        sendData.clear();
    
        file.setFileName("读取参数地址3.dat");
        if(file.open(QFile::ReadOnly))
        {
            sendData = file.readAll();
            serial->write(sendData);
        }
        file.close();
        sendData.clear();
    
    
        file.setFileName("读取参数地址4.dat");
        if(file.open(QFile::ReadOnly))
        {
            sendData = file.readAll();
            serial->write(sendData);
        }
        file.close();
        sendData.clear();
    #if 0
        file.setFileName("读取参数地址5.dat");
        if(file.open(QFile::ReadOnly))
        {
            sendData = file.readAll();
            serial->write(sendData);
        }
        file.close();
        sendData.clear();
    #endif
    
        cmd = writeFlag;
    }
    
    Dialog::~Dialog()
    {
    
    }
    

    dialog.h

    #ifndef DIALOG_H
    #define DIALOG_H
    
    #include <QDialog>
    
    #include <QComboBox>
    #include <QLabel>
    #include <QPushButton>
    #include <QGridLayout>
    #include <QtSerialPort/QSerialPortInfo>
    #include <QtSerialPort>
    #include <QFile>
    #include <QTextStream>
    #include <QDateTime>
    #include <QTimer>
    #include <QMessageBox>
    
    enum enumType
    {
      readFlag,
      cmd1,
      cmd2,
      cmd3,
      cmd4,
      cmd5,
      writeFlag
    };
    
    class Dialog : public QDialog
    {
        Q_OBJECT
    
    public:
        Dialog(QWidget *parent = 0);
        ~Dialog();
    
    private slots:
        void openSerial(void);
        void writeParam(void);
        void sendCmd(void);
        void timerStop(void);
        void readParam(void);
        void oneRead(void);
        void oneWrite(void);
    
    private:
        void saveDataToFile(QByteArray &data);
    
    
    private:
        QComboBox *serialPortComboBox;
        QComboBox *readParaBox;
        QComboBox *writeParaBox;
    
        QPushButton *runButton;
        QPushButton *readPara;
        QPushButton *writePara;
        QPushButton *onlyOneRead;
        QPushButton *onlyOneWrite;
    
        QLabel *msglabel;
        QSerialPort *serial;
        QTimer *timer;
        QFile file;
        QByteArray g_RecBuf;
    
        unsigned int Flag;
    
        enumType cmd;
    };
    
    
    #endif // DIALOG_H
    

      运行效果:

       作用就是通过串口发送以及接收一些数据。




  • 相关阅读:
    Resize a VMWare disk (zz)
    StepbyStep: Installing SQL Server Management Studio2008 Express after Visual Studio 2010(zz)
    (C#)利用反射动态调用类成员[转载]
    Discuz!NT 系统架构分析 (转)
    C#反射实例讲解(转)
    什么是反射?
    创建保存图片目录
    取资源文件中的值 System.Resources.ResourceManager
    Net中的反射使用入门
    iis上实现虚拟目录
  • 原文地址:https://www.cnblogs.com/zhuangquan/p/10114714.html
Copyright © 2011-2022 走看看