1. 项目概述
这个基于Qt5.12开发的串口调试助手是我在实际工作中经常使用的一个实用工具。它虽然界面简洁,但功能非常实用,特别适合嵌入式开发、硬件调试等场景。作为一个经常需要和单片机、传感器打交道的开发者,一个好用的串口调试工具能极大提升工作效率。
这个工具最吸引我的地方在于它完整实现了串口通信的核心功能,包括:
- 基本的文本和十六进制数据收发
- 实用的自动回环功能
- 清晰的代码结构和详细注释
对于初学者来说,这是一个很好的学习Qt串口编程的范例;对于有经验的开发者,它也是一个可以快速上手的调试工具。我在实际使用过程中还根据自己的需求做了一些功能扩展,后面会详细分享这些经验。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 开发环境搭建
2.1 基础环境准备
要运行和开发这个项目,你需要准备以下环境:
- Qt 5.12或更高版本(建议使用Qt 5.15 LTS版本)
- 支持C++11的编译器(MSVC、MinGW或Clang)
- 一个可用的串口设备(可以是实际的硬件串口,也可以是虚拟串口)
提示:建议将Qt安装路径和项目路径都设置为纯英文路径,避免可能出现的编码问题。
2.2 项目配置要点
在Qt Creator中打开项目后,有几个关键配置需要注意:
- 项目文件(.pro)配置:
qmake复制QT += core gui serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = SerialDebugTool
TEMPLATE = app
- 串口权限设置(Linux/macOS):
bash复制sudo usermod -a -G dialout $USER
- 编码设置:
在main.cpp中添加:
cpp复制QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
3. 核心功能实现解析
3.1 串口初始化与配置
串口的初始化是整个工具的基础,在SerialPort类中实现。以下是关键代码分析:
cpp复制bool SerialPort::openPort(const QString &portName)
{
if(port->isOpen()) {
port->close();
}
port->setPortName(portName);
if(!port->open(QIODevice::ReadWrite)) {
qDebug() << "Failed to open port" << portName;
return false;
}
// 默认配置
port->setBaudRate(QSerialPort::Baud9600);
port->setDataBits(QSerialPort::Data8);
port->setParity(QSerialPort::NoParity);
port->setStopBits(QSerialPort::OneStop);
port->setFlowControl(QSerialPort::NoFlowControl);
return true;
}
在实际使用中,我发现以下几个参数需要特别注意:
- 波特率:必须与设备端严格一致,常见的值有9600、115200等
- 数据位:通常是8位,但有些老设备可能使用7位
- 流控制:大多数情况下不需要,但在高速传输时可能需要启用
3.2 数据收发实现
3.2.1 发送功能
发送功能支持文本和十六进制两种模式:
cpp复制void MainWindow::on_sendButton_clicked()
{
QString text = ui->sendTextEdit->toPlainText();
if(text.isEmpty()) return;
QByteArray data;
if(ui->hexSendCheckBox->isChecked()) {
// 十六进制发送处理
data = QByteArray::fromHex(text.toLatin1());
} else {
// 文本模式发送
data = text.toUtf8();
}
if(serialPort->write(data) == -1) {
statusBar()->showMessage("发送失败", 2000);
} else {
statusBar()->showMessage("发送成功", 2000);
}
}
3.2.2 接收功能
接收处理通过readyRead信号触发:
cpp复制void SerialPort::handleReadyRead()
{
QByteArray data = port->readAll();
// 处理接收到的数据
if(!data.isEmpty()) {
emit dataReceived(data);
}
}
在MainWindow中,接收到的数据会根据设置以文本或十六进制形式显示:
cpp复制void MainWindow::onDataReceived(const QByteArray &data)
{
QString displayText;
if(ui->hexDisplayCheckBox->isChecked()) {
// 十六进制显示
displayText = data.toHex(' ').toUpper();
} else {
// 文本显示
displayText = QString::fromUtf8(data);
}
ui->receiveTextEdit->append(displayText);
// 自动回环处理
if(ui->loopbackCheckBox->isChecked()) {
on_sendButton_clicked();
}
}
3.3 自动回环功能
自动回环是调试时非常实用的功能,实现原理很简单:
cpp复制void MainWindow::on_loopbackCheckBox_stateChanged(int state)
{
loopbackEnabled = (state == Qt::Checked);
