【QT5】<知识点> QT串口编程

embedded/2024/10/18 16:48:10/

目录

前言

一、串口编程步骤

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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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.ppmy.cn/embedded/48563.html

相关文章

AI Stable diffusion 报错:稳定扩散模型加载失败,退出

可能是内存不够&#xff0c;看看你最近是加了新的大的模型&#xff0c;可以把你的stable-diffusion-webui\models\Stable-diffusion目录下的某个ckpt删除掉&#xff0c;可能ckpt太大&#xff0c;无法加载成功&#xff1b; Stable diffusion model failed to load, exiting 如图…

基于LangChain-Chatchat实现的RAG-本地知识库的问答应用[1]-最新版快速实践并部署(检索增强生成RAG大模型)

基于LangChain-Chatchat实现的RAG-本地知识库的问答应用[1]-最新版快速实践并部署(检索增强生成RAG大模型) 基于 ChatGLM 等大语言模型与 Langchain 等应用框架实现,开源、可离线部署的检索增强生成(RAG)大模型知识库项目。 1.介绍 一种利用 langchain思想实现的基于本地知…

Frontier疑遭网络风暴:RansomHub组织公开勒索超过200万用户数据

在数字世界的阴影中&#xff0c;一个名为RansomHub的组织悄然崛起&#xff0c;因几起数据泄露事件而备受关注&#xff0c;最近&#xff0c;这个神秘组织宣称他们已经掌握了电信巨头Frontier超过200万的数据信息&#xff0c;这无疑在原本就波谲云诡的网络安全领域投下了一颗重磅…

计算机网络 | 第一章 认识计算机网络 | 王道考研笔记自用

1. 认识计算机网络 1.1 计算机网络的定义与分类 1.1.1 计算机网络的定义 计算机网络是一个将众多分散的、自治的计算机系统&#xff0c;通过通信设备与线路连接起来&#xff0c;由功能完善的软件实现资源共享和信息传递的系统。 图1-1 计算机网络示意图 计算机网络&#xff…

从零开始利用树莓派+扬声器,实现简单的蓝牙音箱,手机连接放歌

背景 树莓派4B自带蓝牙和Wifi, 无需外接 USB dongle; 蓝牙最常见的应用是近距离传输数据,比如蓝牙传文件,蓝牙音箱等。正好家里有个普通的usb供电的便携音箱; 本文用树莓派蓝牙+普通音箱,实现简单的蓝牙音箱。 大致分为三个部分: kernel/driver层的ALSA驱动框架蓝牙音…

Java基础面试重点-3

41. 简述线程生命周期(状态) 其它参考《多线程重点》中的说法。三种阻塞&#xff1a; 等待阻塞&#xff1a; 运行的线程执行o.wait()方法&#xff08;该线程已经持有锁&#xff09;&#xff0c;JVM会把该线程放入等待队列中。同步阻塞&#xff1a; 运行的线程在获取对象的同步…

k8s_DaemonSet和Deployment区别

DaemonSet和Deployment是Kubernetes中两种不同的控制器,用于管理Pod的部署和生命周期。它们的主要区别在于它们的用途、行为和管理方式。以下是对DaemonSet和Deployment的详细解释及其主要区别: DaemonSet 主要用途 DaemonSet确保在每个节点上运行一个Pod。它通常用于部署…

Python开源项目周排行 2024年第9周

#2024年第9周2024年6月3日1buku强大的浏览器书签管理工具。这是一款开源的书签命令行管理工具&#xff0c;它轻量、隐私安全且易于使用&#xff0c;支持从主流浏览器导入书签、自动获取书签信息、跨平台同步和强大的搜索功能。2flagsmith轻松管理功能开关和配置的平台。这是一个…