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"为实际的串口名称。波特率、数据位、停止位和奇偶校验参数应根据你的硬件设备进行相应设置。
这个例子展示了如何打开串口、设置串口参数、发送数据、读取数据以及关闭串口。在实际应用中,你可能需要使用信号和槽来处理数据的异步读写。