【QT5】<重点> QT串口编程

news2024/12/23 23:51:37

目录

前言

一、串口编程步骤

0. 添加串口模块

1. 自动搜索已连接的串口

2. 创建串口对象

3. 初始化串口

4. 打开串口

5. 关闭串口

6. 发送数据

7. 接收数据

二、简易串口助手

1. 实现效果

2. 程序源码

3. 实现效果二


前言

本篇记录QT串口编程相关内容,并制作一个串口助手来巩固理论知识。


一、串口编程步骤

0. 添加串口模块

pro文件中QT += serialport

1. 自动搜索已连接的串口

假设我们已经在ui设计器里添加了一个QComboBox的对象cbSerialPort。接下来,我们通过以下代码将所有已连接的串口名称加入cbSerialPort中,方便用户选择。

//QSerialPortInfo::availablePorts()能够自动搜索已连接的串口
//需要添加头文件<QSerialPortInfo>
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
   ui->cbSerialPort->addItem(info.portName());
}

2. 创建串口对象

//需要添加头文件<QSerialPort>
QSerialPort * serialport = new QSerialPort(this);

3. 初始化串口

【1】初始化串口名:

serialPort->setPortName(ui->cbSerialPort->currentText());

【2】初始化波特率:

QSerialPort::BaudRate baudRate;
if (ui->cbBaudRate->currentText() == "4800") {
    baudRate = QSerialPort::Baud4800;
} else if (ui->cbBaudRate->currentText() == "9600") {
    baudRate = QSerialPort::Baud9600;
} else if (ui->cbBaudRate->currentText() == "115200") {
    baudRate = QSerialPort::Baud115200;
}
serialPort->setBaudRate(baudRate);

【3】初始化数据位:

QSerialPort::DataBits dataBits;
if (ui->cbDataBit->currentText() == "5") {
    dataBits = QSerialPort::Data5;
} else if (ui->cbDataBit->currentText() == "6") {
    dataBits = QSerialPort::Data6;
} else if (ui->cbDataBit->currentText() == "7") {
    dataBits = QSerialPort::Data7;
} else if (ui->cbDataBit->currentText() == "8") {
    dataBits = QSerialPort::Data8;
}
serialPort->setDataBits(dataBits);

【4】初始化停止位:

QSerialPort::StopBits stopBits;
if (ui->cbStopBit->currentText() == "1") {
    stopBits = QSerialPort::OneStop;
} else if (ui->cbStopBit->currentText() == "1.5") {
    stopBits = QSerialPort::OneAndHalfStop;
} else if (ui->cbStopBit->currentText() == "2") {
    stopBits = QSerialPort::TwoStop;
}
serialPort->setStopBits(stopBits);

【5】初始化校验位:

QSerialPort::Parity parity;
if (ui->cbCheckBit->currentText() == "none") {
    parity = QSerialPort::NoParity;
}
serialPort->setParity(parity);

4. 打开串口

//弹出一个窗口告知用户初始化结果
if (serialPort->open(QIODevice::ReadWrite)) {
    QMessageBox::information(this, "提示", "成功");
} else {
    QMessageBox::critical(this, "提示", "失败");
}

5. 关闭串口

serialPort->close();

6. 发送数据

serialPort->write(ui->sendEdit->text().toUtf8());

7. 接收数据

【1】建立信号槽,当有数据发送过来时,调用自定义的槽函数receiveMessage()

connect(serialPort, SIGNAL(readyRead()), this, SLOT(receiveMessage()));

【2】实现槽函数receiveMessage()

void Widget::receiveMessage()
{
    QString buf = serialPort->readAll();
    ui->recvEdit->appendPlainText(buf);
}

二、简易串口助手

1. 实现效果

此QT程序在Windows环境下编译运行,且连接IMX6ULL开发板(串口号为12)。IMX6ULL开发板收到信息后会自动发回接收到的信息。因此,本程序的实现效果如下图所示:

2. 程序源码

【1】widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QSerialPort>
#include <QSerialPortInfo>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_btnOpenSerial_clicked();

    void on_btnCloseSerial_clicked();

    void receiveMessage();

    void on_btnSendMesg_clicked();

    void on_btnClearRecv_clicked();

    void on_btnClearSend_clicked();

private:
    Ui::Widget *ui;
    QSerialPort *serialPort;
};
#endif // WIDGET_H

【2】widget.cpp:

#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>

/***********************************************************
  * @函数: Widget
  * @功能: 构造函数
  * @参数: parent---父对象
  * @返回: 无
  *********************************************************/
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //搜索连接的串口,将名称加入cbSerialPort中
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        ui->cbSerialPort->addItem(info.portName());
    }
    //创建串口对象
    serialPort = new QSerialPort(this);
    //信号槽:串口接收数据
    connect(serialPort, SIGNAL(readyRead()), this, SLOT(receiveMessage()));
    //设置"打开串口"与"关闭串口"按钮互斥
    ui->btnOpenSerial->setEnabled(true);
    ui->btnCloseSerial->setEnabled(false);
}


/***********************************************************
  * @函数: ~Widget
  * @功能: 析构函数
  * @参数: 无
  * @返回: 无
  *********************************************************/
Widget::~Widget()
{
    delete ui;
}


/***********************************************************
  * @函数: on_btnOpenSerial_clicked
  * @功能: “打开串口”按钮的槽函数,初始化串口
  * @参数: 无
  * @返回: 无
  *********************************************************/
void Widget::on_btnOpenSerial_clicked()
{
    //初始化串口名
    serialPort->setPortName(ui->cbSerialPort->currentText());
    //初始化波特率
    QSerialPort::BaudRate baudRate;
    if (ui->cbBaudRate->currentText() == "4800") {
        baudRate = QSerialPort::Baud4800;
    } else if (ui->cbBaudRate->currentText() == "9600") {
        baudRate = QSerialPort::Baud9600;
    } else {
        baudRate = QSerialPort::Baud115200;
    }
    serialPort->setBaudRate(baudRate);
    //初始化数据位
    QSerialPort::DataBits dataBits;
    if (ui->cbDataBit->currentText() == "5") {
        dataBits = QSerialPort::Data5;
    } else if (ui->cbDataBit->currentText() == "6") {
        dataBits = QSerialPort::Data6;
    } else if (ui->cbDataBit->currentText() == "7") {
        dataBits = QSerialPort::Data7;
    } else {
        dataBits = QSerialPort::Data8;
    }
    serialPort->setDataBits(dataBits);
    //初始化停止位
    QSerialPort::StopBits stopBits;
    if (ui->cbStopBit->currentText() == "1") {
        stopBits = QSerialPort::OneStop;
    } else if (ui->cbStopBit->currentText() == "1.5") {
        stopBits = QSerialPort::OneAndHalfStop;
    } else {
        stopBits = QSerialPort::TwoStop;
    }
    serialPort->setStopBits(stopBits);
    //初始化校验位
    QSerialPort::Parity parity;
    if (ui->cbCheckBit->currentText() == "none") {
        parity = QSerialPort::NoParity;
    }
    serialPort->setParity(parity);
    //弹出一个窗口告知用户初始化结果
    if (serialPort->open(QIODevice::ReadWrite)) {
        QMessageBox::information(this, "提示", "串口打开成功");
        //设置"打开串口"与"关闭串口"按钮互斥
        ui->btnOpenSerial->setEnabled(false);
        ui->btnCloseSerial->setEnabled(true);
    } else {
        QMessageBox::critical(this, "提示", "串口打开失败");
    }
}


/***********************************************************
  * @函数: on_btnCloseSerial_clicked
  * @功能: “关闭串口”按钮的槽函数
  * @参数: 无
  * @返回: 无
  *********************************************************/
void Widget::on_btnCloseSerial_clicked()
{
    serialPort->close();
    //设置"打开串口"与"关闭串口"按钮互斥
    ui->btnOpenSerial->setEnabled(true);
    ui->btnCloseSerial->setEnabled(false);
}


/***********************************************************
  * @函数: receiveMessage
  * @功能: 槽函数:接收信息
  * @参数: 无
  * @返回: 无
  *********************************************************/
void Widget::receiveMessage()
{
    QString buf = serialPort->readAll();
    ui->recvEdit->appendPlainText(buf);
}


/***********************************************************
  * @函数: on_btnSendMesg_clicked
  * @功能: “发送信息”按钮的槽函数
  * @参数: 无
  * @返回: 无
  *********************************************************/
void Widget::on_btnSendMesg_clicked()
{
    serialPort->write(ui->sendEdit->text().toUtf8());
}


/***********************************************************
  * @函数: on_btnClearRecv_clicked
  * @功能: “清除接收框”按钮的槽函数
  * @参数: 无
  * @返回: 无
  *********************************************************/
void Widget::on_btnClearRecv_clicked()
{
    ui->recvEdit->clear();
}


/***********************************************************
  * @函数: on_btnClearSend_clicked
  * @功能: “清除输入框”按钮的槽函数
  * @参数: 无
  * @返回: 无
  *********************************************************/
void Widget::on_btnClearSend_clicked()
{
    ui->sendEdit->clear();
}

3. 实现效果二

【1】为了进一步验证简易串口助手的功能,我们进行了如下的实验。

【2】首先,根据视频【虚拟串口创建工具】虚拟串口软件安装教程_哔哩哔哩_bilibili,我们安装了虚拟串口软件,并且产生了两个虚拟串口,如下图所示:

【3】其次,我们开发的串口助手连接com2,另一个串口工具连接com1。如下图所示,它们能够正常地收发数据,这再一次说明了我们开发的串口助手功能是正常的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1829835.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

半导体芯片结构以及译码驱动

一.半导体芯片结构 可能并不是只有一个芯片&#xff0c;有多个芯片就需要片选线了。 二.半导体存储芯片的译码驱动 主要有两种方式&#xff1a;线选法和重合法 线选法&#xff1a;每一个存储单元都用一根字选择线选中&#xff0c;直接选中存储单元的各位。&#xff08;一维…

Codeforces Round 953 (Div. 2)(A~D题解)

这次比赛是我最顺利的一次比赛&#xff0c;也是成功在中途打进前1500&#xff0c;写完第三道题的时候也是保持在1600左右&#xff0c;但是后面就啥都不会了&#xff0c;还吃了点罚时&#xff0c;虽说如此也算是看到进步了&#xff0c;D题学长说很简单&#xff0c;但是我当时分析…

增强大型语言模型(LLM)可访问性:深入探究在单块AMD GPU上通过QLoRA微调Llama 2的过程

Enhancing LLM Accessibility: A Deep Dive into QLoRA Through Fine-tuning Llama 2 on a single AMD GPU — ROCm Blogs 基于之前的博客《使用LoRA微调Llama 2》的内容&#xff0c;我们深入研究了一种称为量化低秩调整&#xff08;QLoRA&#xff09;的参数高效微调&#xff0…

非常好用的7个Vue3组件库!!【送源码】

说到Vue&#xff0c;怎能不提Vue3呢&#xff1f; 它的大名鼎鼎主要归功于一项革命性的创新——Composition API。 这个新功能为逻辑复用带来了前所未有的友好性和灵活性&#xff0c;让开发者们在构建应用时如鱼得水。 如果你现在正在使用Vue3&#xff0c;或者在新的一年考虑…

reflutter工具实践之--xx一番赏app

此文章已经录制b站视频&#xff1a; flutter逆向案例-某某一番赏_哔哩哔哩_bilibili 一、工具介绍--reFlutter 这个框架帮助 Flutter 应用逆向工程&#xff0c;使用 Flutter 库的补丁版本&#xff0c;该版本已经编译并准备好重新打包应用。此库修改了快照反序列化过程&#…

SpringCloudNetflix组件整合

SpringCloudNetflix组件整合 Eureka注册中心 Eureka是什么 Eureka是netflix的一个子模块&#xff0c;也是核心模块之一&#xff0c;Eureka是一个基于REST的服务&#xff0c;用于定位服务&#xff0c;以实现云端中间层服务发现和故障转移。服务注册与发现对于微服务架构来说是…

“Dream Machine“震撼登场!免费推出的AI电影级巨制在网络上引爆热潮

"巅峰初现&#xff01;视频AI新星‘梦幻制造者’华美登场&#xff01; 在视频生成技术的赛道上&#xff0c;Luma AI昨日骄傲地揭开了其旗舰创新——梦幻制造者&#xff08;Dream Machine&#xff09;的神秘面纱&#xff0c;凭借无与伦比的文本到视频及图像到视频转换技术…

Cyber Weekly #11

赛博新闻 1、苹果召开2024年WWDC开发者大会 本周二&#xff08;6月11日&#xff09;凌晨1点&#xff0c;苹果召开2024年全球开发者大会&#xff0c;宣布与OpenAl合作&#xff0c;在iOS18、iPadOS18和macOS Sequoia中全面支持GPT-4o。用户在询问Siri问题时&#xff0c;Siri可以…

Oracle 入门--前提

目录 1.sqlplus 2.dual是什么&#xff1f; 3.SQL语句的种类 4.Oracle是如何工作的 5.Oracle查看配置文件 6.修改配置文件 7.常用的参数设置 1.sqlplus 管理数据库&#xff1a;启动&#xff0c;关闭&#xff0c;创建&#xff0c;删除对象......查看数据库的运行状态&…

01 - matlab m_map地学绘图工具基础函数理解(一)

01 - matlab m_map地学绘图工具基础函数理解&#xff08;一&#xff09; 0. 引言1. m_demo2. 小结 0. 引言 上篇介绍了m_map的配置过程&#xff0c;本篇开始介绍下m_map中涉及到的所有可调用函数。如果配置的没有问题&#xff0c;执行">>help m_map"可以看到类…

戴尔第十一代十二代十三代处理器重装系统找不到驱动程序

一、戴尔第十一代十二代十三代处理器重装系统找不到驱动程序 VMD&#xff08;Volume Management Device&#xff09;是针对下一代存储推出的部署方案。这套方案支持从 PCIe 总线对 NVMe 固态盘进行热升级和更换&#xff0c;而无需关闭系统&#xff0c;同时标准化 LED 管理可帮助…

云计算【第一阶段(14)】Linux的目录和结构

一、Liunx目录结构 1.1、linux目录结构 linux目录结构是树形目录结构 根目录&#xff08;树根&#xff09; 所有分区&#xff0c;目录&#xff0c;文件等的位置起点整个树形目录结构中&#xff0c;使用独立的一个"/",表示 1.2、常见的子目录 必须知道 目录路径目…

UniRx 入门

Reactive X 是 Reactive Extensions 的缩写&#xff0c;一般简写为 Rx&#xff0c;最初是 LINQ 的一个扩展&#xff0c;由微软的团队开发&#xff0c;Rx 是一个编程模型&#xff0c;目标是提供一致的编程接口&#xff0c;帮助开发者更方便的处理异步数据流&#xff0c;支持大部…

Apipost模拟HTTP客户端

模拟HTTP客户端的软件有很多&#xff0c;其中比较著名的就有API-FOX、POSTMAN。 相信很多小伙伴都使用POSTMAN。这篇博客主要介绍Apipost的原因是&#xff0c;Apipost无需下载&#xff0c;具有网页版。 APIFOX的站内下载&#xff1a; Api-Fox&#xff0c;类似于PostMan的软件…

关于HTTP劫持,该如何理解、防范和应对

一、引言 HTTP劫持&#xff08;HTTP Hijacking&#xff09;是一种网络安全威胁&#xff0c;它发生在HTTP通信过程中&#xff0c;攻击者试图通过拦截、篡改或监控用户与服务器之间的数据流量&#xff0c;以达到窃取敏感信息或执行恶意操作的目的。今天我们就来详细了解HTTP劫持…

嵌入式实训day5

1、 from machine import Pin import time # 定义按键引脚控制对象 key1 Pin(27,Pin.IN, Pin.PULL UP) key2 Pin(26,Pin.IN, Pin.PULL UP)led1 Pin(15,Pin.ouT, value0) led2 Pin(2,Pin.ouT, value0) led3 Pin(0,Pin.ouT, value0) # 定义key1按键中断处理函数 def key1 ir…

JavaFX 图像视图

JavaFX ImageView 控件可以在 JavaFX GUI 中显示图像。ImageView 控件必须添加到场景图中才能可见。JavaFX ImageView 控件由类表示 javafx.scene.image.ImageView。 创建一个 ImageView 通过创建类的实例来创建 ImageView 控件实例ImageView。类的构造函数ImageView需要一个…

【JKI SMO】框架讲解(二)

JKI State Machine 讲解 将JKI State Machine 模板拖曳到程序框图中&#xff0c; 如下图&#xff0c; 此模板会默认放置一个OK按钮在前面板中&#xff0c;用于提示用户如何增加一个简单的用户事件去使用此框架。 “Event Structure”&#xff0c;Idle&#xff1a;此分支可以设…

---异常---

我们在运行程序时总遇到各种与报错&#xff0c;数组越界&#xff0c;空指针的引用&#xff0c;这些在java中都称为异常 对于不同的错误都具有一个与他对应的异常类来秒描述 这是对于数组越界这个类里有的方法&#xff0c;这些是描述异常的 在java中有一个完整的描述异常的类的…

JavaFX 节点

JavaFX Node类javafx.scene.Node是添加到JavaFX 场景图的所有组件 的基类&#xff08;超类&#xff09; 。JavaFX Node 类是抽象的&#xff0c;因此你只需将 Node 类的子类添加到场景图中。场景图中的所有 JavaFX Node 实例共享一组由 JavaFX Node 类定义的公共属性。本 JavaFX…