一:限幅滤波
- 思路 先根据经验判断,确定两次采样允许的最大误差(设为A)每次检测到新采样数据值时进行判断:如果本次新采样数值与上次采样的数据值差<=A,
则本次采样值有效,令本次采样结果=新采样值;如果本次采样的值和上次采样的结果差是>A则认为本次采样值无效,放弃本次采样的值,滤波结果=上次采样值。 - 优点 能有效克服因偶然因素引起的脉冲干扰。
- 缺点 无法抑制那种周期性干扰,且平滑性差。
- 例程
/***************************************************
函数名称:AmlitudeLimiterFilter()――限幅滤波法(程序判断滤波法)
*说明:
1调用函数
GetAD(),该函数用来取得当前采样值
2变量说明
Value: 最近一次采样的值,该变量为全局变量
NewValue: 当前采样的值
ReturnValue: 返回值
3常量说明
A:两次采样的最大误差值,该值需要使用者根据实际情况设置
*入口: Value, 上次有效的采样值,在主程序里赋值
*出口:ReturnValue,返回值,本次滤波的值
***************************************************/
#define A 10
unsigned char Value;
unsigned char AmplitudeLimiterFilter()
{
unsigned char NewValue;
unsigned char ReturnValue;
NewValue = GetAD();
if( ( (NewValue-Value)>A ) || ( (Value-NewValue)>A ) )
ReturnValue = Value;
else ReturnValue = NewValue;
return (ReturnValue);
}
二:中位值滤波
- 思路 连续采样N次,把N次采样值按大小排列,取中间值为本次有效值。
- 优点:能有效克服因偶然因素引起的波动干扰,对温度、液位等缓慢变化的被测量参数良好的滤波效果。
- 缺点:对流量、速度等快速变化的参数不宜。
- 例子:
/********************************************************
*函数名称:MiddleValueFilter()――中位值滤波法
*说明 :
1 调用函数
GetAD(), 该函数用来获得当前的采样值
Delay(), 基本延时函数
2变量说明
ArrDataBuffer[N], 用来存放一次性采样的N组数据
Temp, 完成冒泡法使用的临时寄存器
I,j,k,循环使用的参数值
3常量说明
N ,数组的长度
*入口:
*出口:ArrDataBuffer[(N-1)/2],返回值,本次滤波的结果
********************************************************/
unsigned char MiddleValueFilter()
{
unsigned char i,j,k;
unsigned char Temp;
unsigned char ArrDataBuffer[N];
for(i=0; i<N; i++)
{
ArrDataBuffer[i] = GetAD();
Delay();
}
for(j=0; j<N-1; j++)
{
for(k=0; k<N-j; k++)
{
if(ArrDataBuffer[k] > ArrDataBuffer[k+1] )
{
Temp = ArrDataBuffer[k];
ArrDataBuffer[k] = ArrDataBuffer[k+1];
ArrDataBuffer[k+1] = temp;
}
}
}
return (ArrDataBuffer[ (N-1)/2 ]) ;
}
三:算术平均滤波法
- 思路 连续取N个采样值进行算术平均运算(N较大时平滑性好但是灵敏度差,反之,则相反。)
- 优点:对一般随机的干扰的信号进行滤波,这种信号的特点是一个平均值,信号一般在一个范围内波动。
- 对于测量速度慢或要求数据计算快的实时控制不适用。且比较消耗RAM
- 例程:
/**********************************************************
*函数名称:ArithmetcalAverageValueFilter() ――算术平均滤波法
*说明
1调用函数
GetAD(), 该函数用来取得当前采样值
Delay(), 基本延时函数
2变量说明
Value,平均值
Sum,连续采样之和
i,循环使用的变量
3常量说明
N, 数组的长度
*入口:
*出口:Value,返回值,本次滤波结果
**********************************************************/
#define N 12
unsigned char ArithmeticalAvergeValueFilter()
{
unsigned char i;
unsigned char Value;
unsigned short Sum;
Sum = 0;
for(i=0; i<N; i++)
{
Sum += GetAD();
Delay();
}
Value /= N;
return Value;
}
四:递推平均滤波法
- 思路: 把连续N个采样值看成一个队列,队列的长度固定为N。每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据(先进先出原则)。把队列中N个数据进行平均运算,得到的结果为本次滤波的结果。(要选择合适的N)
- 优点 对周期性干扰有良好的抑制作用,平滑度高,适用于高频振荡的系统。
- 缺点 灵敏度低。对偶然出现的脉冲性干扰作用差;不易消除由脉冲干扰所引起的采样值偏差,不合适脉冲干扰比较严重的场合。消耗RAM大。缺点 灵敏度低。对偶然出现的脉冲性干扰作用差;不易消除由脉冲干扰所引起的采样值偏差,不合适脉冲干扰比较严重的场合。消耗RAM大。
- 例程
/************************************************
*函数名称 GlideAverageValueFilter() ――递推平均滤波法
*说明
1调用函数
GetAd(), 该函数用来取得当前采样值
Delay(), 该函数延时
2变量说明
Data[], 暂存数据的数组属于全局变量
Value,平均值
Sum,连续采样之和
i 循环变量
3常量说明
N, 数组的长度
*入口:Data[],暂存数据
*出口:Value, 返回值,本次滤波结果
************************************************/
#define N 12
unsigned char Data[N];
unsigned char GlideAverageValueFilter( Data[0] )
{
unsigned char i;
unsigned char Value;
unsigned short Sum;
Sum = 0;
Data[N-1] = GetAD();
for(i=0; i<N-1; i++)
{
Data[i] = Data[i+1];
Sum += Data[i];
}
Value = Sum / N;
return (Value);
}
五:中位值平均滤波法
- 思路 连续采样N个采样值,去掉一个最大和最小值,然后计算N-2个数据的平均值
- 融合了中位值滤波法和平均值滤波法的优点,对于偶然性出现的脉冲干扰,可消除由其引起的采样偏差。对周期性干扰有良好的抑制作用,平滑度高,适用于高频振荡场合。
- 缺点和算术平均滤波法一样,测量速度慢比较浪费RAM.
- 例程:
/**************************************************
*函数名称 MiddleAverageValueFilter()――中位值平均滤波法
*说明
1函数调用
GetAD(),获取当前数据函数
Delay(), 基本的延时函数
2变量说明
ArrDataBuffer[N] ,用来存放一次性采样值的N组数据
Temp, 完成起泡法使用的临时存放寄存器
i,j,k,循环使用的参数值
Value,平均值
Sum,连续采样之和
3常量说明
N,数组长度
*入口:
*出口:Value, 返回值,本次滤波结果
**************************************************/
#define N 12
unsigned char MidleAverageValueFilter()
{
unsigned char i,j,k,l;
unsigned char Temp;
unsigned char ArrDataBuffer[N];
unsigned short Sum;
unsigned char Value;
//采样N组数据,放入ArrDataBuffer[]中
for( i=0; i<N; i++)
{
ArrDataBuffer[i] = GetAD();
Delay();
}
//采样值由小到大排列,排列采用起泡法
for(j=0; j<N-1; j++)
{
for(k=0; k<N-j; k++)
{
if( ArrDataBuffer[k] > ArrDataBuff[k+1] )
{
Temp = ArrDataBuffer[k];
ArrDataBuffer[k] = ArrDataBuffer[k+1];
ArrDataBuffer[k] = Temp;
}
}
}
//去掉最小和最大值,并求和
for(l=1; l<N-1; l++) {
Sum += ArrDataBuffer[l];
}
Value = Sum/(n-2);
return (Value);
}
六:递推中位值平均滤波法
- 思路: 中位值滤波法+递推平均滤波法
把连续N 个采样值看成一个队列,把长度固定为N每次新采样值放在队尾并把原队首的数据扔掉。把队列中N个数据的最大和最小值去掉,然后再计算N-2个数据的平均值。 - 优点: 融合两种滤波法,对于偶然出现的脉冲干扰可消除由其引起的采样 值偏差。
- 缺点 : 比较浪费RAM
- 例程
/****************************************************
*函数名称 filer( char NEW_DATA, char QUEUE[], char n )
*说明
1调用函数
2变量
max ,存放数据中的最大值
min , 存放数据中的最小值
sum, 存放所有采样值之和
i 循环变量
3常量说明
*入口: NEW_DATA = 新采样值
QUEUE = 队列
n = 队列长度
*出口: sum = 滤波结果
***************************************************/
char filter( char NEW_DATA ,char QUEUE[] , char n ) {
char max;
char min;
int sum;
char i;
QUEUE[0] = NEW_DATA;
max = QUEUE[0];
min = QUEUE[0];
sum = QUEUE[0];
for( i=n-1 ; i!= 0; i--) {
if( QUEUE[i] > max )
max = QUEUE[i];
else if( QUEUE[i] < min )
min = QUEUE[i];
sum += QUEUE[i];
QUEUE[i] = QUEUE [i-1];
}
i = n-2;
sum = sum – max – min + i/2;
//说明 +i/2 是为了四舍五入
sum = sum/2;
return sum;
}
七:限幅平均滤波法
- 思路 限幅滤波+递推平均滤波法。每次采样的数据先进行限幅滤波后,再放入队列中进行递推平均滤波处理
- 优点 融合两种滤波的优点,对于偶然出现的脉冲干扰,可消除由于脉冲干扰引起的采样偏差。优点 融合两种滤波的优点,对于偶然出现的脉冲干扰,可消除由于脉冲干扰引起的采样偏差。
- 缺点 比较消耗RAM
- 例程
/***********************************************
*函数名称 LimitRangeAverageValueFilter()――限幅平均滤波法
*说明
1调用函数
GetAD(),获取当前采样值
Delay(), 基本延时函数
2变量说明
Value,平均值
Sum,队列采样值之和
i ,循环变量
3常量说明
N ,数组长度
*入口:Data[] 队列存放数组
*出口:Value 滤波的平均值
***********************************************/
#define A 10
#define N 12
unsigned char Data[N];
unsigned char LimitRangeAverageValueFilter( Data[] )
{
unsigned char i;
unsigned char Value;
unsigned short Sum;
Data[N] = GetAD();
if( ( (Data[N] – Data[N-1] ) >A ) || ( (Data[N-1] – Data[N] ) >A ) )
Data[N] = Data[N-1];
Sum = Data[N];
for(i=0; i<N-1; i++)
{
Data[i] = Data[i+1];
Sum += Data[i];
}
Value = Sum/N;
return Value;
}
八:一阶滞后滤波法
- 思路 本次滤波结果 = a * 本次采样值 + (1-a)*上次滤波结果
a代表滤波系数,a = 0~1; - 优点 对周期性干扰具有良好的抑制作用,适用于波动频率较高的场合相对于各类平均滤波的方法来说,一阶滤波比较节省RAM空间
- 缺点 相位滞后,灵敏度。滞后程度取决于a值大小。另外,这种方法不能消除滤波频率高于1/2采样频率的干扰信号。
对于没有乘法的和除法的运算指令单片机来说,运算工作量大 - 例程
/***************************************************
*函数名称 OneFactorialFilter()――一阶滞后滤波法
*说明
1调用函数
GetAd(),该函数用来获取当前取样值
Delay(),基本延时函数
2变量说明
Value,上次滤波结果
NewValue,本次采样值
3常量说明
A 滤波系数
*入口:
*出口:ReturnValue 返回值,本次滤波结果
***************************************************/
#define A 128
unsigned char Value;
unsigned char OneFactorialFilter()
{
unsigned char NewValue;
unsined char ReturnValue;
NewValue = GetAD();
ReturnValue = (255-a)*NewValue + a*Value;
ReturnValue /= 255;
return (ReturnValue);
}
九;消抖滤波法
- 思路:设置一个滤波计数器。将每次采样值与当前值比较。如果采样值=当前值,则计数器清0;如果采样值不等于当前值,则计数器+1。然后判断计数器是否》=上限N。如果计数器溢出,则将本次值替换当前有效值,并清计数器。
- 优点 对于变化缓慢的被测参数良好的滤波效果。可避免在临界值附近控制器的反复开/关跳动或显示器上数数值抖动
- 缺点 对快速变化不宜。而且,如果在计数器溢出的那一次采样到的值恰好是干扰值则会将干扰值当作有效值导入系统。
- 例程
/************************************************
*函数名称 AvoidDitheringFilter()――消抖滤波法
*说明 1调用函数
GetAD(),该函数用来取得当前采样值
2变量说明
Count,滤波计数器,该变量为全局变量
Value,当前有效值,该变量为全局变量
NewValue, 当前采样值
3常量说明
N 滤波计数器阈值
*入口
*出口:Value ,返回值,本次滤波结果
************************************************/
#define N 20
unsigned char Count;
unsigned char Value;
unsigned char AvoidDitheringFilter()
{
unsigned char NewValue;
NewValue = GetAD();
if( NewValue == Value )
Count = 0;
else
{
Count++;
if(Count>N)
{
Count=0;
Value = NewValue;
}
}
return (Value);
}
还有一个叫加权递推滤平均滤波法将不再介绍了