第八章: 滤波模块 —— 给你的数据“洗个澡”!
2026/5/2 21:07:57 网站建设 项目流程

🧼 滤波模块 —— 给你的数据“洗个澡”!

✅ 适用对象:嵌入式初学者、传感器开发者
💡 核心目标:理解为什么需要滤波 + 掌握4种常用滤波算法 + 能在项目中灵活选用
🧠 特色:用“洗澡”比喻滤波过程,用“电话降噪”解释原理,小白秒懂!


🎧 一、什么是滤波?

想象你在嘈杂的菜市场打电话

  • 你想说:“今天温度是25度。”
  • 但背景有喇叭声、叫卖声、狗叫声……
  • 对方听到的是:“今…嗞嗞…25…嗡嗡…度?”

这时候,如果手机有个智能降噪功能,只保留你的声音、去掉杂音——这就是滤波

🔍技术定义
滤波就是在信号处理中,去除噪声或不需要的频率成分,保留有用信息的过程。


❓ 二、为什么要滤波?

在真实世界中,传感器采集的数据从来不是“干净”的:

噪声来源举例
环境干扰电磁干扰、电源波动
硬件误差ADC 量化误差、接触不良
突发干扰开关抖动、电机启停

如果不滤波:

  • 温度读数忽高忽低
  • 电机控制频繁抖动
  • 数据分析结果失真

滤波的作用
让数据更稳定、可靠、可信,就像给脏衣服“洗个澡”,焕然一新!


🧰 三、4 种常用滤波算法详解

1. 限幅滤波(Limit Filter)—— “设个安全围栏”

📌 原理

把数据限制在合理范围内,超出就“裁掉”。

🎯 使用场景
  • 传感器偶尔跳变(如 ADC 读到 0 或 4095 的异常值)
  • 已知物理量不可能超过某范围(如温度 -10℃ ~ 60℃)
✅ 优点:简单、快速
❌ 缺点:不能平滑连续噪声
void limit_value(uint32_t *data, int size, uint32_t min_val, uint32_t max_val) { for (int i = 0; i < size; i++) { // 修复:i++ → i++ if (data[i] < min_val) { data[i] = min_val; } else if (data[i] > max_val) { data[i] = max_val; } } }

💡生活比喻:就像给水位设上下限——太高溢出、太低干涸,系统自动“拉回”安全区。


2. 中值滤波(Median Filter)—— “取中间靠谱值”

📌 原理

对窗口内数据排序,取中位数。能有效消除脉冲噪声(尖峰干扰)。

🎯 使用场景
  • 图像去噪(椒盐噪声)
  • 传感器受瞬时干扰(如按键抖动、电机火花)
✅ 优点:抗尖峰干扰强,保留边缘
❌ 缺点:计算量大,不适合高频实时系统
#include <stdlib.h> #include <string.h> int compare(const void *a, const void *b) { return (*(uint32_t *)a - *(uint32_t *)b); } uint32_t mid_value(uint32_t *data, int size) { uint32_t *copy = (uint32_t *)malloc(size * sizeof(uint32_t)); memcpy(copy, data, size * sizeof(uint32_t)); qsort(copy, size, sizeof(uint32_t), compare); uint32_t median; if (size % 2 == 0) { // 修复:= → == median = (copy[size / 2 - 1] + copy[size / 2]) / 2; } else { median = copy[size / 2]; } free(copy); return median; }

💡生活比喻:10个人猜体重,去掉最高最低,取中间那个人的答案——更靠谱!


3. 算术平均滤波(Arithmetic Mean Filter)—— “大家投票取平均”

📌 原理

对 N 个采样值求平均,平滑小波动。

🎯 使用场景
  • 温度、湿度等缓慢变化的传感器
  • 需要降低随机噪声
✅ 优点:平滑效果好
❌ 缺点:响应慢,可能滞后;对突发噪声无效
uint32_t avg_value(uint32_t *data, int size) { uint32_t sum = 0; for (int i = 0; i < size; i++) { // 修复:i++ → i++ sum += data[i]; } return sum / size; }

💡生活比喻:考试去掉一个最高分、一个最低分,再算平均分——更公平!


4. 一阶滞后滤波(First Order Lag Filter)—— “温柔地跟随变化”

📌 原理

一种低通滤波器,输出 = α × 当前值 + (1−α) × 上次输出

  • α 越小,越平滑,但响应越慢
🎯 使用场景
  • 压力、液位、温度等缓慢变化的信号
  • 需要平滑曲线且保留趋势
✅ 优点:内存占用小(只需存上次值),平滑自然
❌ 缺点:对快速变化信号反应迟钝
uint32_t adc_filter(uint32_t CurrValue) { static uint32_t LastValue = 0; // 初始值设为0 // 等效于:LastValue = 0.25 * CurrValue + 0.75 * LastValue uint32_t tmp = (32 * CurrValue + 96 * LastValue) >> 7; // 修复:> → >> LastValue = tmp; return LastValue; }

🔧公式解析
(32 + 96) = 128>>7相当于/128
所以:tmp = (32/128)*Curr + (96/128)*Last = 0.25*Curr + 0.75*Last

💡生活比喻:老司机开车——不猛踩油门,也不急刹车,平稳跟车!


📈 四、滤波前后对比分析

下图展示了四种滤波算法对同一组含噪声原始数据(灰色虚线)的处理效果:

滤波类型曲线颜色效果描述
限幅滤波蓝色抑制了过大的噪声峰值,但保留了其他波动
中值滤波绿色有效去除尖锐脉冲,曲线更平滑
算术平均滤波橙色明显平滑,消除了小幅抖动
一阶滞后滤波红色温和跟踪信号,无突变,适合慢变信号

📊结论:没有“最好”的滤波,只有“最合适”的滤波!


🧪 五、使用场景与对比总结

滤波类型适用场景优点缺点
限幅滤波抑制突发性异常值实现简单、速度快无法平滑连续噪声
中值滤波脉冲噪声、图像处理强力去除尖峰,保边缘计算开销大
算术平均滤波平滑传感器数据效果稳定、易实现信号滞后,怕突变
一阶滞后滤波低频慢变信号内存小、平滑自然响应速度慢

📦 六、完整头文件示例(filter.h)

#ifndef __FILTER_H #define __FILTER_H #include <stdint.h> void limit_value(uint32_t *data, int size, uint32_t min_val, uint32_t max_val); int compare(const void *a, const void *b); uint32_t mid_value(uint32_t *data, int size); uint32_t avg_value(uint32_t *data, int size); uint32_t adc_filter(uint32_t CurrValue); #endif

🧠 本章口诀(背下来!)

🧼滤波就像洗个澡,脏数据变干净好!
🚧限幅设个安全区,异常值全踢掉!
🎯中值专治尖峰扰,排序取中真可靠!
📊平均投票最公平,小幅抖动全抹平!
🐢一阶滞后慢慢走,温柔平滑不抖手!
🔍选对滤波是关键,场景匹配才高效!


这份笔记完整覆盖了滤波所有内容,包括:

  • 滤波概念与必要性
  • 4种算法原理、代码、场景、优缺点
  • 代码细节修复(如i++==>>等)
  • 对比图表描述
  • 头文件与函数注释

现在,你不仅能理解滤波的意义,还能根据项目需求选择最合适的“洗澡方式”,让你的数据干干净净、稳稳当当!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询