首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >串口通信“第二次总超时”的复盘

串口通信“第二次总超时”的复盘

原创
作者头像
码事漫谈
发布2025-08-12 19:21:25
发布2025-08-12 19:21:25
4410
举报
文章被收录于专栏:程序员程序员

一次看似简单的“重试两次”,为何第二次永远收不到数据?undefined本文把问题从表面现象一直追到硬件协议层,给出可落地的最终方案。


1 问题现象

在 Windows 平台下,我们的代码大致如下(精简后):

代码语言:cpp
复制
// 最外层:业务重试 2 次
for (int i = 0; i < 2; ++i) {
    PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR);
    SendCommData(hComm, szCmd, 30);     // 30 字节
    if (RecvCommData(hComm, szRecv, 18)) // 想收 18 字节
        return SUCCESS;
    Sleep(100);
}
  • 第 1 轮:undefined发送 → 接收 → 很快返回 18 字节,但内容因干扰而“错误”。undefined逻辑判失败 → 进入第 2 轮。
  • 第 2 轮:undefined同样步骤,却永远超时(ReadFile 一直读不到 0 字节)。

2 逐层排查

排查项

结果

结论

线路波形

TX 两次都成功发出 30 字节;RX 第 2 次无任何波形

设备未回数据

串口缓存

每轮都 PurgeComm

旧数据已清空

超时参数

单轮 ReadFile 最多 150 ms + 18×100 ms = 1.95 s,足够长

不是时间不够

波特率 / 时钟

已确认正确

排除硬件速率问题

设备说明书

一帧指令一次应答,重复指令不响应

根因已找到


3 根本原因

设备协议本身只支持“单次应答”。

  • 收到第 1 帧 → 立即回 18 字节。
  • 再收第 2 帧(内容完全相同)→ 直接丢弃,不发任何数据

因此:

  • 第 1 轮即使因干扰拿到“错误帧”,也把唯一一次应答“用掉”。
  • 第 2 轮再发,设备不回 → FIFO 永远空 → ReadFile 超时。

4 最终解决方案

方案

说明

代码示例

A. 一次性收对

把单轮超时拉大,确保首轮就能把完整帧收齐。出现错误直接报错,不再重发同一帧。

ReadTotalTimeoutConstant = 1000; ReadTotalTimeoutMultiplier = 0;

B. 协议级重试

若必须重试,修改设备固件或协议:带序号/ACK,使设备能区分“重发”。

由硬件/固件团队完成

C. 上层策略

把重试逻辑改为“断电复位→重新上电→再发指令”,让设备重新初始化。

电源控制脚或继电器

如果硬件无法改动,方案 A 是唯一可行且零成本的落地做法


5 推荐参数组合(方案 A)

代码语言:cpp
复制
COMMTIMEOUTS cto = {0};
cto.ReadIntervalTimeout        = 20;   // 字节间 20 ms 容错
cto.ReadTotalTimeoutMultiplier = 0;    // 不字节累加
cto.ReadTotalTimeoutConstant   = 1000; // 整帧 1 s 足够
SetCommTimeouts(hComm, &cto);

// 去掉内部循环重试
BOOL RecvCommData(HANDLE hComm, char* buf, DWORD want)
{
    DWORD got = 0;
    return ReadFile(hComm, buf, want, &got, NULL) && got == want;
}

6 一句话总结

第二次超时不是 Windows 的问题,而是设备协议“只回一次”。

要么第一轮就保证正确,要么改协议/硬件;否则永远重发无效。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 问题现象
  • 2 逐层排查
  • 3 根本原因
  • 4 最终解决方案
  • 5 推荐参数组合(方案 A)
  • 6 一句话总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档