以下是使用 虚拟串口工具(socat) 测试 Qt 串口程序的完整详细指南,包含代码示例和调试技巧:
📦 第一步:安装 socat
在终端执行:
sudo apt install socat
🔗 第二步:创建虚拟串口对
运行以下命令,创建一对相互连接的虚拟串口:
socat -d -d pty,raw,echo=0 pty,raw,echo=0
输出示例:
2023/07/20 14:30:00 socat[1234] N PTY is /dev/pts/2
2023/07/20 14:30:00 socat[1234] N PTY is /dev/pts/3
关键说明:
- 生成的虚拟端口是
/dev/pts/2(发送端)和/dev/pts/3(接收端) - 两个端口的数据完全互通,发送到
/dev/pts/2的数据会立即出现在/dev/pts/3
🛠️ 第三步:Qt 程序配置(发送端)
在 Qt 中配置发送端串口:
#include <QSerialPort>
#include <QDebug>
// 在窗口类中声明
private:
QSerialPort *serialSender;
// 初始化发送端
void SerialTest::initSender() {
serialSender = new QSerialPort(this);
// 配置参数(必须与接收端一致)
serialSender->setPortName("/dev/pts/2"); // 使用虚拟发送端口
serialSender->setBaudRate(QSerialPort::Baud115200);
serialSender->setDataBits(QSerialPort::Data8);
serialSender->setParity(QSerialPort::NoParity);
serialSender->setStopBits(QSerialPort::OneStop);
serialSender->setFlowControl(QSerialPort::NoFlowControl);
if (!serialSender->open(QIODevice::WriteOnly)) {
qDebug() << "发送端打开失败:" << serialSender->errorString();
return;
}
// 发送测试数据
sendTestData();
}
// 发送数据函数
void SerialTest::sendTestData() {
QByteArray data = "Hello Qt Serial!";
qint64 bytesWritten = serialSender->write(data);
if (bytesWritten != data.size()) {
qDebug() << "发送数据不完整";
} else {
qDebug() << "已发送:" << data;
}
serialSender->flush(); // 确保数据全部发出
}
📡 第四步:Qt 程序配置(接收端)
在 Qt 中配置接收端串口并验证数据:
#include <QSerialPort>
#include <QDebug>
// 在窗口类中声明
private:
QSerialPort *serialReceiver;
QByteArray expectedData;
// 初始化接收端
void SerialTest::initReceiver() {
serialReceiver = new QSerialPort(this);
// 配置参数(必须与发送端一致)
serialReceiver->setPortName("/dev/pts/3"); // 使用虚拟接收端口
serialReceiver->setBaudRate(QSerialPort::Baud115200);
serialReceiver->setDataBits(QSerialPort::Data8);
serialReceiver->setParity(QSerialPort::NoParity);
serialReceiver->setStopBits(QSerialPort::OneStop);
serialReceiver->setFlowControl(QSerialPort::NoFlowControl);
if (!serialReceiver->open(QIODevice::ReadOnly)) {
qDebug() << "接收端打开失败:" << serialReceiver->errorString();
return;
}
// 连接信号槽
connect(serialReceiver, &QSerialPort::readyRead, this, &SerialTest::handleReadyRead);
}
// 接收数据槽函数
void SerialTest::handleReadyRead() {
QByteArray receivedData = serialReceiver->readAll();
qDebug() << "接收到的数据:" << receivedData;
// 验证数据一致性
if (receivedData == expectedData) {
qDebug() << "✅ 数据验证成功!";
} else {
qDebug() << "❌ 数据不匹配:"
<< "发送:" << expectedData
<< "接收:" << receivedData;
}
}
🔍 第五步:调试与验证
1. 手动验证(使用 CuteCom)
- 打开两个 CuteCom 窗口:
- 窗口1:选择
/dev/pts/2(发送端) - 窗口2:选择
/dev/pts/3(接收端)
- 窗口1:选择
- 在窗口1输入数据,窗口2应立即显示相同内容
2. Qt 程序调试技巧
- 检查端口状态:
qDebug() << "发送端状态:" << (serialSender->isOpen() ? "已打开" : "未打开") << "错误:" << serialSender->errorString(); - 设置读写超时:
serialSender->setReadTimeout(500); // 500ms 超时 serialSender->setWriteTimeout(500); - 使用字节填充验证:
// 发送端 QByteArray pattern(1024, 0xA5); // 填充 0xA5 字节 serialSender->write(pattern); // 接收端 if (receivedData.contains(0xA5)) { qDebug() << "填充模式验证通过"; }
⚠️ 常见问题排查
1. 端口不存在错误
- 现象:
QSerialPort::open: Device not found - 原因:socat 生成的端口号与代码中配置的不一致
- 解决:
- 重新运行
socat命令获取最新端口号 - 在代码中使用动态获取端口的方式:
// 查找可用虚拟端口 QFile file("/dev/pts/"); if (file.exists()) { QDir dir("/dev/pts"); QStringList entries = dir.entryList(QDir::System); for (const QString &entry : entries) { if (entry.startsWith("pts")) { qDebug() << "找到虚拟端口:" << entry; } } }
- 重新运行
2. 数据不完整错误
- 现象:发送 10 字节数据,接收端仅收到 5 字节
- 原因:未调用
flush()或串口缓冲区未清空 - 解决:
// 发送端添加延迟和flush serialSender->write(data); serialSender->flush(); QThread::msleep(50); // 等待硬件处理
3. 权限拒绝错误
- 现象:
QSerialPort::open: Permission denied - 解决:
# 方法1:临时权限 sudo chmod 666 /dev/pts/2 /dev/pts/3 # 方法2:永久权限(推荐) sudo usermod -aG dialout $USER newgrp dialout # 立即生效
📝 完整测试流程
- 运行
socat创建虚拟端口对 - 启动 Qt 程序,初始化发送端和接收端
- 在发送端调用
sendTestData() - 观察接收端的
handleReadyRead输出 - 验证数据一致性
通过以上步骤,您可以完整测试串口程序的发送和接收功能。虚拟串口方案无需硬件连接,适合快速迭代调试。
3.关联链接
4.关联知识
927

被折叠的 条评论
为什么被折叠?



