滑动窗口去抖动:连续 N 次满足条件才算数

一句话: 用 ADC 监测模拟信号时,单次读数可能被干扰毛刺影响导致误判。滑动窗口法:连续 N 次读数都满足条件才确认状态变化——既抗干扰又不延迟响应。

适合谁读:适合嵌入式开发者、单片机初学者及遇到类似问题的工程师

为什么单次阈值不够

用 ADC 读取电压来判断"稳定了没有":

if (abs(vtec - vtec_last) < 100) { // 判为稳定 }

问题:

  • 刚启动时 VTEC 恰好经过零点→ 单次满足条件 → 误判为稳定(实际还在剧烈变化)
  • 外部干扰导致 VTEC 瞬间跳变→ 单次不满足条件 → 误判为不稳定(实际已经很稳了)

滑动窗口法

不只看本次,看连续 N 次:

#define STABLE_THRESHOLD 100 // 波动阈值 #define STABLE_COUNT 3 // 连续稳定次数 int16_t i16LastVal; uint8_t u8StableCnt; void Monitor(int16_t i16CurrentVal) { int16_t i16Delta = abs(i16CurrentVal - i16LastVal); if (i16Delta < STABLE_THRESHOLD) { u8StableCnt++; // 这次稳了,计数+1 if (u8StableCnt >= STABLE_COUNT) { SetState(STABLE); // 连续N次都稳 → 真稳了 } } else { u8StableCnt = 0; // 波动超阈值 → 清零,重来 } i16LastVal = i16CurrentVal; }

为什么比单次阈值好

单次: ✓ ✓ ✗ ✓ ✓ → 毛刺触发误判 滑动窗口: ✓ ✓ ✗ ✓ ✓ → 计数被清零,等连续 3 次才判稳
单次阈值滑动窗口
抗毛刺差,一次干扰就误判好,需要连续 N 次
响应速度延迟 N 个采样周期
参数只有阈值阈值 + 连续次数

参数怎么设

#define STABLE_THRESHOLD 100 // mV,靠实测定——太小误报多,太大漏报 #define STABLE_COUNT 3 // 次数,愿意多等就改大

THRESHOLD × COUNT决定了判断窗口的长度。100ms 采样 × 3 次 = 300ms 判稳——既抗干扰又不至于等太久。


总结

要点说明
原理不只看本次,看连续 N 次
好处单次毛刺不触发误判
代价延迟 N 个采样周期
适用任何需要"稳定判据"的 ADC 监测场景

不需要复杂的滤波器,一个滑动窗口计数器就够了。


有用的话点个收藏,下次调试直接用。有问题欢迎评论区交流,看到了都会回。

下一篇:用分和元讲透(附代码)——NTC测温、SPI通信、I2C从机、定点数运算——外设驱动从入门到精通