10种软件滤波方法
1、限幅滤波法(又称程序判断滤波法)
A、方法:
根据经验判断,确定两次采样允许的最大偏差值(设为A)
每次检测到新值时判断:
如果本次值与上次值之差<=A,则本次值有效
如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值
B、优点:
能有效克服因偶然因素引起的脉冲干扰
C、缺点
无法抑制那种周期性的干扰
平滑度差
2、中位值滤波法
A、方法:
连续采样N次(N取奇数)
把N次采样值按大小排列
取中间值为本次有效值
B、优点:
能有效克服因偶然因素引起的波动干扰
对温度、液位的变化缓慢的被测参数有良好的滤波效果
C、缺点:
对流量、速度等快速变化的参数不宜
3、算术平均滤波法
A、方法:
连续取N个采样值进行算术平均运算
N值较大时:信号平滑度较高,但灵敏度较低
N值较小时:信号平滑度较低,但灵敏度较高
N值的选取:一般流量,N=12;压力:N=4
B、优点:
适用于对一般具有随机干扰的信号进行滤波
这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动
C、缺点:
对于测量速度较慢或要求数据计算速度较快的实时控制不适用
比较浪费RAM
4、递推平均滤波法(又称滑动平均滤波法)
A、方法:
把连续取N个采样值看成一个队列
队列的长度固定为N
每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则)
把队列中的N个数据进行算术平均运算,就可获得新的滤波结果
N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4
B、优点:
对周期性干扰有良好的抑制作用,平滑度高
适用于高频振荡的系统
C、缺点:
灵敏度低
对偶然出现的脉冲性干扰的抑制作用较差
不易消除由于脉冲干扰所引起的采样值偏差
不适用于脉冲干扰比较严重的场合
比较浪费RAM
5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
A、方法:
相当于“中位值滤波法”+“算术平均滤波法”
连续采样N个数据,去掉一个最大值和一个最小值
然后计算N-2个数据的算术平均值
N值的选取:3~14
B、优点:
融合了两种滤波法的优点
对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差
C、缺点:
测量速度较慢,和算术平均滤波法一样
比较浪费RAM
6、限幅平均滤波法
A、方法:
相当于“限幅滤波法”+“递推平均滤波法”
每次采样到的新数据先进行限幅处理,
再送入队列进行递推平均滤波处理
B、优点:
融合了两种滤波法的优点
对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差
C、缺点:
比较浪费RAM
7、一阶滞后滤波法
A、方法:
取a=0~1
本次滤波结果=(1-a)*本次采样值+a*上次滤波结果
B、优点:
对周期性干扰具有良好的抑制作用
适用于波动频率较高的场合
C、缺点:
相位滞后,灵敏度低
滞后程度取决于a值大小
不能消除滤波频率高于采样频率的1/2的干扰信号
8、加权递推平均滤波法
A、方法:
是对递推平均滤波法的改进,即不同时刻的数据加以不同的权
通常是,越接近现时刻的数据,权取得越大。
给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低
B、优点:
适用于有较大纯滞后时间常数的对象
和采样周期较短的系统
C、缺点:
对于纯滞后时间常数较小,采样周期较长,变化缓慢的信号
不能迅速反应系统当前所受干扰的严重程度,滤波效果差
9、消抖滤波法
A、方法:
设置一个滤波计数器
将每次采样值与当前有效值比较:
如果采样值=当前有效值,则计数器清零
如果采样值<>当前有效值,则计数器+1,并判断计数器是否>=上限N(溢出)
如果计数器溢出,则将本次值替换当前有效值,并清计数器
B、优点:
对于变化缓慢的被测参数有较好的滤波效果,
可避免在临界值附近控制器的反复开/关跳动或显示器上数值抖动
C、缺点:
对于快速变化的参数不宜
如果在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当作有效值导入系统
10、限幅消抖滤波法
A、方法:
相当于“限幅滤波法”+“消抖滤波法”
先限幅,后消抖
B、优点:
继承了“限幅”和“消抖”的优点
改进了“消抖滤波法”中的某些缺陷,避免将干扰值导入系统
C、缺点:
对于快速变化的参数不宜
10种软件滤波方法的示例程序
OurWay 发表于 2005-9-2 22:24:00
10种软件滤波方法的示例程序(JKRL)
假定从8位AD中读取数据(如果是更高位的AD可定义数据类型为int),子程序为get_ad();
1、限副滤波
/* A值可根据实际情况调整
value为有效值,new_value为当前采样值
滤波程序返回有效的实际值 */
#define A 10
char value;
char filter()
{
char new_value;
new_value = get_ad();
if ( ( new_value - value > A ) || ( value - new_value > A )
return value;
return new_value;
}
2、中位值滤波法
/* N值可根据实际情况调整
排序采用冒泡法*/
#define N 11
char filter()
{
char value_buf[N];
char count,i,j,temp;
for ( count=0;count<N;count++)
{
value_buf[count] = get_ad();
delay();
}
for (j=0;j<N-1;j++)
{
for (i=0;i<N-j;i++)
{
if ( value_buf>value_buf[i+1] )
{
temp = value_buf;
value_buf = value_buf[i+1];
value_buf[i+1] = temp;
}
}
}
return value_buf[(N-1)/2];
}
3、算术平均滤波法
#define N 12
char filter()
{
int sum = 0;
for ( count=0;count<N;count++)
{
sum + = get_ad();
delay();
}
return (char)(sum/N);
}
4、递推平均滤波法(又称滑动平均滤波法)
#define N 12
char value_buf[N];
char i=0;
char filter()
{
char count;
int sum=0;
value_buf[i++] = get_ad();
if ( i == N ) i = 0;
for ( count=0;count<N,count++)
sum = value_buf[count];
return (char)(sum/N);
}
5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
#define N 12
char filter()
{
char count,i,j;
char value_buf[N];
int sum=0;
for (count=0;count<N;count++)
{
value_buf[count] = get_ad();
delay();
}
for (j=0;j<N-1;j++)
{
for (i=0;i<N-j;i++)
{
if ( value_buf>value_buf[i+1] )
{
temp = value_buf;
value_buf = value_buf[i+1];
value_buf[i+1] = temp;
}
}
}
for(count=1;count<N-1;count++)
sum += value[count];
return (char)(sum/(N-2));
}
6、限幅平均滤波法
/*
*/
略 参考子程序1、3
7、一阶滞后滤波法
/* 为加快程序处理速度假定基数为100,a=0~100 */
#define a 50
char value;
char filter()
{
char new_value;
new_value = get_ad();
return (100-a)*value + a*new_value;
}
8、加权递推平均滤波法
/* coe数组为加权系数表,存在程序存储区。*/
#define N 12
char code coe[N] = {1,2,3,4,5,6,7,8,9,10,11,12};
char code sum_coe = 1+2+3+4+5+6+7+8+9+10+11+12;
char filter()
{
char count;
char value_buf[N];
int sum=0;
for (count=0,count<N;count++)
{
value_buf[count] = get_ad();
delay();
}
for (count=0,count<N;count++)
sum += value_buf[count]*coe[count];
return (char)(sum/sum_coe);
}
9、消抖滤波法
#define N 12
char filter()
{
char count=0;
char new_value;
new_value = get_ad();
while (value !=new_value);
{
count++;
if (count>=N) return new_value;
delay();
new_value = get_ad();
}
return value;
}
10、限幅消抖滤波法
/*
*/
略 参考子程序1、9
11、IIR 数字滤波器
A. 方法:
确定信号带宽, 滤之。
Y(n) = a1*Y(n-1) + a2*Y(n-2) + ... + ak*Y(n-k) + b0*X(n) + b1*X(n-1) + b2*X(n-2) + ... + bk*X(n-k)
B. 优点:高通,低通,带通,带阻任意。设计简单(用matlab)
C. 缺点:运算量大。
IIR滤波例子
int BandpassFilter4(int InputAD4)
{
int ReturnValue;
int ii;
RESLO=0;
RESHI=0;
MACS=*PdelIn;
OP2=1068; //FilterCoeff4[4];
MACS=*(PdelIn+1);
OP2=8; //FilterCoeff4[3];
MACS=*(PdelIn+2);
OP2=-2001;//FilterCoeff4[2];
MACS=*(PdelIn+3);
OP2=8; //FilterCoeff4[1];
MACS=InputAD4;
OP2=1068; //FilterCoeff4[0];
MACS=*PdelOu;
OP2=-7190;//FilterCoeff4[8];
MACS=*(PdelOu+1);
OP2=-1973; //FilterCoeff4[7];
MACS=*(PdelOu+2);
OP2=-19578;//FilterCoeff4[6];
MACS=*(PdelOu+3);
OP2=-3047; //FilterCoeff4[5];
*p=RESLO;
*(p+1)=RESHI;
mytestmul<<=2;
ReturnValue=*(p+1);
for (ii=0;ii<3;ii++)
{
DelayInput[ii]=DelayInput[ii+1];
DelayOutput[ii]=DelayOutput[ii+1];
}
DelayInput[3]=InputAD4;
DelayOutput[3]=ReturnValue;
// if (ReturnValue<0)
// {
// ReturnValue=-ReturnValue;
// }
return ReturnValue;
}
//------------------------------------------------------------------------------
防脉冲干扰移动平均值法数字滤波器的C语言算法及其实现
在许多的数据采集系统中,现场的强电设备较多,不可避免
地会产生尖脉冲干扰,这种干扰一般持续时间短,峰值大,对这样
的数据进行数字滤波处理时,仅仅采用算术平均或移动平均滤波
时,尽管对脉冲干扰进行了1/n的处理,但,其剩余值仍然较大。
这种场合最好的策略是:将被认为是受干扰的信号数据去掉,这
就是防脉冲干扰平均值滤波法的原理。
防脉冲干扰平均值滤波法的算法是:对连续的n个数据进行排序,
去掉其中最大和最小的2个数据,将剩余数据示平均值。
在一般8051单片机的应用中为了加快数据处理速度,n可以取值6。
而对于具有较快速度的处理器,则n值可以适当取大一些。但最好是
n=2^k+2, k为整数,因为这样在求平均值average=SUM/(n-2)=SUM/2^k时,
可以写成average=SUM>>k,用移位的方法,可以加快处理速度。
上述算法显然还存在一个不足之处,就是每采集一个数据就要进行一次排序,
这样会大量占用系统宝贵的时间。这可以通过存储当前数据中的最大值和最小值
来改进。具体做法是:
系统中用两个变量来存储当前n个数据的最大值和最小值在这个数组中的
偏移量(也就是数组下标,存储数组下标而直接不存储数据本身是因为:在一般的
系统中,n不会超无符号短整形的表示范围,因此用一个char形变量就可以存储了
而如果直接存储数据本身,则许多情况下要用int形变量,甚至更长的类型)。这样
只要在当前输入的数据将要覆盖的数据正好是当前的最大值或最小值时才在下个数
组中查找最大值或最小值,而其他情况下则只要将输入的数据与最大值和最小值比较
就可以修改下最大值和最小值了,而且不用进行数据排序。
这个算法很简单,下面是对应的C语言代码实现,可以很方便的应用的具体的51单片机,
或其他处理器上,只须做少量的修改。
#i nclude"stdio.h"
#define dtype unsigned int // 采集数据的数据类型
#define uint8 char
#define LEN 6 //移动算术平均的个数+2=SHIFT<<2+2
#define SHIFT 2 //2^SHIFT
uint8 pdata; //移动指针
uint8 pmax,pmin; //记录数据表中最大值和最小值的位置,
//在一般的数据采集系统中,数据的长度>=8,
//因此用指针记录而不是直接记录最大值和最小值
dtype datas[LEN];
dtype szlb(dtype _data)
{
/****************************/
/* 在调用此子程序前必须对 */
/* pdata,datas[]数组, */
/* pmax,pmin进行初始化 */
/****************************/
uint8 i;
dtype average=0; //清零,用来计算平均值
pdata=(pdata+1)%LEN; //指针下标在0到LEN-1上滑动
datas[pdata]=_data; //采样所得数据存入数据表中
for(i=0;i<LEN;i++)
average+=datas; //求所有数据总和
/*******去除被认为是脉冲的数据******/
if(_data>datas[pmax])
pmax=pdata; //得到最大值的指针
else if(_data<datas[pmin])
pmin=pdata; //得到最小值的指针
if(pdata==pmax) //如果当前输入值将存入当前最大值的位置时
{ //由以上方法将不可行,必须从其他位置中查找极值
for(i=0;i<LEN;i++)
if(datas>datas[pmax])
pmax=i;
}
else if(pdata==pmin)//如果当前输入值将存入当前最大值的位置时
{ //由以上方法将不可行,必须从其他位置中查找极值
for(i=0;i<LEN;i++)
if(datas<datas[pmin])
pmin=i;
}
average=average-datas[pmax]-datas[pmin];//减去脉冲
return (average>>SHIFT); //求算术平均值
}
/******以下是在VC++6.0环境下运行的测试程序**/
/***通过手动输入来模拟数据采集过程****/
void main()
{
uint8 i;
dtype _data;
pdata=0;
pmax=0;
pmin=0;
for(i=0;i<LEN;i++)
datas=0;
printf("数据: 最大 最小\n");
while(1)
{
scanf("%u",&_data);
szlb(_data);
for(i=0;i<LEN;i++)
printf("%-3u ",datas);
printf(" %-3u %-3u",datas[pmax],datas[pmin]);
printf("\n");
}
}
算术平均滤波
所谓算术平均滤波就是把n个采样值相加,然后取其算术平均值作为本次有效的采样信号
PUSH PSW ;现场保护
PUSH A
MOV FLAG,#00H ;进位位清零
MOV R0,DATA ;设置数据存储区首址
MOV R7,#08H ;设置采样数据个数
CLR A ;清累加器
LOOP: ADD A,@R0 ;两数相加
JNC NEXT ;无进位,转NEXT
INC FLAG ;有进位,进位位加1
NEXT: INC R0 ;数据指针加1
DJNZ R7, LOOP ;未加完,继续加
MOV R7,#03H ;设置循环次数
DIVIDE: MOV TEMP,A ;保存累加器中的内容
MOV A,FLAG ;累加结果除2
CLR C
RRC A
MOV FLAG,A
MOV A,TEMP
RRC A
DJNZ R7,DIVIDE ;未结束,继续执行
MOV SAMP,A ;保存结果至SAMP中
POP A ;恢复现场
POP PSW
RET
限幅滤波程序
设在顺序采样时刻T1、T2、T3所采集的数据分别为Y1、Y2、Y3,则当
∣Y2-Y1∣≤△y,则Y2作为采样值;
∣Y2-Y1∣>△y, 则保留Y2,但不作为采样值,继续采样得Y3;
如果∣Y3-Y2∣≤△y,则Y3作为采样值;
∣Y3-Y2∣>△y, 则取作为采样值。
程序
PUSH PSW ;保护现场
PUSH A
CLR C ;进位标志位清零
MOV DATA,DATA2
MOV A,DATA1
SUBB A,DATA ;求Yn-1 -Yn
JNC COMPARE ;如果Yn-1 -Yn≥0,转COMPARE
CPL A ;如果Yn-1 -Yn<0, 求补
INC A
COMPARE: CLR C
SUBB A,LIMIT ;│Yn-Yn-1│和△y比较
JC OVER ;如果│Yn-Yn-1│≤△y,DATA2→DATA
MOV DATA,DATA1 ;如果│Yn-Yn-1│>△y,DATA1→DATA
OVER: POP A ;恢复现场
POP PSW
RET ;返回
如何选用滤波电容
滤波电容在开关电源中起着非常重要的作用,如何正确选择滤波电容,尤其是输出滤
波电容的选择则是每个工程技术人员都十分关心的问题。50Hz工频电路中使用的普通电解
电容器,其脉动电压频率仅为100Hz,充放电时间是毫秒数量级。
为获得更小的脉动系数,所需的电容量高达数十万μF,因此普通低频铝电解电容器的
目标是以提高电容量为主,电容器的电容量、损耗角正切值以及漏电流是鉴别其优劣的主
要参数。而开关电源中的输出滤波电解电容器,其锯齿波电压频率高达数十kHz,甚至是数
十MHz,这时电容量并不是其主要指标,衡量高频铝电解电容优劣的标准是“阻抗-频率”
特性,要求在开关电源的工作频率内要有较低的等效阻抗,同时对于半导体器件工作时产
生的高频尖峰信号具有良好的滤波作用。
普通的低频电解电容器在10kHz左右便开始呈现感性,无法满足开关电源的使用要求。
而开关电源专用的高频铝电解电容器有四个端子,正极铝片的两端分别引出作为电容器的
正极,负极铝片的两端也分别引出作为负极。电流从四端电容的一个正端流入,经过电容
内部,再从另一个正端流向负载;从负载返回的电流也从电容的一个负端流入,再从另一
个负端流向电源负端。由于四端电容具有良好的高频特性,为减小电压的脉动分量以及抑
制开关尖峰噪声提供了极为有利的手段。高频铝电解电容器还有多芯的形式,即将铝箔分
成较短的若干段,用多引出片并联连接以减小容抗中的阻抗成份。并且采用低电阻率的材
料作为引出端子,提高了电容器承受大电流的能力。