Qt5实现Windows平台串口通信

简介: Qt5实现Windows平台串口通信

一、环境配置

  1. 开发环境: Qt 5.15.2+ (MSVC 2019编译器) Windows 10/11

  2. 依赖配置

    # .pro文件配置
    QT += serialport widgets
    LIBS += -lQt5SerialPort
    

二、界面设计

1. 控件布局

<!-- mainwindow.ui -->
<widget class="QMainWindow" name="MainWindow">
    <layout class="QGridLayout">
        <!-- 串口配置区 -->
        <item row="0" column="0">
            <QLabel text="串口号"/>
        </item>
        <item row="0" column="1">
            <QComboBox objectName="cmbPort"/>
        </item>

        <!-- 波特率设置 -->
        <item row="1" column="0">
            <QLabel text="波特率"/>
        </item>
        <item row="1" column="1">
            <QComboBox objectName="cmbBaudRate"/>
        </item>

        <!-- 控制按钮 -->
        <item row="2" column="0" colspan="2">
            <QPushButton text="打开串口" objectName="btnOpen"/>
        </item>

        <!-- 数据收发区 -->
        <item row="3" column="0">
            <QPlainTextEdit objectName="txtSend"/>
        </item>
        <item row="3" column="1">
            <QPlainTextEdit objectName="txtRecv"/>
        </item>

        <!-- 发送按钮 -->
        <item row="4" column="0" colspan="2">
            <QPushButton text="发送数据" objectName="btnSend"/>
        </item>
    </layout>
</widget>

三、核心代码实现

1. 头文件定义

// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSerialPort>

QT_BEGIN_NAMESPACE
namespace Ui {
    class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow {
   
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_btnOpen_clicked();
    void on_btnSend_clicked();
    void serialRead();

private:
    void initSerialPort();
    void populatePorts();

    Ui::MainWindow *ui;
    QSerialPort *serial;
};

#endif // MAINWINDOW_H

2. 实现文件

// mainwindow.cpp
#include "mainwindow.h"
#include <QSerialPortInfo>
#include <QByteArray>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
   
    ui->setupUi(this);

    // 初始化串口
    serial = new QSerialPort(this);
    initSerialPort();
    populatePorts();

    // 信号槽连接
    connect(ui->btnOpen, &QPushButton::clicked, this, &MainWindow::on_btnOpen_clicked);
    connect(ui->btnSend, &QPushButton::clicked, this, &MainWindow::on_btnSend_clicked);
    connect(serial, &QSerialPort::readyRead, this, &MainWindow::serialRead);
}

MainWindow::~MainWindow()
{
   
    if(serial->isOpen()) serial->close();
    delete ui;
}

void MainWindow::initSerialPort()
{
   
    // 配置默认参数
    serial->setBaudRate(QSerialPort::Baud9600);
    serial->setDataBits(QSerialPort::Data8);
    serial->setParity(QSerialPort::NoParity);
    serial->setStopBits(QSerialPort::OneStop);
    serial->setFlowControl(QSerialPort::NoFlowControl);
}

void MainWindow::populatePorts()
{
   
    ui->cmbPort->clear();
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
   
        ui->cmbPort->addItem(info.portName());
    }
}

void MainWindow::on_btnOpen_clicked()
{
   
    if(serial->isOpen()) {
   
        serial->close();
        ui->btnOpen->setText("打开串口");
    } else {
   
        serial->setPortName(ui->cmbPort->currentText());
        if(serial->open(QIODevice::ReadWrite)) {
   
            ui->btnOpen->setText("关闭串口");
        } else {
   
            QMessageBox::critical(this, "错误", serial->errorString());
        }
    }
}

void MainWindow::on_btnSend_clicked()
{
   
    QByteArray data = ui->txtSend->toPlainText().toUtf8();
    if(!data.isEmpty()) {
   
        qint64 bytes = serial->write(data);
        if(bytes == -1) {
   
            QMessageBox::warning(this, "发送失败", serial->errorString());
        }
    }
}

void MainWindow::serialRead()
{
   
    QByteArray buffer = serial->readAll();
    if(!buffer.isEmpty()) {
   
        ui->txtRecv->appendPlainText(QString::fromUtf8(buffer));
    }
}

四、功能扩展

1. 十六进制支持

// 在发送函数中添加HEX转换
void MainWindow::on_btnSend_clicked()
{
   
    QString text = ui->txtSend->toPlainText();
    QByteArray data;

    if(ui->chkHexSend->isChecked()) {
   
        bool ok;
        data = QByteArray::fromHex(text.toUtf8(), &ok);
        if(!ok) {
   
            QMessageBox::warning(this, "错误", "无效的HEX格式");
            return;
        }
    } else {
   
        data = text.toUtf8();
    }

    serial->write(data);
}

2. 数据校验

// 在配置函数中添加校验位设置
void MainWindow::setParity(QSerialPort::Parity parity) {
   
    serial->setParity(parity);
}

// 示例:CRC16校验
quint16 MainWindow::calculateCRC(const QByteArray &data) {
   
    quint16 crc = 0xFFFF;
    for(auto byte : data) {
   
        crc ^= (quint16)byte << 8;
        for(int i=0; i<8; i++) {
   
            if(crc & 0x8000) crc = (crc << 1) ^ 0x1021;
            else crc <<= 1;
        }
    }
    return crc;
}

五、调试技巧

  1. 虚拟串口测试: 使用VSPD创建虚拟串口对(如COM3 <-> COM4) 在程序中选择不同端口测试双向通信

  2. 数据监控

    // 添加调试输出
    qDebug() << "Received:" << buffer.toHex(' ') << "Length:" << buffer.size();
    
  3. 流量控制

    // 启用硬件流控制
    serial->setFlowControl(QSerialPort::HardwareControl);
    

六、编译与运行

  1. 构建配置

    qmake mainwindow.pro
    make
    
  2. 运行验证: 确保COM端口未被占用 通过设备管理器确认串口参数匹配

参考代码 Qt5串口通信程序 www.youwenfan.com/contentalf/69949.html

七、常见问题处理

现象 解决方案
无法打开串口 检查端口号是否正确,关闭占用程序
数据丢失 增加接收缓冲区,优化读取频率
显示乱码 统一使用UTF-8编码,添加校验逻辑
高波特率不稳定 降低波特率,检查线缆质量

八、工程结构

SerialDemo/
├── Src/
│   ├── main.cpp
│   ├── mainwindow.cpp
│   └── mainwindow.h
├── Res/
│   └── mainwindow.ui
└── SerialDemo.pro
相关文章
|
3月前
|
安全 Linux iOS开发
Binary Ninja 5.1.8104 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
Binary Ninja 5.1.8104 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
416 53
Binary Ninja 5.1.8104 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
|
3月前
|
Linux API iOS开发
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
271 14
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
|
4月前
|
安全 Linux API
JEB Pro v5.31 (macOS, Linux, Windows) - 逆向工程平台
JEB Pro v5.31 (macOS, Linux, Windows) - 逆向工程平台
169 0
|
5月前
|
Unix Linux 编译器
解决在Windows平台上运行Golang程序时出现的syscall.SIGUSR1未定义错误。
通过这种结构,你的代码既可以在支持 SIGUSR1 信号的系统上正常工作,又可以在不支持这些信号的 Windows 系统上编译通过,确保跨平台的兼容性和功能的完整性。
227 0
|
Unix Linux iOS开发
Splunk Enterprise 10.0.0 (macOS, Linux, Windows) - 搜索、分析和可视化,数据全面洞察平台
Splunk Enterprise 10.0.0 (macOS, Linux, Windows) - 搜索、分析和可视化,数据全面洞察平台
152 0
|
Java 数据安全/隐私保护 iOS开发
Windows 平台上也可以进行 iOS App 的开发
为了将 iOS APP 上架至 App Store,我们需要准备以下基本需求资料:1. 苹果开发者账号(如果还没有账号,需要先申请,可以参考苹果开发者账号申请教程)
|
C++ Windows 编译器
Windows平台上C++开发内存泄漏检查方法
充分的利用调试工具可以非常方便地避免内存泄漏问题。       这里介绍两种方法,互为补充,第一种是VC编译器提供的方法,第二种是专用的内存泄漏检查工具Memmory Validator。这两种方法的基本原理是一样的:内存分配要通过CRT在运行时实现,只要在分配内存和释放内存时分别做好记录,程序结束时对比分配内存和释放内存的记录就可以确定是不是有内存泄漏。
1119 0
|
3月前
|
安全 数据安全/隐私保护 虚拟化
Windows Server 2022 中文版、英文版下载 (2025 年 10 月更新)
Windows Server 2022 中文版、英文版下载 (2025 年 10 月更新)
821 2
Windows Server 2022 中文版、英文版下载 (2025 年 10 月更新)
|
3月前
|
安全 Unix 物联网
Windows 7 & Windows Server 2008 R2 简体中文版下载 (2025 年 10 月更新)
Windows 7 & Windows Server 2008 R2 简体中文版下载 (2025 年 10 月更新)
367 0
Windows 7 & Windows Server 2008 R2 简体中文版下载 (2025 年 10 月更新)
|
3月前
|
存储 SQL 人工智能
Windows Server 2025 中文版、英文版下载 (2025 年 10 月更新)
Windows Server 2025 中文版、英文版下载 (2025 年 10 月更新)
524 0

推荐镜像

更多
  • qt