Qt中串口模块的使用

串口模块介绍

1、简介

在Qt的拓展模块中,Qt提供了许多的结果通讯模块,有串口、can、 ModBus等。下面就简单介绍一些Qt中的串口模块。

Qt串口提供基本功能,包括配置、I/O操作、获取和设置RS-232引脚的控制信号。

Qt串口模块不支持以下功能:

  • 终端功能,如回声、控制CR/LF等。

  • 文本模式。

  • 配置读取或写入时的超时和延迟。

  • 引脚输出信号更改通知。

  • 特殊收发器条件,如帧错误、奇偶校验错误和中断条件错误。

2、包含类

在Qt串口模块中主要使用的类有两个:

QSerialPort 提供访问串行端口的功能
QSerialPortInfo 提供有关现有串行端口的信息

串口模块使用

串口的使用步骤如下:

1、在项目中引入串口模块

cpp 复制代码
QT += serialport

2、添加串口类相关头文件

#include <QSerialPort>
cpp 复制代码
#include <QSerialPortInfo>

3、使用QSerialPortInfo中的静态文件获取设备中的串口信息。availablePorts()函数返回的是一个串口信息的列表。

cpp 复制代码
    foreach(const QSerialPortInfo &Info, QSerialPortInfo::availablePorts()) { //读取串口信息
         m_serialPort->setPort(Info);
         if( m_serialPort->open(QIODevice::ReadWrite) ) {
             portnames.append(Info.portName());
             m_serialPort->close();
         }
     }

4、创建一个QSerialPort类对象,使用通过availablePorts()函数获取的串口信息,设置需要打开的串口号、波特率、校验位等一些串口信息。设置的函数如下:

bool setBaudRate(qint32 baudRate , QSerialPort::Directions directions = AllDirections) 设置波特率
bool setBreakEnabled(bool set = true)
bool setDataBits(QSerialPort::DataBits dataBits) 设置数据位
bool setDataTerminalReady(bool set)
bool setFlowControl(QSerialPort::FlowControl flowControl) 设置流量控制模式
bool setParity(QSerialPort::Parity parity) 设置校验模式
void setPort(const QSerialPortInfo &serialPortInfo)
void setPortName(const QString &name) 设置串口号
void setReadBufferSize(qint64 size) 设置读写缓存区大小
bool setRequestToSend(bool set) 设置保持线路信号RTS的状态(高或低)
bool setStopBits(QSerialPort::StopBits stopBits) 设置停止位

5、设置完各种参数之后就可以打开串口了,打开串口使用serialPort类中的open函数。此函数需要传入一个权限控制:读、写、读写等。

cpp 复制代码
bool MySerialPort::openSeriaPort(QSerialPort::OpenMode openmode){
    return m_serialPort->open(openmode);
}

6、在Qt中使用QSerialPort::readyRead信号通知程序有数据上来。之后程序在使用readAll()函数获取缓存区中数据。

cpp 复制代码
connect(m_serialPort,&QSerialPort::readyRead,[=]()
    {
        qDebug() << "MySerialPort createSeriaPort readDate";
        readDate();
    });
cpp 复制代码
void MySerialPort::readDate(){
    QByteArray data = m_serialPort->readAll();
    emit haveReceive(data);
}

7、Qt串口模块中使用QSerialPort中的write函数写入数据,并发送。

cpp 复制代码
qint64 MySerialPort::writeDate(QByteArray data,int len){
    return m_serialPort->write(data,len);
}

至此,Qt中串口的基础使用已经完成,可以进行串口数据交互了,

例子

一下自己是一个简单的串口使用Demo。

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QTextBrowser>
#include <QLineEdit>
#include "myserialport.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    QSerialPort *serial;
    QLineEdit *fasong;
    QTextBrowser *jieshou;

    MySerialPort serialPort;



private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void on_comboBox_currentTextChanged(const QString &arg1);

    void on_comboBox_2_currentTextChanged(const QString &arg1);

    void readBytes(QByteArray data);

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
cpp 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QDebug>
#include <QSerialPort>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    qDebug() << "主窗口构造函数";

    fasong = ui->fasong;
    jieshou = ui->jieshou;
    serialPort.createSeriaPort(QSerialPort::Data8,QSerialPort::NoParity,QSerialPort::OneStop,QSerialPort::NoFlowControl);
    connect(&serialPort,&MySerialPort::haveReceive,this,&MainWindow::readBytes);

    QStringList lists = serialPort.getPortNames();
    foreach (QString str, lists) {
        ui->comboBox->addItem(str);
    }
    ui->comboBox_2->addItem("1200");
    ui->comboBox_2->addItem("2400");
    ui->comboBox_2->addItem("4800");
    ui->comboBox_2->addItem("9600");
    ui->comboBox_2->addItem("19200");

}

MainWindow::~MainWindow()
{
    delete ui;
    serialPort.closeSeriaPort();
}


void MainWindow::on_pushButton_clicked()
{
     qDebug() << "发送数据" ;

    QByteArray data = fasong->displayText().toUtf8();
    int len = data.length();

    serialPort.writeDate(data,len);    //串口发数据
}


//cpp
void MainWindow::readBytes(QByteArray data) {
    qDebug() << "接收数据" ;
    jieshou->setText(data);

}

void MainWindow::on_pushButton_2_clicked()
{
     //打开串口
     if(!serialPort.openSeriaPort(QIODevice::ReadWrite))
     {
         qDebug() << "串口打开失败" ;
     }

}

void MainWindow::on_comboBox_currentTextChanged(const QString &arg1)
{
   serialPort.setPortName(arg1);
}

void MainWindow::on_comboBox_2_currentTextChanged(const QString &arg1)
{
    //设置波特率
    serialPort.setBaudRate(arg1.toInt());
}
cpp 复制代码
/***************************************************************
* 文件名称: MySerialPort
* 文件功能: 封装qt中的串口创建
* 开发时间: 
* 开发人:  
***************************************************************/


#ifndef MYSERIALPORT_H
#define MYSERIALPORT_H

#include <QSerialPort>
#include <QSerialPortInfo>
#include <QObject>
class MySerialPort : public QObject
{
    Q_OBJECT

public:
    /**
     * @brief MySerialPort 构造函数,没有具体意义
     * @param parent
     */
    MySerialPort(QObject *parent = nullptr);
    /**
     * @brief ~MySerialPort 析构函数,用于释放new 的串口实例
     */
    virtual ~MySerialPort();
    /**
     * @brief createSeriaPort 用于创建串口对象
     * @param dataBits   数据位数
     * @param parity     奇偶校验
     * @param stopBits   停止位数
     * @param flowControl 流量控制
     * @return
     */
    bool createSeriaPort(QSerialPort::DataBits dataBits,QSerialPort::Parity parity,QSerialPort::StopBits stopBits,QSerialPort::FlowControl flowControl);
    /**
     * @brief readDate 读取数据,此函数会发送一个带参数的信号
     */
    void readDate();
    /**
     * @brief writeDate 发送数据
     * @param data      想要发送的数据
     * @param len       想要发送数据的长度
     * @return          是否发送成功
     */
    qint64 writeDate(QByteArray data,int len);
    /**
     * @brief setPortName 设置端口号
     * @param portName    端口号
     */
    void setPortName(QString portName);
    /**
     * @brief setBaudRate 设置波特率
     * @param baudRate    波特率
     * @return
     */
    bool setBaudRate(int baudRate);
    /**
     * @brief getPortNames  获取当前系统中可用的串口
     * @return              返回值为一个字符串列表
     */
    QStringList getPortNames();
    /**
     * @brief openSeriaPort 打开串口
     * @param openmode      打开串口模式
     * @return
     */
    bool openSeriaPort(QSerialPort::OpenMode openmode);
    /**
     * @brief closeSeriaPort 关闭串口
     */
    void closeSeriaPort();

signals:
    /**
     * @brief haveReceive 向外部发送接收串口数据的函数
     * @param data
     */
    void haveReceive(QByteArray data);


private:
    QSerialPort * m_serialPort = nullptr;
};

#endif // MYSERIALPORT_H
cpp 复制代码
#include "myserialport.h"
#include <QDebug>
MySerialPort::MySerialPort(QObject *parent):QObject(parent)
{
}
MySerialPort::~MySerialPort(){
    if(m_serialPort != nullptr){
        delete m_serialPort;
    }
}
bool MySerialPort::createSeriaPort(QSerialPort::DataBits dataBits,QSerialPort::Parity parity,QSerialPort::StopBits stopBits,QSerialPort::FlowControl flowControl){
    qDebug() << "MySerialPort createSeriaPort";
    m_serialPort = new QSerialPort();
    m_serialPort->setDataBits(dataBits);
    m_serialPort->setParity(parity);
    m_serialPort->setStopBits(stopBits);
    m_serialPort->setFlowControl(flowControl);
    connect(m_serialPort,&QSerialPort::readyRead,[=]()
    {
        qDebug() << "MySerialPort createSeriaPort readDate";
        readDate();
    });
    return true;
}

void MySerialPort::readDate(){
    QByteArray data = m_serialPort->readAll();
    emit haveReceive(data);
}

qint64 MySerialPort::writeDate(QByteArray data,int len){
    return m_serialPort->write(data,len);
}

void MySerialPort::setPortName(QString portName){
    m_serialPort->setPortName(portName);
}

bool MySerialPort::setBaudRate(int baudRate){
  return  m_serialPort->setBaudRate(baudRate);
}

QStringList MySerialPort::getPortNames(){
    QStringList portnames;
    if(m_serialPort == nullptr){
        return  portnames;
    }
    foreach(const QSerialPortInfo &Info, QSerialPortInfo::availablePorts()) { //读取串口信息
         m_serialPort->setPort(Info);
         if( m_serialPort->open(QIODevice::ReadWrite) ) {
             portnames.append(Info.portName());
             m_serialPort->close();
         }
     }
    return portnames;
}

bool MySerialPort::openSeriaPort(QSerialPort::OpenMode openmode){
    return m_serialPort->open(openmode);
}

void MySerialPort::closeSeriaPort(){
     m_serialPort->close();
}
相关推荐
qystca26 分钟前
洛谷 B3637 最长上升子序列 C语言 记忆化搜索->‘正序‘dp
c语言·开发语言·算法
薯条不要番茄酱27 分钟前
数据结构-8.Java. 七大排序算法(中篇)
java·开发语言·数据结构·后端·算法·排序算法·intellij-idea
今天吃饺子32 分钟前
2024年SCI一区最新改进优化算法——四参数自适应生长优化器,MATLAB代码免费获取...
开发语言·算法·matlab
努力进修36 分钟前
“探索Java List的无限可能:从基础到高级应用“
java·开发语言·list
Ajiang28247353043 小时前
对于C++中stack和queue的认识以及priority_queue的模拟实现
开发语言·c++
幽兰的天空3 小时前
Python 中的模式匹配:深入了解 match 语句
开发语言·python
Theodore_10226 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
----云烟----8 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024068 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
开心工作室_kaic8 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端