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();
}
相关推荐
重生之我在20年代敲代码37 分钟前
strncpy函数的使用和模拟实现
c语言·开发语言·c++·经验分享·笔记
爱上语文38 分钟前
Springboot的三层架构
java·开发语言·spring boot·后端·spring
编程零零七3 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
2401_858286114 小时前
52.【C语言】 字符函数和字符串函数(strcat函数)
c语言·开发语言
铁松溜达py4 小时前
编译器/工具链环境:GCC vs LLVM/Clang,MSVCRT vs UCRT
开发语言·网络
everyStudy4 小时前
JavaScript如何判断输入的是空格
开发语言·javascript·ecmascript
C-SDN花园GGbond5 小时前
【探索数据结构与算法】插入排序:原理、实现与分析(图文详解)
c语言·开发语言·数据结构·排序算法
迷迭所归处6 小时前
C++ —— 关于vector
开发语言·c++·算法
架构文摘JGWZ7 小时前
Java 23 的12 个新特性!!
java·开发语言·学习
leon6257 小时前
优化算法(一)—遗传算法(Genetic Algorithm)附MATLAB程序
开发语言·算法·matlab