前面闲来无事,整理了下平时用得比较多的部分MCU滤波算法,当然 代码网上都有,我只是做了一个搬运工,合并了一些算法,整理成模块函数,需要用的时候直接调用就可以。 这里简单介绍包含的内容,详细代码和使用说明在附件里。大家可自行查阅。
AD滤波算法函数模块说明: 一、该模块包含滤波算法有:中位值滤波、中位值平均滤波、递推平均滤波、一阶滞后滤波。用户可根据项目不同情况选用不同的滤波算法。 1.1、中位值滤波:连续采样N次(N取奇数),把N次采样值按大小排列,取中间值为本次有效值。适用范围能有效克服因偶然因素引起的波动干扰,对温度、液位的变化缓慢的被测参数有良好的滤波效果。不过对流量、速度等快速变化的参数不宜。 1.2、中位值平均滤波:连续采用N个数据,去掉一个最大值和一个最小值,然后计算N-2个数据的算术平均值。适用范围:对应偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差。但是测量速度较慢, 比较浪费RAM。 1.3递推平均滤波:把连续取N个采样值看成一个队列,队列的长度固定为N,每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据,把队列中得N个数据进行算术平均运算,就可以获得新的滤波结果。 适用范围:对周期性干扰有良好的抑制作用,平滑度高,适用于高频振荡的系统。缺点是灵敏度低,对偶然出现的脉冲性干扰的抑制作用较差,不易消除由于脉冲干扰所引起的采样值偏差,不适用于脉冲干扰比较严重的场合。 1.4、一阶滞后滤波:对周期性干扰具有良好的抑制作用,适用于波动频率较高得场合。缺点就是相位滞后,灵敏度低,滞后程度取决于a的大小,不能消除滤波频率高于采样频率1/21/2的干扰信号。本次滤波结果result=(1-a)*本次采样值+a*上次值。a=(0~1) 二、滤波函数 2.1、中位值/中位值平均滤波函数 函数名:FILTER_median(TYPE_STATE Flag) 输入值:Flag:选择中位值滤波或中位值平均滤波 ON:中位值平均滤波 OFF:中位值滤波 返回值:滤波结果 2.2、递推平均滤波函数 函数名:FILTER_recursive() 输入值:无 返回值:sum:滤波结果 2.3、一阶滞后滤波函数 函数名:FILTER_firstorder() 输入值:无 返回值:value:滤波结果 备注:在干电池剩余电量检测中,经过测试对比数据,使用中位值平均滤波算法比较合适。数据整体表现平稳,灵敏度较高,脉冲干扰直接滤除。测试数据如下:
单片机源程序如下:
- /*********************************************************
- *文件名: filter.h
- *日 期: 2018/7/26
- *描 述: AD滤波算法函数头文件
- *备 注:
- **********************************************************/
- #ifndef __FILTER_H__
- #define __FILTER_H__
- //typedef unsigned char uint8_t;
- //typedef unsigned short int uint16_t;
- //typedef unsigned int uint32_t;
- //typedef unsigned __int64 uint64_t;
- typedef enum {OFF = 0x0, ON = 0x1} TYPE_STATE;
- extern unsigned short int meanvalue; // ADC值声明 meanvalue根据情况改变
- #define AD_VALUE meanvalue // ADC采集值 meanvalue根据情况改变可直接宏定义AD函数
- #define A 50 // 一阶滞后滤波系数
- #define N 9 // 采样次数 不同的滤波方法取值不同
- #define TIME 300 //AD读取延时,等待AD采集完成 大致够AD采集时间即可
- /******** 函******* 数 ******* 声 ******* 明 ********/
- unsigned short int FILTER_limit(void); //限幅滤波
- unsigned short int FILTER_median(TYPE_STATE Flag); //中位值滤波 中位值平均滤波 Flag:中位值平均滤波使能
- unsigned short int FILTER_recursive(void); //递推平均滤波
- unsigned short int FILTER_firstorder(void); //一阶滞后滤波
- #endif
复制代码
所有资料51hei提供下载:
|