当前位置: 首页 > news >正文

Qt QSerialPort串口编程

文章目录

    • `Qt QSerialPort`串口编程
    • Qt Serial Port模块简述
      • 1.QSerialPortInfo类
        • 1.1示例用法
      • 2.QSerialPort类
        • 2.1设置串口参数
        • 2.2打开串口
        • 2.3数据读写
        • 2.4关闭串口
      • 3.串口编程基本流程
        • 3.1 简单实例

Qt QSerialPort串口编程

Qt 框架的Qt Serial Port 模块提供了访问串口的基本功能,包括串口通信参数配置和数据读写,使用 Qt Serial Port 模块就可以很方便地编写具有串口通信功能的应用程序。

Qt Serial Port模块简述

Qt Serial Port 模块用于串口通信编程,要在一个项目中使用 Qt Serial Port 模块,需要在项目配置文件中加入一行语句:QT += serialport
Qt Serial Port 模块中只包含有两个类:QSerialPortInfo QSerialPort

1.QSerialPortInfo类

QSerialPortInfo 类有两个静态函数可以用于获取系统中可用的串口列表,以及系统支持的串口通信波特率列表,这两个静态函数定义如下:
QList<QSerialPortInfo> QSerialPortInfo::availablePorts() //获取系统中的串口列表
QList<qint32> QSerialPortInfo::standardBaudRates() //获取目标平台支持的可用标准波特率列表
静态函数 availablePorts()返回一个 QSerialPortInfo对象的列表,列表中的每个 QSerialPortInfo对象代表一个串行端口,可以查询端口名称、系统位置、描述、制造商以及一些其他的硬件信息。QSerialPortInfo类也可以用作QSerialPort类的setPort()方法的输入参数。

1.1示例用法

示例代码枚举所有可用的串行端口,并将其参数打印到控制台:

 const auto serialPortInfos = QSerialPortInfo::availablePorts();for (const QSerialPortInfo &portInfo : serialPortInfos) {qDebug() << "\n"<< "Port:" << portInfo.portName() << "\n"<< "Location:" << portInfo.systemLocation() << "\n"<< "Description:" << portInfo.description() << "\n"<< "Manufacturer:" << portInfo.manufacturer() << "\n"<< "Serial number:" << portInfo.serialNumber() << "\n"<< "Vendor Identifier:"<< (portInfo.hasVendorIdentifier()? QByteArray::number(portInfo.vendorIdentifier(), 16): QByteArray()) << "\n"<< "Product Identifier:"<< (portInfo.hasProductIdentifier()? QByteArray::number(portInfo.productIdentifier(), 16): QByteArray());}

2.QSerialPort类

QSerialPort是QT框架提供的一个用来操作串口设备接口的类,它封装了操作系统底层实现的串口API,同时提供了事件处理机制和信号槽机制,可以方便地读写串口数据和处理串口事件。QSerialPort 的父类是 QIODevice,所以它属于 I/O 设备类。

2.1设置串口参数

串口通信参数有波特率、数据位个数、停止位个数、奇偶校验位、流控制等,QSerialPort 类有如下几个函数用于设置和返回串口通信参数。
bool setBaudRate(qint32 baudRate, QSerialPort::Directions directions = AllDirections) //设置波特率
qint32 baudRate(QSerialPort::Directions directions = AllDirections)//获取波特率
bool setDataBits(QSerialPort::DataBits dataBits)//设置数据位个数
QSerialPort::DataBits dataBits() //获取数据位个数
bool setStopBits(QSerialPort::StopBits stopBits)//设置停止位个数
QSerialPort::StopBits stopBits() //获取停止位个数
bool setParity(QSerialPort::Parity parity)//设置奇偶校验
QSerialPort::Parity parity() //获取奇偶校验

bool setFlowControl(QSerialPort::FlowControl flowCongrol) //设置流控制
QSerialPort::FlowControl flowCongrol() //获取流控制

串口波特率枚举类型QSerialPort::BaudRate,下面列出了最常用的串口波特率

常量 值 描述 QSerialPort::Baud1200 1200 1200 baud. QSerialPort::Baud2400 2400 2400 baud. QSerialPort::Baud4800 4800 4800 baud. QSerialPort::Baud9600 9600 9600 baud. QSerialPort::Baud19200 19200 19200 baud. QSerialPort::Baud38400 38400 38400 baud. QSerialPort::Baud57600 57600 57600 baud. QSerialPort::Baud115200 115200 115200 baud.

数据位枚举类型QSerialPort::DataBits

奇偶校验位枚举类型QSerialPort::Parity ,有以下几种枚举常量。
QSerialPort::NoParity,对应数值 0,无校验位。
QSerialPort::EvenParity,对应数值 2,偶校验。
QSerialPort::OddParity,对应数值 3,奇校验

QSerialPort::SpaceParity,对应数值 4,偶校验。

QSerialPort:MarkParity,对应数值 5,奇校验。

停止位枚举类型 QSerialPort::StopBits ,有以下几种枚举常量。
QSerialPort::OneStop,对应数值 1,表示一个停止位。 QSerialPort::TwoStop,对应数值 2,表示两个停止位。 QSerialPort::OneAndHalfStop,对应数值 3,表示 1.5 个停止位。
串口通信参数一般是 8 个数据位,1 个停止位,无奇偶校验位。打开串口之前需要设置好这些串口通信参数。

void setPort(const QSerialPortInfo &serialPortInfo) //设置串口
void setPortName(const QString &name) //设置串口名称

2.2打开串口

设置串口通信参数后,就可以打开串口进行数据读写。

bool open(QIODeviceBase::OpenMode mode) //打开串口

2.3数据读写

打开一个串口后,就可以使用 QSerialPort 的各种读写函数来读写串口的数据。串口数据读写有阻塞式和非阻塞式两种方式,非阻塞式又被称为异步方式。在 GUI 程序里一般使用异步方式,在非 GUI 程序或单独的线程里一般使用阻塞式。

异步方式读写数据相关的函数有如下这些:
qint64 bytesAvailable() //返回缓冲区中等待读取的数据字节数 QByteArray read(qint64 maxSize) //读取 maxSize 个字节的数据 QByteArray readAll() //读取缓冲区内的全部数据 bool canReadLine() //是否有可以按行读取的数据 //读取一行数据,最多读取 maxSize 个字节,行数据以换行符结束 QByteArray readLine(qint64 maxSize = 0) //将缓冲区的数据写入串口,最多写入 maxSize 个字节 qint64 write(const char *data, qint64 maxSize) //将缓冲区 data 的数据写入串口,以\0 结束,一般用于写字符串数据 qint64 write(const char *data) qint64 write(const QByteArray &data) //将字节数组 data 的内容写入串口
使用异步方式读写数据时,QSerialPort 有两个信号可表示缓冲区的数据变化。
void readyRead() //接收缓冲区有待读取的数据时,此信号被发射 void bytesWritten(qint64 bytes) //当发送缓冲区内的一批数据写入串口后,此信号被发射

QSerialPort 还有两个阻塞式的等待函数,定义如下:
bool waitForBytesWritten(int msecs = 30000) //最多等待 msecs ms,直到串口数据发送结束
bool waitForReadyRead(int msecs = 30000) //最多等待 msecs ms,直到串口接收到一批数据
例如,运行 waitForReadyRead()时将阻塞等待最多 30000ms,直到 QSerialPort 的接收缓冲区里有新的可以读取的数据且 readyRead()信号被发射后,函数 waitForReadyRead()才会退出,运行后续的代码。在运行 waitForReadyRead()时,应用程序的事件循环无法处理窗口事件,所以,可能会导致界面无响应的情况。所以,一般在非 GUI 程序,或独立的读写串口数据的线程里才使用这两个阻塞式函数

2.4关闭串口

不再需要进行串口通信时,要关闭串口。相关函数定义如下:

void close() //关闭串口

3.串口编程基本流程

添加模块QT += serialport;

声明变量QSerialPort *serialPort;

创建类实例 serialPort = new QSerialPort();

设置串口信息和通讯参数;

打开串口 serialPort->open(QIODevice::ReadWrite);

发送和接收数据;这里可以开线程进行数据发送和接收;

关闭串口serialPort->close()

QSerialPort()`;

设置串口信息和通讯参数;

打开串口 serialPort->open(QIODevice::ReadWrite);

发送和接收数据;这里可以开线程进行数据发送和接收;

关闭串口serialPort->close()

3.1 简单实例

以下是一个简单的例子,展示了如何使用QSerialPort类发送和接收数据。

首先,确保你的.pro文件中包含了serialport模块:

QT += serialport

然后,在你的代码中,你可以这样使用QSerialPort

#include <QSerialPort>
#include <QSerialPortInfo>// 创建一个QSerialPort对象
QSerialPort *serialPort = new QSerialPort(this);// 检测可用的串口并设置
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {if (info.description() == "YourPortName") { // 替换为你的串口名称serialPort->setPort(info);break;}
}// 设置串口参数,例如波特率、数据位、停止位和奇偶校验
serialPort->setBaudRate(QSerialPort::Baud9600);
serialPort->setDataBits(QSerialPort::Data8);
serialPort->setStopBits(QSerialPort::OneStop);
serialPort->setParity(QSerialPort::NoParity);// 打开串口
if (!serialPort->open(QIODevice::ReadWrite)) {qDebug() << "Error opening serial port";return;
}// 发送数据
serialPort->write("Hello Serial Port!\n");// 读取数据
while (serialPort->waitForReadyRead(1000)) { // 等待1秒QByteArray data = serialPort->readAll();// 处理接收到的数据qDebug() << "Received:" << data;
}// 关闭串口
serialPort->close();

确保你的硬件串口设备已经连接并且可用,替换"YourPortName"为实际的串口名称。波特率、数据位、停止位和奇偶校验参数应根据你的硬件设备进行相应设置。

这个例子展示了如何打开串口、设置串口参数、发送数据、读取数据以及关闭串口。在实际应用中,你可能需要使用信号和槽来处理数据的异步读写。

相关文章:

Qt QSerialPort串口编程

文章目录 Qt QSerialPort串口编程Qt Serial Port模块简述1.QSerialPortInfo类1.1示例用法 2.QSerialPort类2.1设置串口参数2.2打开串口2.3数据读写2.4关闭串口 3.串口编程基本流程3.1 简单实例 Qt QSerialPort串口编程 Qt 框架的Qt Serial Port 模块提供了访问串口的基本功能&…...

扫雷游戏及其中的知识点

大家好呀,今天我们给大家讲解扫雷游戏如何用C语言制作,以及制作扫雷游戏中的一些C语言知识。 想到扫雷游戏,大家有什么想法吗?大家还记得扫雷游戏是什么样子的吗?我在网上找了一些扫雷游戏的图片给大家提供参考: 如图所示,扫雷游戏需要的元素有以下几个: 1.进入游戏界面…...

【乐企-业务篇】开票前置校验服务-规则链服务接口实现(发票基础信息校验)

开票前置校验服务-规则链服务接口实现(发票基础信息校验) 代码 import liquibase.pro.packaged.L; import org.apache.commons.collections4.Collec...

【搜索算法】以扩召回为目标,item-tag不如query-tag能扩更多数量

首先ElasticSearch的召回结果已大量解决了精确召回的问题&#xff0c;扩召回主要就是增加一些推荐的搜索结果。 以item类目tag为例&#xff0c; 如果item类目体系一共20个类目&#xff0c;每个item都有一个类目&#xff0c;一共有10000个item&#xff0c;则平均每个类目tag下有…...

SpringBoot入门(黑马)

1. SpringBootWeb入门开发 需求&#xff1a;使用SpringBoot 开发一个web 应用&#xff0c;浏览器发起请求 /hello 后&#xff0c;给浏览器返回字符串"Hello World~"。 步骤&#xff1a; 1. 创建springBoot工程&#xff0c;并勾选web开发相关依赖。 2. 定义 HelloCo…...

Stream流操作

准备工作 准备 Gender 枚举类以及 Customer 类 enum Gender {MALE("男性"), FEMALE("女性");private String value;Gender() {}Gender(String value) {this.value value;}Overridepublic String toString() {return "Gender{" "value&qu…...

【Linux】查看操作系统开机时初始化的驱动模块列表的一个方法

这个方法是摸索出来的&#xff0c;也不一定对&#xff1a; 1、驱动层module_init(module_init_function)作为模块初始化&#xff0c;并且提供模块内部初始化的函数名&#xff1b; 2、找到所有驱动目录drivers下所有module_init(module_init_function)&#xff0c;在内核6.9.0…...

快速入门Vue

Vue是什么 Vue.js&#xff08;通常简称为Vue&#xff09;是一个开源的JavaScript框架&#xff0c;用于构建用户界面和单页应用程序&#xff08;SPA&#xff09;。它由尤雨溪&#xff08;Evan You&#xff09;在2014年开发并发布。Vue的核心库只关注视图层&#xff0c;易于上手…...

ubuntu系统服务器离线安装python包

一、根据工程需要本地下载所需python包 1. 下载环境requirements.txt pip freeze > requirements.txt2. 根据requirements.txt下载python包 注意&#xff1a;查看服务器属于x_86架构还是arm架构、cpython还是pypy 2.1 确定服务器架构&#xff08;终端输入&#xff09; …...

re题(30)BUUCTF-[HDCTF2019]Maze

BUUCTF在线评测 (buuoj.cn) 查一下壳&#xff0c;32位upx壳 脱完壳放到ida&#xff0c;shiftF12看一下字符串&#xff0c;是个迷宫&#xff0c;maze&#xff08;迷宫&#xff09; 这里有一个经典的花指令 (导致找不到main函数) 下方有个奇怪的jnz指令&#xff0c;它跳转到了下…...

day36+day37 0-1背包

### 9.9 01背包问题&#xff08;一维二维&#xff09; 背包问题分类&#xff1a;01背包&#xff08;一种物品只有一个&#xff09;&#xff0c;完全背包&#xff08;一种物品有无数个&#xff09;&#xff0c;多重背包&#xff08;不同物品有不同数量&#xff09; 46. 携带研究…...

PostMan使用变量

环境变量 使用场景 当测试过程中&#xff0c;我们需要对开发环境、测试环境、生产环境进行测试 不同的环境对应着不同的服务器&#xff0c;那么这个时候我们就可以使用环境变量来区分它们 避免切换测试环境后&#xff0c;需要大量的更改接口的url地址 全局变量 使用场景 当…...

多线程同步

多线程 程序中默认只有一个线程&#xff0c;pthread_create()函数调用后就有2个线程。 pthread_create() #include <pthread.h> #include <string.h> #include <unistd.h> #include <iostream> using namespace std; //线程函数 void * callback(vo…...

第159天:安全开发-Python-协议库爆破FTPSSHRedisSMTPMYSQL等

案例一: Python-文件传输爆破-ftplib 库操作 ftp 协议 开一个ftp 利用ftp正确登录与失败登录都会有不同的回显 使用ftplib库进行测试 from ftplib import FTP # FTP服务器地址 ftp_server 192.168.172.132 # FTP服务器端口&#xff08;默认为21&#xff09; ftp_po…...

软件测试 | APP测试 —— Appium 的环境搭建及工具安装教程

大家应该都有同一种感觉&#xff0c;学习appium最大的难处之一在于环境的安装&#xff0c;安装流程比较繁琐&#xff0c;安装的工具和步骤也较多&#xff0c;以下是基于Windows系统下的Android手机端的安装流程。就像我们在用Selenium进行web自动化测试的时候一样&#xff0c;我…...

计算机人工智能前沿进展-大语言模型方向-2024-09-13

计算机人工智能前沿进展-大语言模型方向-2024-09-13 1. OneEdit: A Neural-Symbolic Collaboratively Knowledge Editing System Authors: Ningyu Zhang, Zekun Xi, Yujie Luo, Peng Wang, Bozhong Tian, Yunzhi Yao, Jintian Zhang, Shumin Deng, Mengshu Sun, Lei Liang, Z…...

衡石分析平台使用手册-替换衡石minio

替换衡石minio​ 在使用HENGSHI SENSE服务过程中&#xff0c;可以根据业务需要替换HENGSHI自带的minio。本文讲述使用Aws S3和Aliyun OSS替代衡石minio的过程。 准备工作​ 在进行配置前&#xff0c;请在aws s3或aliyun oss完成如下准备工作。 创建access_key和secret_acces…...

怎么将几个pdf合成为一个?把几个PDF合并成为一个的8种方法

怎么将几个pdf合成为一个&#xff1f;将多个PDF文件合并成一个整体可以显著提高信息整合的效率&#xff0c;并简化文件的管理与传递。例如&#xff0c;将不同章节的电子书合成一本完整的书籍&#xff0c;或者将多个部门的报告整合成一个统一的文档&#xff0c;可以使处理流程变…...

明明没有程序占用端口,但是启动程序却提示端口无法使用,项目也启动失败

明明没有程序占用端口&#xff0c;但是启动程序却提示端口无法使用&#xff0c;项目也启动失败 win10、端口占用、port、netstat、used背景 曾在springboot中遇到过&#xff0c;新建spring cloud时又遇到这个问题&#xff0c;如果不从根本上解决&#xff0c;就需要改端口&…...

ClickHouse的安装配置+DBeaver远程连接

1、clickhouse的下载&#xff1a; 先去clickhouse官网进行下载&#xff0c;继续往下翻找文档&#xff0c;将DBeaver也下载下来 下载地址&#xff1a;https://packages.clickhouse.com/rpm/stable/ 下载这个四个rpm包 2、上传rmp文件到Linux中 自己创建的一个clickhouse-ins…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

MySQL的pymysql操作

本章是MySQL的最后一章&#xff0c;MySQL到此完结&#xff0c;下一站Hadoop&#xff01;&#xff01;&#xff01; 这章很简单&#xff0c;完整代码在最后&#xff0c;详细讲解之前python课程里面也有&#xff0c;感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...

2025年- H71-Lc179--39.组合总和(回溯,组合)--Java版

1.题目描述 2.思路 当前的元素可以重复使用。 &#xff08;1&#xff09;确定回溯算法函数的参数和返回值&#xff08;一般是void类型&#xff09; &#xff08;2&#xff09;因为是用递归实现的&#xff0c;所以我们要确定终止条件 &#xff08;3&#xff09;单层搜索逻辑 二…...

Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合

无论是python&#xff0c;或者java 的大型项目中&#xff0c;都会涉及到 自身平台微服务之间的相互调用&#xff0c;以及和第三发平台的 接口对接&#xff0c;那在python 中是怎么实现的呢&#xff1f; 在 Python Web 开发中&#xff0c;FastAPI 和 Django 是两个重要但定位不…...

归并排序:分治思想的高效排序

目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法&#xff0c;由约翰冯诺伊曼在1945年提出。其核心思想包括&#xff1a; 分割(Divide)&#xff1a;将待排序数组递归地分成两个子…...