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

目录

前言

一、串口编程步骤

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.mfbz.cn/a/717727.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

早期发现,健康生活!第三届ZAODX世界肿瘤早筛大会圆满落幕!

2024年6月15日-16日&#xff0c;第三届ZAODX世界肿瘤早筛大会在雄安新区盛大开幕&#xff01;本次会议由河北雄安新区管理委员会公共服务局指导&#xff0c;第三届ZAODX世界肿瘤早筛大会组委会和早筛网主办&#xff0c;粤港澳大湾区精准医学研究院&#xff08;广州&#xff09;…

Paragon NTFS for Mac 15软件下载及安装教程

简介&#xff1a; NTFS For Mac 15是首个支持Mac上读写NTFS外置存储设备解决方案 &#xff0c;解决mac不能读写外置让您更加简单直观的在Mac机上随意对NTFS文件修改、删除等操作。 安 装 包 获 取 地 址&#xff1a; Paragon Ntfs For Mac 15版&#xff1a; ​​https://sou…

04 远程访问及控制

1、SSH远程管理 SSH是一种安全通道协议&#xff0c;主要用来实现字符界面的远程登录、远程复制等功能。 SSH协议对通信双方的数据传输进行了加密处理&#xff08;包括用户登陆时输入得用户口令&#xff09;。 终端&#xff1a;接收用户的指令 TTY终端不能远程&#xff0c;它…

《跟我一起学“网络安全”》——等保风评加固应急响应

等保风评加固应急响应 一、安全加固 背景 随着IP技术的飞速发展&#xff0c;一个组织的信息系统经常会面临内部和外部威胁的风险&#xff0c;网络安全已经成为影响信息系统的关键问题。 虽然传统的防火墙等各类安全产品能提供外围的安全防护&#xff0c;但并不能真正彻底的消…

吴恩达2022机器学习专项课程C2W3:2.26 机器学习发展历程

目录 开发机器学习系统的过程开发机器学习案例1.问题描述2.创建监督学习算法3.解决问题4.小结 误差分析1.概述2.误差分析解决之前的问题3.小结 增加数据1.简述2.增加数据案例一3.增加数据案例二4.添加数据的技巧5.空白创建数据6.小结 迁移学习1.简述2.为什么迁移学习有作用3.小…

【设计模式-12】代理模式的代码实现及使用场景

&emsp&#xff1b;代理模式是一种应用很广发的结构性设计模式&#xff0c;它的设计初衷就是通过引入新的代理对象&#xff0c;在客户端和目标对象之间起到中介的作用&#xff0c;从而实现控制客户端对目标对象的访问&#xff0c;比如增强或者阉割某些能力。 1. 概述 代理模…

如何理解电流镜负载的差分对的增益

我们知道最普通的电阻负载的差分对的差分增益是-gmRD&#xff0c;如果我们不希望输出是双端的&#xff0c;而是希望单端输出&#xff0c;那么使用电阻负载的差分对会导致增益变为原先的一半&#xff0c;因此引入了电流镜负载的差分对&#xff0c;它可以在保证增益与原先相同的情…

一小时搞定JavaScript(1)——JS基础

前言,本篇文章是依据bilibili博主(波波酱老师)的学习笔记,波波酱老师讲的很好,很适合速成!!! 文章目录 1.基本语法1.1 JS语言的特点1.2 创建一个JS文件1.3 输入与输出1.4 变量1.4.1 命名规则1.4.2 变量声明数字类型字符串类型布尔类型未定义类型 1.4.3 类型转换隐式转换显示转…

数据可视化实验一:Panda数据处理及matplotlib绘图初步

目录​​​​​​​ 2024-6-17 一、请将所有含有发明家“吴峰”的发明专利的“申请日”打印出来。并将含有“吴峰”的所有发明专利条目保存到Excel中 1.1 代码实现 1.2 运行结果 二、读取文件创建城市、人口、性别比、城镇化率DataFrame对象&#xff0c;计算指标排名&…

嘴尚绝卤味:传统与创新的味蕾碰撞,尝鲜必备美食!

在当今的餐饮市场中&#xff0c;各式各样的美食层出不穷&#xff0c;让人目不暇接。而在这一片美食的海洋中&#xff0c;嘴尚绝卤味以其独特的魅力和口感&#xff0c;成功吸引了众多食客的目光。今天&#xff0c;就让我们一起来探索一下&#xff0c;嘴尚绝卤味究竟有何魔力&…

MongoDB~分片数据存储Chunk;其迁移原理、影响,以及避免手段

分片数据存储&#xff1a;Chunk存储 Chunk&#xff08;块&#xff09; 是 MongoDB 分片集群的一个核心概念&#xff0c;其本质上就是由一组 Document 组成的逻辑数据单元。每个 Chunk 包含一定范围片键的数据&#xff0c;互不相交且并集为全部数据。 分片集群不会记录每条数据…

Java多线程下载工具,多线程,多任务,断点续传,GUI

目录 一、题目要求 二、效果展示 三、功能实现 四、代码 一、题目要求 序号 功能名称 功能需求标识 简要描述 1 下载功能 Download 当用户输入一个下载链接后&#xff0c;能识别链接并开始多线程下载工作&#xff0c;包括线程监听、线程管理等。 2 续传功能 …

[面试题]Spring

[面试题]Java【基础】[面试题]Java【虚拟机】[面试题]Java【并发】[面试题]Java【集合】[面试题]MySQL[面试题]Maven[面试题]Spring Boot[面试题]Spring Cloud[面试题]Spring MVC[面试题]Spring[面试题]MyBatis Spring 是一个很庞大的技术体系&#xff0c;可以说包容一切&…

APP Android

APP Android 安卓源生应用程序 APP IOS-CSDN博客 05.04 06:11Testing

MySQL修改用户权限(宝塔)

在我们安装好的MySQL中&#xff0c;很可能对应某些操作时&#xff0c;不具备操作的权限&#xff0c;如下是解决这些问题的方法 我以宝塔创建数据库为例&#xff0c;创建完成后&#xff0c;以创建的用户名和密码登录 这里宝塔中容易发生问题的地方&#xff0c;登录不上去&#…

电离层对流层延迟解算

前言&#xff1a; 本章节代码均在Gitee中开源&#xff1a; 电离层对流层延迟解算https://gitee.com/Ehundred/navigation-engineering/tree/master/%E5%8D%AB%E6%98%9F%E5%AF%BC%E8%88%AA%E5%8E%9F%E7%90%86/%E7%94%B5%E7%A6%BB%E5%B1%82%E5%AF%B9%E6%B5%81%E5%B1%82%E8%AF%A…

Python学习笔记12:进阶篇(一),类的相关知识

前言 在讲类之前&#xff0c;我们简单介绍一些Python的知识。这些知识在入门篇没讲&#xff0c;想学Python的&#xff0c;基本都对Python有基础的了解&#xff0c;但是今天开始的进阶知识&#xff0c;会涉及到一些Python的特性&#xff0c;所以在这里介绍一下。 Python是一种高…

数据仓库与数据挖掘(期末复习)

数据仓库与数据挖掘&#xff08;期末复习&#xff09; ETL的含义Extract 、 Transformation、Load。 ODS的全称Operational Data Store。 DW全称 Data Warehourse DM全称是Data Mart 数据仓库数据抽取时所用到技术是增量、全量、定时、调度 STAGE层作用是提供业务系统数据…

HTC手机卷土重来,价格和配置给我看麻了

第一眼看到我是不敢相信的&#xff0c;HTC 竟然还活着。 提到 HTC&#xff0c;相信不少同学会发出「那是我在夕阳下奔跑并逝去的青春」这样的感叹吧。 曾经辉煌一时的手机大佬&#xff0c;市占率曾一度达到 15%。 璀璨就如同天边一闪而过的流星。关于它的风光地位&#xff0c;…

FinalShell 连接虚拟机超时,主机ping不通虚拟机,解决

出现问题&#xff1a; 连接主机...java.net.ConnectException: Connection timed out: connect 在排查错误时发现&#xff1a; 虚拟机内能互相ping通&#xff0c;虚拟机能ping通主机 但是主机的cmd命令ping不通虚拟机 问题原因&#xff1a; 虚拟机内能互相ping通&#xff0…