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
相关文章
|
1月前
|
安全 Linux iOS开发
Binary Ninja 5.1.8104 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
Binary Ninja 5.1.8104 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
277 53
Binary Ninja 5.1.8104 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
|
1月前
|
Linux API iOS开发
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
154 14
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
|
2月前
|
安全 Linux API
JEB Pro v5.31 (macOS, Linux, Windows) - 逆向工程平台
JEB Pro v5.31 (macOS, Linux, Windows) - 逆向工程平台
143 0
|
3月前
|
Unix Linux 编译器
解决在Windows平台上运行Golang程序时出现的syscall.SIGUSR1未定义错误。
通过这种结构,你的代码既可以在支持 SIGUSR1 信号的系统上正常工作,又可以在不支持这些信号的 Windows 系统上编译通过,确保跨平台的兼容性和功能的完整性。
158 0
|
Unix Linux iOS开发
Splunk Enterprise 10.0.0 (macOS, Linux, Windows) - 搜索、分析和可视化,数据全面洞察平台
Splunk Enterprise 10.0.0 (macOS, Linux, Windows) - 搜索、分析和可视化,数据全面洞察平台
89 0
|
20天前
|
安全 数据安全/隐私保护 虚拟化
Windows Server 2022 中文版、英文版下载 (2025 年 10 月更新)
Windows Server 2022 中文版、英文版下载 (2025 年 10 月更新)
310 2
Windows Server 2022 中文版、英文版下载 (2025 年 10 月更新)
|
20天前
|
安全 Unix 物联网
Windows 7 & Windows Server 2008 R2 简体中文版下载 (2025 年 10 月更新)
Windows 7 & Windows Server 2008 R2 简体中文版下载 (2025 年 10 月更新)
159 0
Windows 7 & Windows Server 2008 R2 简体中文版下载 (2025 年 10 月更新)
|
20天前
|
存储 SQL 人工智能
Windows Server 2025 中文版、英文版下载 (2025 年 10 月更新)
Windows Server 2025 中文版、英文版下载 (2025 年 10 月更新)
279 0
|
2月前
|
运维 安全 网络安全
Windows Server 2019拨号“找不到设备”?Error 1058解决指南
Windows Server 2019拨号报错1058?别急!这不是硬件故障,而是关键服务被禁用。通过“服务依存关系”排查,依次启动“安全套接字隧道协议”“远程接入连接管理”和“路由与远程访问”服务,仅需4步即可恢复PPPoE或VPN拨号功能,轻松解决网络中断问题。
193 1
|
2月前
|
存储 SQL 人工智能
Windows Server 2025 中文版、英文版下载 (2025 年 9 月更新)
Windows Server 2025 中文版、英文版下载 (2025 年 9 月更新)
901 3
Windows Server 2025 中文版、英文版下载 (2025 年 9 月更新)

热门文章

最新文章

推荐镜像

更多
  • qt