039 织梦云idc网站源码,珠海网站建设找哪家好,wordpress教育主题,百度竞价排名广告Qt串口
Qt串口编程是使用Qt框架进行串口通信的一种技术#xff0c;它的主要作用在于实现应用程序与外部设备之间的数据交换#xff0c;特别是那些通过串口进行通信的设备。串口通信广泛用于连接嵌入式系统、嵌入式设备和传感器、单片机、无线模块等外部硬件设备。它在很多嵌入…Qt串口
Qt串口编程是使用Qt框架进行串口通信的一种技术它的主要作用在于实现应用程序与外部设备之间的数据交换特别是那些通过串口进行通信的设备。串口通信广泛用于连接嵌入式系统、嵌入式设备和传感器、单片机、无线模块等外部硬件设备。它在很多嵌入式系统、嵌入式设备和传感器等应用中被广泛使用。
一、串口编程基础
1.1 串口通信基础
目前使用最广泛的串口为 DB9 接口适用于较近距离的通信。一般小于10米DB9接口有9个针脚。
串口通信的主要参数如下波特率衡量通信速度的参数表示每秒钟传送的bit的个数。例如9600波特表示每秒钟发送9600个bit。数据位衡量通信中实际数据位的参数当计算机发送一个信息包实际包含的有效数据位个数。停止位用于表示单个包的最后一位。典型的值为1,1.5和2位。奇偶校验位串口通信中一种检错方式。常用的检错方式有偶、奇校验。1.2 QtSerialPort模块简介
QtSerialPort模块是QT5中附加模块的一个模块为硬件和虚拟的串口提供统一的接口。
串口由于其简单和可靠目前在像嵌入式系统、机器人等工业中依旧用得很多。使用QtSerialPort模块开发者可以大大缩短开发串口相关的应用程序的周期。
Qt SerialPort 提供了基本的功能包括配置、I/O操作、获取和设置RS-232引脚的信号。
要在应用程序中使用QtSerialPort需要包括如下的声明
#include QSerialPortInfo
#include QSerialPort要链接 QtSerialPort 模块需要在.pro文件中添加如下内容
QT serialportQSerialPort 提供了访问串口的接口函数。使用辅助类QSerialPortInfo可以获取可用的串口信息。将 QSerialPortInfo 辅助类对象做为参数使用setPort()或setPortName()函数可以设置要访问的串口设备。
设置好端口后可以使用open()函数以只读、只写或读写的模式打开使用。使用close()函数关闭串口并且取消IO操作。注意串口使用独占方式打开。串口成功打开后QSerialPort会尝试确定串口的当前配置并初始化。可以使用setBaudRate()、setDataBits()、setParity()、
setStopBits()和setFlowControl()函数重新配置端口设置。
有一对名为QSerialPort::dataTerminalReady、QSerialPort::requestToSend的属性QSerialPort提供了中止正在调用线程直到
信号触发的一系列函数。这些函数用于阻塞串口。
waitForReadyRead()阻塞调用直到有新的数据可读
waitForBytesWritten()阻塞调用直到数据以及写入串口
阻塞串口编程与非阻塞串口编程完全不同。阻塞串口不会要求时间循环并且通常会简化代码。然而在GUI程序中为了避免冻结用户界面阻塞串口编程只能用于非GUI线程。
QSerialPort也能使用 QTextStream 和 QDataStream 的流操作符。在试图使用流操作符 读时需要确保有足够可用的数据。
1.3 QSerialPort 成员函数
构造函数
QSerialPort::QSerialPort(QObject *parent Q_NULLPTR)
QSerialPort::QSerialPort(const QString name, QObject *parent Q_NULLPTR)
QSerialPort::QSerialPort(const QSerialPortInfo serialPortInfo, QObject *parent Q_NULLPTR)如果当前没有数据可读返回 true
[virtual] bool QSerialPort::atEnd() const波特率改变后信号触发
[signal] void QSerialPort::baudRateChanged(qint32 baudRate, QSerialPort::Directions directions)返回可读数据的字节数
[virtual] qint64 QSerialPort::bytesAvailable() const返回可写数据的字节数
[virtual] qint64 QSerialPort::bytesToWrite() const关闭串口
[virtual] void QSerialPort::close()设置串口端口信息为 serialPortInfo
void QSerialPort::setPort(const QSerialPortInfo serialPortInfo)设置串口名为name
void QSerialPort::setPortName(const QString name)#include QCoreApplication
#include QSerialPort
#include QSerialPortInfo
#include QDebugint main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 创建串口对象无父对象QSerialPort serial;// 设置串口名serial.setPortName(COM3); // 右侧注释指定要操作的串口设备名// 打开串口读写模式if (!serial.open(QSerialPort::ReadWrite)) {qDebug() 串口打开失败;return -1;}// 设置波特率serial.setBaudRate(QSerialPort::Baud9600); // 右侧注释设置通信速率为9600// 设置数据位、校验位、停止位serial.setDataBits(QSerialPort::Data8); // 数据位8serial.setParity(QSerialPort::NoParity); // 无校验serial.setStopBits(QSerialPort::OneStop); // 1个停止位serial.setFlowControl(QSerialPort::NoFlowControl); // 无流控// 检查是否有可读数据if (serial.atEnd()) { // 右侧注释如果当前没有数据可读则返回trueqDebug() 没有可读数据;}// 获取可读数据字节数qint64 bytesAvailable serial.bytesAvailable(); // 右侧注释返回当前可读数据字节数qDebug() 可读字节数: bytesAvailable;// 写入数据QByteArray data Hello Serial;qint64 bytesWritten serial.write(data); // 右侧注释写入数据到串口返回写入字节数qDebug() 写入字节数: bytesWritten;// 获取等待写入的字节数qint64 toWrite serial.bytesToWrite(); // 右侧注释返回仍然在缓冲区等待写入的数据字节数qDebug() 待写字节数: toWrite;// 关闭串口serial.close(); // 右侧注释关闭串口设备return a.exec();
}
二、QSerialPortInfo
2.1 QSerialPortInfo简介
QSerialPortInfo 类提供已有串口设备的信息。使用 QSerialPortInfo 类的静态成员函数生成 QSerialPortInfo 对象的链表。
链表中的每个QSerialPortInfo对象代表一个串口每个串口可以使用端口名、系统定位、描述、制造商查询。QSerialPortInfo类
对象也可以用做QSerialPort类的setPort()成员函数的参数。
2.2 QSerialPortInfo成员函数
构造函数
QSerialPortInfo::QSerialPortInfo(const QSerialPort port)
QSerialPortInfo::QSerialPortInfo(const QString name)
QSerialPortInfo::QSerialPortInfo(const QSerialPortInfo other)返回当前系统可用串口的链表
[static] QListQSerialPortInfo QSerialPortInfo::availablePorts()如果串口可用返回串口的描述信息
QString QSerialPortInfo::description() const如果有一个合法的16位生产码返回true
bool QSerialPortInfo::hasProductIdentifier() const如果有一个合法的16位制造商编码返回true
bool QSerialPortInfo::hasVendorIdentifier() const如果串口当前正忙返回true
bool QSerialPortInfo::isBusy() const如果串口可用返回串口的制造商的名字
QString QSerialPortInfo::manufacturer() const返回串口的名字
QString QSerialPortInfo::portName() const如果串口可用返回串口的16位的生产编码
quint16 QSerialPortInfo::productIdentifier() const如果串口可用返回串口的序列号
QString QSerialPortInfo::serialNumber() const返回目标平台支持的可用的标准波特率的链表
[static] QListqint32 QSerialPortInfo::standardBaudRates()使用other交换QSerialPortInfo对象
void QSerialPortInfo::swap(QSerialPortInfo other)返回串口的系统位置
QString QSerialPortInfo::systemLocation() const如果串口可用返回16位的制造商编码
quint16 QSerialPortInfo::vendorIdentifier() const#include QCoreApplication
#include QSerialPortInfo
#include QDebugint main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 获取系统当前可用串口的链表QListQSerialPortInfo ports QSerialPortInfo::availablePorts(); // 静态函数返回所有可用串口信息// 遍历每一个串口foreach (const QSerialPortInfo info, ports) {qDebug() --------------------------------------;qDebug() 端口名: info.portName(); // 返回串口的名字例如 COM3qDebug() 系统位置: info.systemLocation(); // 串口在系统中的路径例如 /dev/ttyS0 或 COM3qDebug() 描述信息: info.description(); // 返回串口的描述例如 USB-SERIAL CH340qDebug() 制造商: info.manufacturer(); // 返回串口制造商例如 wch.cnqDebug() 序列号: info.serialNumber(); // 返回串口序列号若有if (info.hasVendorIdentifier()) { // 判断是否有合法的16位制造商编码qDebug() 厂商ID: info.vendorIdentifier(); // 返回厂商ID例如 6790}if (info.hasProductIdentifier()) { // 判断是否有合法的16位产品编码qDebug() 产品ID: info.productIdentifier(); // 返回产品ID例如 29987}qDebug() 是否忙: (info.isBusy() ? 是 : 否); // 串口当前是否被占用}// 获取支持的标准波特率列表QListqint32 baudRates QSerialPortInfo::standardBaudRates(); // 返回可用的标准波特率链表qDebug() 支持的标准波特率: baudRates;return a.exec();
}
2.3 QSerialPortInfo显示串口信息实例
#include QCoreApplication
#include QSerialPortInfo
#include QSerialPort
#include QList
#include QDebugint main(int argc, char *argv[]) {QCoreApplication a(argc, argv);QListQSerialPortInfo list QSerialPortInfo::availablePorts(); // 获取系统中可用串口列表qDebug() Total number of availiable ports: list.count(); // 输出可用串口的总数foreach(const QSerialPortInfo serialportinfo, list) {qDebug() Port: serialportinfo.portName(); // 串口名称例如 COM3qDebug() Location: serialportinfo.systemLocation(); // 串口系统位置例如 COM3 或 /dev/ttyUSB0qDebug() Description: serialportinfo.description(); // 串口描述信息例如 USB-SERIAL CH340qDebug() Manufactutor: serialportinfo.manufacturer(); // 制造商名称例如 wch.cnqDebug() Vendor Indentifier: serialportinfo.vendorIdentifier(); // 厂商ID16位十六进制数qDebug() Busy: serialportinfo.isBusy(); // 串口是否被占用true/false}return a.exec(); // 进入事件循环QCoreApplication要求
}
实现简易串口
mainwindow.h
#ifndef MYWIDGET_H
#define MYWIDGET_H#include QWidget
#include QSerialPort // 串口类
QT_BEGIN_NAMESPACE
namespace Ui { class MyWidget; } // 前向声明 UI 界面类
QT_END_NAMESPACEclass MyWidget : public QWidget
{Q_OBJECT // Qt 宏启用信号槽机制public:MyWidget(QWidget *parent nullptr); // 构造函数初始化窗口~MyWidget(); // 析构函数释放资源public slots:void onOpenPort(); // 打开串口的槽函数void reviceData(); // 接收串口消息的槽函数void on_pushButton_clicked(); // 发送消息的槽函数按钮点击private:Ui::MyWidget *ui; // 界面指针管理 UI 控件QSerialPort *serial; // 串口对象用于收发数据
};
#endif // MYWIDGET_H
mainwindow.cpp
#include mywidget.h
#include ui_mywidget.h
#include QSerialPortInfo
#include QDebug
#include QSerialPortMyWidget::MyWidget(QWidget *parent): QWidget(parent), ui(new Ui::MyWidget)
{ui-setupUi(this);serial new QSerialPort; // 创建串口对象//// 设置端口 QListQSerialPortInfo list QSerialPortInfo::availablePorts(); // 获取可用串口列表for(auto info: list){ui-comboBox_port-addItem(info.portName()); // 将串口名添加到下拉框}// 设置波特率ui-comboBox_baudRate-addItem(9600, QSerialPort::Baud9600);ui-comboBox_baudRate-addItem(19200, QSerialPort::Baud19200);ui-comboBox_baudRate-addItem(QStringLiteral(38400), QSerialPort::Baud38400);ui-comboBox_baudRate-addItem(QStringLiteral(115200), QSerialPort::Baud115200);// 设置数据位ui-comboBox_dataBit-addItem(QStringLiteral(5), QSerialPort::Data5);ui-comboBox_dataBit-addItem(QStringLiteral(6), QSerialPort::Data6);ui-comboBox_dataBit-addItem(QStringLiteral(7), QSerialPort::Data7);ui-comboBox_dataBit-addItem(QStringLiteral(8), QSerialPort::Data8);// 设置奇偶校验位ui-comboBox_parity-addItem(tr(None), QSerialPort::NoParity);ui-comboBox_parity-addItem(tr(Even), QSerialPort::EvenParity);ui-comboBox_parity-addItem(tr(Odd), QSerialPort::OddParity);ui-comboBox_parity-addItem(tr(Mark), QSerialPort::MarkParity);ui-comboBox_parity-addItem(tr(Space), QSerialPort::SpaceParity);// 设置停止位ui-comboBox_stopBit-addItem(QStringLiteral(1), QSerialPort::OneStop);ui-comboBox_stopBit-addItem(QStringLiteral(2), QSerialPort::TwoStop);// 添加流控ui-comboBox_flowBit-addItem(tr(None), QSerialPort::NoFlowControl);ui-comboBox_flowBit-addItem(tr(RTS/CTS), QSerialPort::HardwareControl);ui-comboBox_flowBit-addItem(tr(XON/XOFF), QSerialPort::SoftwareControl);// 打开串口按钮点击信号连接到槽函数connect(ui-pushButton_3,QPushButton::clicked,this,MyWidget::onOpenPort);
}MyWidget::~MyWidget()
{delete ui; // 释放 UI 内存
}void MyWidget::onOpenPort()
{if(ui-pushButton_3-text() 打开串口){ // 如果按钮显示“打开串口”说明串口未打开// 获取串口信息并设置serial-setPortName(ui-comboBox_port-currentText()); // 设置端口名serial-setBaudRate(ui-comboBox_baudRate-currentText().toInt()); // 设置波特率serial-setDataBits(QSerialPort::Data8); // 数据位serial-setParity(QSerialPort::NoParity); // 奇偶校验serial-setStopBits(QSerialPort::OneStop); // 停止位serial-setFlowControl(QSerialPort::NoFlowControl); // 流控if(serial-open(QIODevice::ReadWrite)){ // 打开串口ui-pushButton_3-setText(关闭串口); // 按钮改为关闭串口qDebug() 打开串口 serial-portName() 成功;// 串口有新数据可读时触发 reviceData() 槽connect(serial,QSerialPort::readyRead,this,MyWidget::reviceData);}} else {// 关闭串口if(serial-isOpen()){serial-close(); // 关闭串口}ui-pushButton_3-setText(打开串口); // 按钮改为打开串口}
}void MyWidget::reviceData()
{QByteArray buf;buf serial-readAll(); // 读取串口缓冲区所有数据if(!buf.isEmpty()){ui-plainTextEdit-appendPlainText(buf); // 显示到文本框}
}void MyWidget::on_pushButton_clicked()
{serial-write(ui-plainTextEdit_2-toPlainText().toUtf8()); // 将输入框数据写入串口
}三、图形界面设计
3.1 图形界面设计如图所示3.2 图形界面相关属性设置3.3 测试结果