实时中值滤波 + 低通滤波 示例程序(STM32环境)

一、功能概述

本示例实现两个滤波器:

  • 中值滤波器(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 范围内奇数;
  • 实际效果图:
相关推荐
comyccccc19 分钟前
平衡车底板设计:精准布局与高效布线学习笔记
单片机·嵌入式硬件
La Pulga30 分钟前
【FreeRTOS源码学习笔记】任务创建
笔记·stm32·mcu·学习·嵌入式·freertos·实时操作系统
芯片人0071 小时前
GEK100系列芯片进入上市公司上海移远通信供应链
人工智能·单片机·嵌入式硬件·物联网·芯片
fly_sunnn2 小时前
ADC模数转换器
单片机·嵌入式硬件
我叫洋洋3 小时前
I2C 为什么必须用开漏输出?从推挽短路、线与,到上拉电阻取值
单片机·嵌入式硬件
无敌贵点大王3 小时前
从寄存器层面重学STM32(5)——串口USART理论部分
stm32·单片机·嵌入式硬件
女神下凡3 小时前
芯参谋(83):AliOS Things_驱动开发指南
arm开发·驱动开发·单片机·嵌入式硬件·设计规范·1024程序员节
女神下凡3 小时前
芯参谋(84):Linux eMMC 驱动开发指南
linux·运维·arm开发·驱动开发·单片机·嵌入式硬件
szxinmai主板定制专家15 小时前
X86 工控机 vs RK3588 异构主控:AMR 控制器 BOM、散热、长期运维对比
运维·stm32·单片机·嵌入式硬件·fpga开发·am62x
HQB202617 小时前
屹晶微电子 EG1130|2‑24V 输入 / 最高 28V 输出 内置 MOS 异步升压 DC‑DC|SOT23‑6|摄像头 / 车充 / 电池充电电源
嵌入式硬件·硬件工程