cstriker1407的笔记本

好记性不如铅笔头

C && C++, QT, 编程

QT5使用串口简单笔记

最近重新拾起来了QT编程,这里简单的笔记下如何使用QT的串口功能。
QT除了可以跨平台之外,它的文档和DEMO也写的非常优秀。串口的文档网址【 https://doc.qt.io/qt-5/qtserialport-index.html 】
从文档中可以看到,QT对于串口有2个操作类,一个是信息查询类,一个是串口读写类。
这里分别简单笔记下:

项目引用:

参考文档,可以看到,使用串口需要增加module,如下图:

信息查询:

API【 https://doc.qt.io/qt-5/qserialportinfo.html 】,代码非常简单:

#include <QSerialPortInfo>

void refresh_serial()
{
    QList<QSerialPortInfo> port_list = QSerialPortInfo::availablePorts();
    for(int index = 0; index < port_list.size(); index++)
    {
        qDebug("Find Port:%s\t%s\t%s\t%s\t%s\t%s",
               qPrintable(port_list[index].description()),
               qPrintable(port_list[index].manufacturer()),
               qPrintable(port_list[index].portName()),
               qPrintable(port_list[index].serialNumber()),
               qPrintable(port_list[index].systemLocation())
               );
    }
}

输出信息类似如下:

Find Port:Silicon Labs CP210x USB to UART Bridge	Silicon Labs	COM4	0001	\\.\COM4	H?????
这里需要注意的是我们使用【 portName 】 来进行串口读写操作。

串口读写:

QT串口读写API非常简单,支持同步/异步读写,支持配置各种串口选项。这里只笔记一个最简单的DEMO:

/*
demo_serial_port.h
*/
#ifndef DEMO_SERIAL_PORT_H
#define DEMO_SERIAL_PORT_H

#include <QSerialPort>

class Demo_Serial_Port : public QObject
{
    Q_OBJECT

public:
    Demo_Serial_Port();

    void init_uart(QString &port_name, int baudrate);
    void release_uart();

    /*
block_time==0: 不阻塞
block_time>0:  阻塞时间:block_time毫秒
    */
    bool write_data(const QString &data, unsigned int block_time);
/*
read_timeout==0: 不阻塞
read_timeout>0:  阻塞时间:read_timeout毫秒
*/
    QString read_data(unsigned int read_timeout);

signals:
    void on_write_finished(Demo_Serial_Port *port);
    void on_read_ready(Demo_Serial_Port *port);

private slots:
    void handleReadyRead();
    void handleBytesWritten(qint64 bytes);
    void handleError(QSerialPort::SerialPortError error);

private:
    QSerialPort serial_port;
    QByteArray written_data;
    qint64 written_bytes;
    bool inited;
};

#endif // DEMO_SERIAL_PORT_H

//==================================================================
/*
demo_serial_port.cpp
*/

#include "Demo_Serial_Port.h"

Demo_Serial_Port::Demo_Serial_Port()
{
    inited = false;
}

void Demo_Serial_Port::init_uart(QString &port_name, int baudrate)
{
    if(inited != false)
        return;

    qDebug("Init Uart <%s>:%d", qPrintable(port_name), baudrate);

    serial_port.setPortName(port_name);
    serial_port.setBaudRate(baudrate);
    serial_port.setDataBits(QSerialPort::Data8);
    serial_port.setStopBits(QSerialPort::OneStop);
    serial_port.setParity(QSerialPort::NoParity);
    serial_port.setFlowControl(QSerialPort::NoFlowControl);

    connect(&serial_port, &QSerialPort::readyRead, this, &Demo_Serial_Port::handleReadyRead);
    connect(&serial_port, &QSerialPort::errorOccurred, this, &Demo_Serial_Port::handleError);
    connect(&serial_port, &QSerialPort::bytesWritten, this, &Demo_Serial_Port::handleBytesWritten);

    serial_port.open(QIODevice::ReadWrite);

    written_bytes = 0;
    inited = true;
}

void Demo_Serial_Port::release_uart()
{
    if(inited != true)
        return;

    qDebug("Release Uart <%s>", qPrintable(serial_port.portName()));
    serial_port.close();
    written_bytes = 0;
}


bool Demo_Serial_Port::write_data(const QString &data, unsigned int block_time)
{
    if(inited != true)
        return false;

    if(written_bytes != 0)
    {
        qCritical("<%s> last written not finish %d", qPrintable(serial_port.portName()), written_bytes);
        return false;
    }

    written_bytes = 0;
    written_data = data.toLocal8Bit();
    written_data.append('\r');

    qint64 bytesWritten = serial_port.write(written_data);
    if ((bytesWritten == -1) || (bytesWritten != written_data.size()))
    {
        qCritical("<%s> write Err:%d data:%s", qPrintable(serial_port.portName()),bytesWritten, qPrintable(data) );
        return false;
    }

    if(block_time > 0)
    {
        if (serial_port.waitForBytesWritten(block_time) != true)
        {
            qCritical("<%s> write Timeout:%d data:%s", qPrintable(serial_port.portName()),bytesWritten, qPrintable(data) );
            return false;
        }else
        {
            written_bytes = 0;
            qDebug("<%s> write data:<%s> Finish", qPrintable(serial_port.portName()),written_data.data());
            return true;
        }
    }else
    {
        return true;
    }
}

QString Demo_Serial_Port::read_data(unsigned int read_timeout)
{
    if(inited != true)
        return QString("");

    QByteArray readData = serial_port.readAll();
    if(read_timeout != 0)
    {
        if(serial_port.waitForReadyRead(read_timeout) == true)
        {
            readData.append(serial_port.readAll());
        }else
        {
            qCritical("<%s> read Timeout:%d", qPrintable(serial_port.portName()), read_timeout);
        }
    }
    qDebug("<%s> read data:<%s> Success", qPrintable(serial_port.portName()),readData.data());
    return QString(readData);
}

void Demo_Serial_Port::handleReadyRead()
{
    emit on_read_ready(this);
}

void Demo_Serial_Port::handleBytesWritten(qint64 bytes)
{
    written_bytes += bytes;
    if(written_bytes == written_data.size())
    {
//        qDebug("<%s> write data:%s Finish", qPrintable(serial_port.portName()),written_data.data());
        written_bytes = 0;
        emit on_write_finished(this);
    }
}

void Demo_Serial_Port::handleError(QSerialPort::SerialPortError error)
{
    qCritical("<%s> err<%d>:%s", qPrintable(serial_port.portName()),error, qPrintable(serial_port.errorString()) );
}

QT官方实例:

参考【 https://doc.qt.io/qt-5/qtserialport-examples.html 】,里面有大量实例,进入入口如下:

Leave a Reply

3 × 2 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

Theme by Anders Norén

苏ICP备16032087号