Qt QSerialPort串口编程

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"为实际的串口名称。波特率、数据位、停止位和奇偶校验参数应根据你的硬件设备进行相应设置。

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

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值