目录
一.滤波种类
1. 1 限幅滤波
优点:克服偶然因素引入的脉冲干扰
缺点:周期性干扰无法去除、平滑度差
1.2 中值滤波
优点:克服偶然因素引起的干扰,对缓慢变化的被测量效果良好
缺点:对流量、速度等快速变化参数不宜采用,对较大的N占用RAM和处理器较多
1.3 算术平均滤波
优点:可对具有随机干扰的信号进行处理,这类信号一般具有一个平均值,信号会在某一数值范围附近上下波动
缺点:不适用于高速数据应用,灵敏程度与平滑程度与N有关,RAM和处理速度由N值决定
1.4 递推平均滤波
优点:对周期性干扰有良好的抑制作用,平滑度高
缺点:灵敏度较低,对偶发脉冲干扰抑制作用较弱,不易消除由脉冲干扰引起的采样值的偏差,费RAM
1.5 中值平均滤波
优点:综合了两种滤波方法的有点,抑制脉冲干扰
缺点:只适合用于速度较慢的场合,RAM由N决定
1.6 限幅平均滤波
优点:抑制偶发脉冲干扰,消除由此引入的采样的偏差
缺点:不适合高速信号的处理,RAM资源由N决定
1.7 一阶滞后滤波
优点:适用于波动频率较高的场合,对周期性干扰具有良好的抑制作用,运算量不大
缺点:造成相位滞后,灵敏度低,不能消除频率高于采样率1/2的干扰信号
1.8 加权递推平均滤波
优点:适用于较大纯滞后时间常数的对象和采样周期较短的系统
缺点:对纯滞后时间常数较小,采样周期较长,变化缓慢的信号不能迅速反应系统当前所受干扰严重程度,滤波效果差
1.9 消抖滤波
优点:对变化缓慢的被测参数有较好的滤波效果,可避免在临界值附近控制器的反复开、关跳动或显示器上数值的抖动
缺点:对快速变化的参数不宜,若计数器溢出的那一次采样到的正好是干扰,则干扰会被当成有效值导入系统
1.10 限幅消抖滤波
优点:限幅和消抖的优点,改进了消抖滤波的缺陷,避免将干扰值导入系统
缺点:对于快速变化的参数不宜使用
二.滤波介绍
2.1限幅滤波
根据采集的数据,若当前采集值较前一次采集值相差维持在一定的偏差内,则将
每次采集到的数据和前一次的数据进行比较,若其差的绝对值大于某一特定值,则认为是干扰数据,继续输出上一次的数据,反之 ,则认为数据有效
代码:
#define uint unsigned int
#define uchar unsigned char
uchar A[]={100,110,106 ,108,130,100,100,100,101,102} ;
uchar get_ad_val()
{
uchar ad_val;
return ad_val;
}
/*限幅滤波参考程序*/
#define Amp 10
uchar value
uchar Amplitude_Fliter()
{
uchar new_value;
new_value=get_ad_val();
if((new_value-value )>Amp || (value-new_value) >Amp)
return value; //其余情况,本次值无效
return new_value; //若本次与上次之差<=Amp,本次无效
}
2.2中位值滤波
进行连续的N此采样,把N次采样的值按照大小进行排列,取其中间一个值(N为奇数)或中间两个值的平均值(N为偶数)作为中值,N的大小决定了平滑程度和灵敏程度
代码:
/*中值滤波参考程序*/
#define N 11
uchar Median_Fliter()
{
uchar value[N];
uchar count,i,j,temp;
for(count=0;count<N;count++)//获取采样值
value[count]=get_ad_val();
for(j=0;j<N-1;j++) //冒泡排序法
{
for(i=0;i<N-j;i++) // { // if(value[i]>value[i+1])
{
temp=value[i];
value[i]=value[i+1];
value[i+1]=temp;
}
}
}
return value[(N+1)/2];
}
2.3算术平均滤波
过程与中值滤波类似,但是取的是算术平均值
代码:
/*算术平均滤波*/
#define N 12
uchar Aver_Fliter()
{
uchar count;
int sum=0;
for(count=0;count<N;count++)
{
sum+=get_ad_val();
}
return (uchar)(sum/N);
}
2.4递推平均滤波(滑动平均滤波)
N个采样序列设为一个FIFO(先入先出)队列,每次采样值加入队列尾部,最旧的值出队列并舍弃,每次对队列内现有的元素取平均值作为此次采样值,队列的长度是一定的使用时,存储空间本身应预先存有一定量的(N)数据
代码:
/*递推平均滤波**/
#define N 12
uchar value[N];
uchar i=0;
uchar Raver_Fliter()
{
uchar count;
int sum=0;
value[i++]=get_ad_val();
if(i==N)i=0;//保证FIFO
for(count=0;count<N;count++)
sum+=value[count];
return (uchar)(sum/N);
}
2.5中值平均滤波(防脉冲干扰平均滤波)
中值滤波和算术平均滤波的思想相结合,采N个数据,去掉一个最大值,去掉一个最小值,求剩下的数据的平均值作为采样值
代码:'
/*中值平均滤波*/
#define N 12
uchar Median_Avr_Fliter()
{
uchar count,i,j,temp;
uchar value[N];
int sum=0;
for(count=0;count<N;count++)
value[count]=get_ad_val();
for(j=0;j<N-1;j++)//冒泡排序,也可以换成其他比较大小的方式
{
for(i=0;i<N-j;i++)
{
temp=value[i];
value[i]=value[i+1];
value[i+1]=temp;
}
}
for(count=1;count<N-1;count++)
sum+=value[count];
return (uchar)(sum/(N-2));
}
2.6限幅平均滤波
限幅滤波+递推平均滤波,每次采样得到的数据先进行限幅处理,再送入队列进行平均滤波处理
代码:
/*限幅平均滤波*/
#define N 12
#define Amp 10
uchar value[N]
uchar i=0;
uchar value;
uchar Amplitude_Fliter()
{
uchar new_value;
new_value=get_ad_val();
if(new_value-value>Amp ||(value-new_value)>Amp)
return value;
return new_value;
}
// 调用了限幅滤波函数
uchar Raver_Fliter()
{
uchar count;
int sum=0;
value[i++]=Amplitude_Fliter();
if(i==N) I=0; //保证FIFO;
for(count=0;count<N;count++)
sum+=value[count];
return (uchar) (sum/N);
}
2.7一阶滞后滤波
取一个比例常数k(0<k<1),本次输出的结果=k本次采样值+(1-k)前一次的输出值,输出由本次和前一次共同决定,影响程度由k决定,阶数可扩展。
代码:
/*一阶滞后滤波*/
#define a 50
uchar value;
uchar Delay_Fliter()
{
uchar new_value;
new_value=get_ad_val();
return (uchar)( ( (100-a)*value+a*new_value) /100);
}
2.8加强递归平均滤波
对递归平均滤波的改进,不同时刻采样数据具有不同的权重。通常是距离当前时刻越近,权重越大,给新的采样值的权重越大,灵敏度越高,信号平滑度越低.
代码:
/*加权递归平均滤波*/
#define N 12
uchar code coe[N]={1,2,3,4,5,6,7,8,9,10,11,12};
uchar code sum_coe=78;
uchar Weighting_Fliter()
{
uchar count;
uchar value[N];
int sum=0;
for(count=0;count<N;count++)
value[count]=get_ad_val();
for(count=0;count<N;count++)
sum+=value[count]*coe[count];
return (uchar)(sum/sum_coe);
}
2.9消抖滤波
设置一个滤波计数器,将每次采样值和当前的有效值进行比较,若采样值等于当前有效值,则计数器清零;反之,计数器加1,并判断滤波计数器是否达到设置的溢出上限,若计数器溢出,则将本次的值替换当前有效值,并清零计数器
代码:
/*消抖滤波*/
#define N 12
uchar value;
uchar EL_Fliter()
{
uchar count=0;
uchar new_value;
new_value=get_ad_val();
while(value!=new_value)
{
count++;
if(count>=N)return new_value;
new_value=get_ad_val();
}
return value;
}
2.10限幅消抖滤波
限幅滤波+消抖滤波,先限幅,后消抖
代码:
*限幅消抖滤波参考程序*/
/*先限幅,后消抖*/
#define Amp 10
#define N 12
uchar value;
uchar Amplitude_Fliter()
{
uchar new_value;
new_value=get_ad_val();
if((new_value-value>Amp)||(value-new_value>Amp))
return value; //其余情况下,本次值无效
return new_value; //若本次与上次之差<=Amp,本次值有效
}
//调用 限幅滤波函数Amplitude_Fliter()
uchar EL_Fliter()
{
uchar count=0;
uchar new_value;
new_value=Amplitude_Fliter()
while(value!=new_value)
{
count++;
if(count>=N)return new_value;
new_value=Amplitude_Fliter()
}
return value;
}
打赏作者