一、功能概述
本示例实现两个滤波器:
- 中值滤波器(Median Filter):对短期异常值(如尖峰噪声)有良好的抑制能力;
- 低通滤波器(Low-Pass Filter):对数据进行平滑处理,适合去除高频抖动。
适用于如 ADC传感器数据处理、电子秤、电流电压读取等场景。
二、代码结构说明
✅ 头文件 filter.h
c
#ifndef FILTER_H
#define FILTER_H
#define WINDOW_SIZE 50
typedef struct {
int buffer[WINDOW_SIZE]; // 数据缓冲区
int index; // 当前写入索引(环形)
int count; // 当前已存数据个数
} MedianFilter;
extern MedianFilter myMedianFilter;
void medianInit(MedianFilter* filter);
int medianFilter(MedianFilter* filter, int new_value);
int lowPassFilter(int input);
#endif
✅ 源文件 filter.c
🔹 中值滤波器实现
c
#include "filter.h"
#include <stdlib.h>
// 冒泡排序用于求中值(可替换为更高效算法)
static void sort_array(int* src, int* dst, int size) {
for (int i = 0; i < size; i++) dst[i] = src[i];
for (int i = 0; i < size - 1; i++) {
for (int j = i + 1; j < size; j++) {
if (dst[i] > dst[j]) {
int temp = dst[i];
dst[i] = dst[j];
dst[j] = temp;
}
}
}
}
// 初始化滤波器状态
void medianInit(MedianFilter* filter) {
for (int i = 0; i < WINDOW_SIZE; i++)
filter->buffer[i] = 0;
filter->index = 0;
filter->count = 0;
}
// 中值滤波主函数
int medianFilter(MedianFilter* filter, int new_value) {
filter->buffer[filter->index] = new_value;
filter->index = (filter->index + 1) % WINDOW_SIZE;
if (filter->count < WINDOW_SIZE)
filter->count++;
int sorted[WINDOW_SIZE];
sort_array(filter->buffer, sorted, filter->count);
if (filter->count % 2 == 1)
return sorted[filter->count / 2];
else
return (sorted[filter->count / 2 - 1] + sorted[filter->count / 2]) / 2;
}
🔹 低通滤波器实现
c
int lowPassFilter(int input) {
static int prev_output = 0;
uint8_t alpha_shift = 3; // α = 1/8,越大越平滑
prev_output = prev_output + ((input - prev_output) >> alpha_shift);
return prev_output;
}
✅ 主函数测试示例
c
#include <stdio.h>
#include "filter.h"
MedianFilter myMedianFilter;
int mainTest() {
medianInit(&myMedianFilter);
int data[] = {100, 102, 98, 500, 101, 99, 97, 103};
int len = sizeof(data) / sizeof(data[0]);
for (int i = 0; i < len; i++) {
int medFiltered = medianFilter(&myMedianFilter, data[i]);
int lpFiltered = lowPassFilter(data[i]);
printf("Raw: %d\tMedian: %d\tLowPass: %d\n", data[i], medFiltered, lpFiltered);
}
return 0;
}
三、使用说明
- 可移植至 STM32 项目,适合 ADC 滤波等场景;
- 中值滤波适合抗冲击干扰,低通滤波适合抑制小幅高频抖动;
WINDOW_SIZE
可根据实际采样频率和响应速度调整;- 建议中值窗口不宜过大,推荐 5~51 范围内奇数;
- 实际效果图: