
一句话: 时基的坑一个项目里能踩三次tick 实际 0.5ms 却按 1ms 算所有延时差 2 倍宏名写 MS 实际是 TICK8000 以为是 8 秒只有 4 秒宏值小于等于调度周期时调宏等于没调。三条都沾上就是深夜排查。适合谁读用定时器产生系统心跳、基于 tick 计数器做延时/超时的嵌入式工程师。坑一tick 是 0.5ms按 1ms 用——延时全差一倍一个自动控制流程代码里写着每 0.3 秒执行一步实测每步 0.6 秒——节奏慢一倍但功能正常。这种功能对、节奏错的问题最阴险不崩、不错只是时间不对很多人会怀疑自己看错了。查到最后是定时器配置定时器频率 1MHz重装载值 500——中断周期是500µs 0.5ms。而代码里所有延时宏都按 1ms 在算// 定时器配置500 周期 1MHz → 中断每 0.5ms 一次 // 但代码里把 tick 当成 1ms 用 #define STEP_PERIOD 600 // 以为是 600ms实际 300ms所有基于 tick 的延时乘以 2 才对。为什么这么难查不报错、现象合理慢一倍像正常的慢、宏名带误导STEP_MS让人默认毫秒。坑二宏名写 MS实际是 TICK——超时直接减半序列超时宏#define LIGHT_SEQ_TIMEOUT_MS 8000U /* 看起来是 8 秒 */实际8000 × 0.5ms 4 秒。宏名带 MS人按毫秒直觉写值超时减半——某个环节慢热时误超时停机上板测试恰好没遇到极端情况错误被掩盖。这个坑在同一套代码里踩了三次次数宏/注释实际值结果1超时宏写 8000注释8秒8000×0.5ms4秒超时减半慢热误停机2搜索步宏 600注释0.3s/步600×0.5ms300ms侥幸换算对了3注释等0.5s复测宏值 600 0.3s又是单位直觉错坑三宏值 ≤ 调度周期调宏等于没调二分法想提速把搜索步 0.3s 改成 0.05s宏值 100——没效果。排查发现二分法挂在主循环100ms的时基标志上每次被调用时 elapsed 已经 ≥100ms宏写 1000.05s还是 500.025s实际都是 100ms/步。规则宏值小于等于调度周期时实际步进 调度周期。要真提速先改调用粒度新增 50ms 时基标志把函数挂上去再调宏值才有意义。再试 0.02s10ms 调用粒度 20ms 步进——这次是真快但快出问题测量瞬态还没建立就读数方向误判搜索失控推到顶格。认识了硬件下限测量建立时间 ~100ms。步长有下限不是越小越好。怎么根治宏名不要写 MS写XXX_TICK或XXX_CNT让人知道单位是 tick注释里强制写换算结果/* 100 × 0.5ms 50ms */——每个宏旁边写死换算后的真实时间所有用 tick 计数器的地方统一排查时基陷阱在项目里是成片出现的调度周期是隐藏约束改步进时间前先确认谁在调用、多久调一次先确认 tick 单位再写延时宏算中断周期预分频 ÷ 重装载值 IO 翻转实测别靠猜自查清单有没有宏名带 MS 但实际比较的是 tick 计数器时基计数器单位是不是 0.5ms / 1ms / 别的宏值是否小于等于调度周期等于没调注释里的时间是不是按 1ms 直觉写的延时/超时最近有没有差一点的感觉实测对比tick当1ms用延时全差2倍 | 宏名写MS8000超时只有4秒 | 宏≤调度周期调宏等于没调有用的话点个收藏下次调试直接用。有问题欢迎评论区交流看到了都会回。下一篇一次全量测试排掉三个bug嵌入式调试的三条方法论——分层排查、边界测试、测试清单驱动