Qt串口通信
Qt提供了两个关于串口通信的C++类,分别是QSerialPort和QSerialPortInfo。
QSerialPort类提供了操作串口的各种接口。
QSerialPortInfo是一个辅助类,可以提供计算机中可用的串口的各种信息。
1.QSerialPortInfo Class
用于提供外部串行端口的信息
使用静态函数生成一个QSerialPortInfo对象的列表。列表中的每个QSerialPortInfo对象存储着单个串行端口的信息,可以查询端口名称,系统位置,描述和制造商。QSerialPortInfo类也可作为QSerialPort类中setPort()方法的输入参数。
Header: #include <QSerialPortInfo>
qmake: QT += serialport
1.1 Public Functions
// 构造函数
// 构造一个空的QSerialPortInfo对象
QSerialPortInfo::QSerialPortInfo();
// 通过串行口来构造一个QSerialPortInfo对象
QSerialPortInfo::QSerialPortInfo(const QSerialPort& port);
// 通过串行口名称来构造一个QSerialPortInfo对象
// 该构造函数根据端口名称在可用的串口中查找相关的串口,并为该端口构造串口信息实例
QSerialPortInfo::QSerialPortInfo(const QString& name);
// 复制构造函数
QSerialPortInfo::QSerialPortInfo(const QSerialPortInfo& other);
// 析构函数
QSerialPortInfo::~QSerialPortInfo();
// 如果串行口处于占用状态返回true,否则返回false
bool QSerialPortInfo::isBusy() const;
// 返回此QSerialPortInfo对象是否包含串行端口定义
bool QSerialPortInfo::isNull() const;
// 返回串行端口的名称
QString QSerialPortInfo::portName() const;
// 返回串行端口的系统位置
QString QSerialPortInfo::systemLocation() const;
// 返回串行端口的描述字符串(如果可用);否则返回空字符串。
QString QSerialPortInfo::description() const;
// 返回串行端口的制造商字符串(如果可用);否则返回空字符串
QString QSerialPortInfo::manufacturer() const;
// 返回串行端口的序列号字符串(如果可用);否则返回空字符串
QString QSerialPortInfo::serialNumber() const;
// 返回目标平台支持的可用标准波特率列表
QList<qint32> QSerialPortInfo::standardBaudRates();
// 如果存在有效的16位供应商编号,则返回true;否则返回false
bool QSerialPortInfo::hasVendorIdentifier() const;
// 如果存在有效的16位产品号,则返回true;否则返回false。
bool QSerialPortInfo::hasProductIdentifier() const;
// 返回串行端口的16位供应商编号(如果可用);否则返回零。
quint16 QSerialPortInfo::vendorIdentifier() const;
// 返回串行端口的16位产品号(如果可用);否则返回零。
quint16 QSerialPortInfo::productIdentifier() const;
// 交换其他QSerialPortInfo对象与调用该函数的QSerialPortInfo对象。这个方法执行起来非常快并且不会失败。
void QSerialPortInfo::swap(QSerialPortInfo& ther);
// 运算符重载函数
QSerialPortInfo& QSerialPortInfo::operator=(const QSerialPortInfo& other);
1.2 Static Public Members
// 返回目标平台支持的可用标准波特率列表。
static QList<qint32> standardBaudRates();
// 返回系统上可用串行端口的列表。
static QList<QSerialPortInfo> availablePorts();
2.QSerialPort Class
Header: #include <QSerialPort>
qmake: QT += serialport
inherits: QIODevice
2.1 Public Types
/*
* 该枚举描述通信设备操作的波特率
* 注:此枚举中仅列出了最常见的标准波特率
* baudRate:qint32
*/
enum QSerialPort::BaudRate
{
Baud1200 = 1200,
Baud2400 = 2400,
Baud4800 = 4800,
Baud9600 = 9600,
Baud19200 = 19200,
Baud38400 = 38400,
Baud57600 = 57600,
Baud115200 = 115200,
UnknownBaud = -1
};
/*
* 该枚举描述了通信设备传输采用的数据位数
*/
enum DataBits
{
Data5 = 5,
Data6 = 6,
Data7 = 7,
Data8 = 8,
UnknownDataBits = -1
};
/*
* 该枚举描述了数据传输可用的方向
*/
enum Direction
{
Input = 1,
Output = 2,
AllDirections = Input | Output
};
/*
* 该枚举描述了所使用的流控制
*/
enum FlowControl
{
NoFlowControl,
HardwareControl,
SoftwareControl,
UnknownFlowControl = -1
};
/*
* 该枚举描述了所使用的奇偶效验方案
*/
enum Parity
{
NoParity = 0,
EvenParity = 2,
OddParity = 3,
SpaceParity = 4,
MarkParity = 5,
UnknownParity = -1
};
/*
* 该枚举描述了所使用的停止位数
*/
enum StopBits
{
OneStop = 1,
OneAndHalfStop = 3,
TwoStop = 2,
UnknownStopBits = -1
};
2.2 Public Functions
// 用给定的父对象构造一个新的串行端口对象。
QSerialPort::QSerialPort(QObject* parent = nullptr);
// 用给定的父对象构造一个新的串行端口对象,以表示具有指定名称的串行端口
QSerialPort::QSerialPort(const QString& name, QObject* parent = nullptr);
// 用给定的父对象构造一个新的串行端口对象,用指定的助手类serialPortInfo表示串行端口。
QSerialPort::QSerialPort(const QSerialPortInfo& serialPortInfo, QObject* parent = nullptr);
// 如有必要,关闭串行端口,然后销毁对象
QSerialPort::~QSerialPort();
给实例化的串口对象指定本地串口
// 设置存储在串行端口信息实例serialPortInfo中的端口。
void QSerialPort::setPort(const QSerialPortInfo& serialPortInfo);
// 设置串行端口的名称去设置QSerialPort实例
void QSerialPort::setPortName(const QString& name);
配置串口特性
// 配置串口波特率和读写方向
bool QSerialPort::setBaudRate(qint32 baudRate, Directions directions = AllDirections);
// 配置串口数据位数
bool QSerialPort::setDataBits(DataBits dataBits);
// 配置串口流控
bool QSerialPort::setFlowControl(FlowControl flowControl);
// 配置串口奇偶效验位
bool QSerialPort::setParity(Parity parity);
// 配置串口停止位
bool QSerialPort::setStopBits(StopBits stopBits);
2.3 Reimplemented Public Functions
/*
* 使用OpenMode模式开打串行端口,如果成功,则返回true;
* 否则返回false并设置一个错误代码,该代码可以通过调用error()方法获得
* mode:必须是 QIODevice::ReadOnly, QIODevice::WriteOnly,
* or QIODevice::ReadWrite。其他模式不提供支持
*/
bool QSerialPort::open(OpenMode mode);
/*
* 根据给定的方向,丢弃输出或输入缓冲区中的所有字符。
* 这包括清除内部类缓冲区和UART(驱动程序)缓冲区。同时终止挂起的读或写操作。
* 如果成功,则返回true;否则返回false
* 注意:在试图清除任何缓冲数据之前,必须打开串行端口;
* 否则返回false并设置NotOpenError错误代码。
*/
bool QSerialPort::clear(Directions directions = AllDirections);
2.4 Signals
等用到之后再填充
2.5 Reimplemented Protected Functions
/*
* 注意:在尝试关闭串行端口之前,必须先打开串行端口;否则设置NotOpenError错误代码。
*/
virtual void QSerialPort::close();
3. 操作流程
3.1枚举本地可连接的所有串口
// 1.通过QSerialPortInfo对象
QList<QSerialPortInfo> m_serialPortInfos;
foreach (const QSerialPortInfo& info, QSerialPortInfo::availablePorts())
{
m_serialPortInfos.append(info);
qDebug() << "SerialPortName: " << info.portName();
}
// 2.通过串口名称
QStringList m_serialPortName;
foreach(const QSerialPortInfo& info, QSerialPortInfo::availablePorts())
{
m_serialPortName << info.portName();
qDebug() << "SerialPortName: " << info.portName();
}
3.2打开串口,对串口进行配置
// 实例化一个串口类对象
QSerialPort* m_serialPort = new QSerialPort();
// 如果串口已经打开,则先需要关闭它
if (m_serialPort->isOpen())
{
m_serialPort->clear();
m_serialPort->close();
}
// 设置串口名字
m_serialPort->setPortName(m_serialPortName[0]);
if (!m_serialPort->open(QIODevice::ReadWrite))
{
qDebug() << m_serialPortName[0] << "serialPort open faile!";
return;
}
// 配置串口
// 配置串口波特率和方向
m_serialPort->setBaudRate(QSerialPort::Baud115200, QSerialPort::AllDirections);
m_serialPort->setDataBits(QSerialPort::Data8); // 8位数据
m_serialPort->setFlowControl(QSerialPort::NoFlowControl); // 无流控
m_serialPort->setParity(QSerialPort::NoParity); // 无校验位
m_serialPort->setStopBits(QSerialPort::OneStop); // 一位停止位
3.3数据交互
// 当下位机发送来数据,会产生一个&QIODevice::readyRead()信号。定义一个槽函数去接收数据
connect(m_serialPort, &QSerialPort::readyRead, this, &myClass::recvInfo);
// 接收数据函数
void recvInfo()
{
QByteArray info = m_serialPort->readAll();
}
// 发送数据函数
void sendInfo()
{
m_serialPort->write("");
}
3.4回收资源,关闭串口
if (m_serialPort->isOpen())
{
m_serialPort->clear();
m_serialPort->close();
}
m_serialPort->deleteLater(); // delete m_serialPort;