|
发表于 2009-9-24 22:31:04
|
显示全部楼层
我记的本论坛有的,刚才没有搜到。我在转贴一下。
/*0001*/ 1、限幅滤波法(又称程序判断滤波法)
/*0002*/ A、方法:
/*0003*/ 根据经验判断,确定两次采样允许的最大偏差值(设为A)
/*0004*/ 每次检测到新值时判断:
/*0005*/ 如果本次值与上次值之差<=A,则本次值有效
/*0006*/ 如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值
/*0007*/ B、优点:
/*0008*/ 能有效克服因偶然因素引起的脉冲干扰
/*0009*/ C、缺点
/*0010*/ 无法抑制那种周期性的干扰
/*0011*/ 平滑度差
/*0012*/
/*0013*/ 2、中位值滤波法
/*0014*/ A、方法:
/*0015*/ 连续采样N次(N取奇数)
/*0016*/ 把N次采样值按大小排列
/*0017*/ 取中间值为本次有效值
/*0018*/ B、优点:
/*0019*/ 能有效克服因偶然因素引起的波动干扰
/*0020*/ 对温度、液位的变化缓慢的被测参数有良好的滤波效果
/*0021*/ C、缺点:
/*0022*/ 对流量、速度等快速变化的参数不宜
/*0023*/
/*0024*/ 3、算术平均滤波法
/*0025*/ A、方法:
/*0026*/ 连续取N个采样值进行算术平均运算
/*0027*/ N值较大时:信号平滑度较高,但灵敏度较低
/*0028*/ N值较小时:信号平滑度较低,但灵敏度较高
/*0029*/ N值的选取:一般流量,N=12;压力:N=4
/*0030*/ B、优点:
/*0031*/ 适用于对一般具有随机干扰的信号进行滤波
/*0032*/ 这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动
/*0033*/ C、缺点:
/*0034*/ 对于测量速度较慢或要求数据计算速度较快的实时控制不适用
/*0035*/ 比较浪费RAM
/*0036*/
/*0037*/ 4、递推平均滤波法(又称滑动平均滤波法)
/*0038*/ A、方法:
/*0039*/ 把连续取N个采样值看成一个队列
/*0040*/ 队列的长度固定为N
/*0041*/ 每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则)
/*0042*/ 把队列中的N个数据进行算术平均运算,就可获得新的滤波结果
/*0043*/ N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4
/*0044*/ B、优点:
/*0045*/ 对周期性干扰有良好的抑制作用,平滑度高
/*0046*/ 适用于高频振荡的系统
/*0047*/ C、缺点:
/*0048*/ 灵敏度低
/*0049*/ 对偶然出现的脉冲性干扰的抑制作用较差
/*0050*/ 不易消除由于脉冲干扰所引起的采样值偏差
/*0051*/ 不适用于脉冲干扰比较严重的场合
/*0052*/ 比较浪费RAM
/*0053*/
/*0054*/ 5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
/*0055*/ A、方法:
/*0056*/ 相当于“中位值滤波法”+“算术平均滤波法”
/*0057*/ 连续采样N个数据,去掉一个最大值和一个最小值
/*0058*/ 然后计算N-2个数据的算术平均值
/*0059*/ N值的选取:3~14
/*0060*/ B、优点:
/*0061*/ 融合了两种滤波法的优点
/*0062*/ 对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差
/*0063*/ C、缺点:
/*0064*/ 测量速度较慢,和算术平均滤波法一样
/*0065*/ 比较浪费RAM
/*0066*/
/*0067*/
/*0068*/ 6、限幅平均滤波法
/*0069*/ A、方法:
/*0070*/ 相当于“限幅滤波法”+“递推平均滤波法”
/*0071*/ 每次采样到的新数据先进行限幅处理,
/*0072*/ 再送入队列进行递推平均滤波处理
/*0073*/ B、优点:
/*0074*/ 融合了两种滤波法的优点
/*0075*/ 对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差
/*0076*/ C、缺点:
/*0077*/ 比较浪费RAM
/*0078*/
/*0079*/ 7、一阶滞后滤波法
/*0080*/ A、方法:
/*0081*/ 取a=0~1
/*0082*/ 本次滤波结果=(1-a)*本次采样值+a*上次滤波结果
/*0083*/ B、优点:
/*0084*/ 对周期性干扰具有良好的抑制作用
/*0085*/ 适用于波动频率较高的场合
/*0086*/ C、缺点:
/*0087*/ 相位滞后,灵敏度低
/*0088*/ 滞后程度取决于a值大小
/*0089*/ 不能消除滤波频率高于采样频率的1/2的干扰信号
/*0090*/
/*0091*/ 8、加权递推平均滤波法
/*0092*/ A、方法:
/*0093*/ 是对递推平均滤波法的改进,即不同时刻的数据加以不同的权
/*0094*/ 通常是,越接近现时刻的数据,权取得越大。
/*0095*/ 给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低
/*0096*/ B、优点:
/*0097*/ 适用于有较大纯滞后时间常数的对象
/*0098*/ 和采样周期较短的系统
/*0099*/ C、缺点:
/*0100*/ 对于纯滞后时间常数较小,采样周期较长,变化缓慢的信号
/*0101*/ 不能迅速反应系统当前所受干扰的严重程度,滤波效果差
/*0102*/
/*0103*/ 9、消抖滤波法
/*0104*/ A、方法:
/*0105*/ 设置一个滤波计数器
/*0106*/ 将每次采样值与当前有效值比较:
/*0107*/ 如果采样值=当前有效值,则计数器清零
/*0108*/ 如果采样值<>当前有效值,则计数器+1,并判断计数器是否>=上限N(溢出)
/*0109*/ 如果计数器溢出,则将本次值替换当前有效值,并清计数器
/*0110*/ B、优点:
/*0111*/ 对于变化缓慢的被测参数有较好的滤波效果,
/*0112*/ 可避免在临界值附近控制器的反复开/关跳动或显示器上数值抖动
/*0113*/ C、缺点:
/*0114*/ 对于快速变化的参数不宜
/*0115*/ 如果在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当作有效值导入系统
/*0116*/
/*0117*/ 10、限幅消抖滤波法
/*0118*/ A、方法:
/*0119*/ 相当于“限幅滤波法”+“消抖滤波法”
/*0120*/ 先限幅,后消抖
/*0121*/ B、优点:
/*0122*/ 继承了“限幅”和“消抖”的优点
/*0123*/ 改进了“消抖滤波法”中的某些缺陷,避免将干扰值导入系统
/*0124*/ C、缺点:
/*0125*/ 对于快速变化的参数不宜
/*0126*/
/*0127*/
/*0128*/ 第11种方法:IIR 数字滤波器
/*0129*/
/*0130*/ A. 方法:
/*0131*/ 确定信号带宽, 滤之。
/*0132*/ 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)
/*0133*/
/*0134*/ B. 优点:高通,低通,带通,带阻任意。设计简单(用matlab)
/*0135*/ C. 缺点:运算量大。
/*0136*/
/*0137*/
/*0138*/ //---------------------------------------------------------------------
/*0139*/
/*0140*/ 软件滤波的C程序样例
/*0141*/
/*0142*/ 10种软件滤波方法的示例程序
/*0143*/
/*0144*/ 假定从8位AD中读取数据(如果是更高位的AD可定义数据类型为int),子程序为get_ad();
/*0145*/
/*0146*/ 1、限副滤波
/*0147*/ /* A值可根据实际情况调整
<font color=#646400>|*0148*| value为有效值,new_value为当前采样值
|*0149*| 滤波程序返回有效的实际值 */</font>
/*0150*/ #define A 10
/*0151*/
/*0152*/ char value;
/*0153*/
/*0154*/ char filter()
/*0155*/ {
/*0156*/ char new_value;
/*0157*/ new_value = get_ad();
/*0158*/ if ( ( new_value - value > A ) || ( value - new_value > A )
/*0159*/ return value;
/*0160*/ return new_value;
/*0161*/
/*0162*/ }
/*0163*/
/*0164*/ 2、中位值滤波法
/*0165*/ /* N值可根据实际情况调整
<font color=#646400>|*0166*| 排序采用冒泡法*/</font>
/*0167*/ #define N 11
/*0168*/
/*0169*/ char filter()
/*0170*/ {
/*0171*/ char value_buf[N];
/*0172*/ char count,i,j,temp;
/*0173*/ for ( count=0;count
/*0174*/ {
/*0175*/ value_buf[count] = get_ad();
/*0176*/ delay();
/*0177*/ }
/*0178*/ for (j=0;j
/*0179*/ {
/*0180*/ for (i=0;i
/*0181*/ {
/*0182*/ if ( value_buf>value_buf[i+1] )
/*0183*/ {
/*0184*/ temp = value_buf;
/*0185*/ value_buf = value_buf[i+1];
/*0186*/ value_buf[i+1] = temp;
/*0187*/ }
/*0188*/ }
/*0189*/ }
/*0190*/ return value_buf[(N-1)/2];
/*0191*/ }
/*0192*/
/*0193*/ 3、算术平均滤波法
/*0194*/ /*
<font color=#646400>|*0195*| */</font>
/*0196*/
/*0197*/ #define N 12
/*0198*/
/*0199*/ char filter()
/*0200*/ {
/*0201*/ int sum = 0;
/*0202*/ for ( count=0;count
/*0203*/ {
/*0204*/ sum + = get_ad();
/*0205*/ delay();
/*0206*/ }
/*0207*/ return (char)(sum/N);
/*0208*/ }
/*0209*/
/*0210*/ 4、递推平均滤波法(又称滑动平均滤波法)
/*0211*/ /*
<font color=#646400>|*0212*| */</font>
/*0213*/ #define N 12
/*0214*/
/*0215*/ char value_buf[N];
/*0216*/ char i=0;
/*0217*/
/*0218*/ char filter()
/*0219*/ {
/*0220*/ char count;
/*0221*/ int sum=0;
/*0222*/ value_buf[i++] = get_ad();
/*0223*/ if ( i == N ) i = 0;
/*0224*/ for ( count=0;count
/*0225*/ sum = value_buf[count];
/*0226*/ return (char)(sum/N);
/*0227*/ }
/*0228*/
/*0229*/ 5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
/*0230*/ /*
<font color=#646400>|*0231*| */</font>
/*0232*/ #define N 12
/*0233*/
/*0234*/ char filter()
/*0235*/ {
/*0236*/ char count,i,j;
/*0237*/ char value_buf[N];
/*0238*/ int sum=0;
/*0239*/ for (count=0;count
/*0240*/ {
/*0241*/ value_buf[count] = get_ad();
/*0242*/ delay();
/*0243*/ }
/*0244*/ for (j=0;j
/*0245*/ {
/*0246*/ for (i=0;i
/*0247*/ {
/*0248*/ if ( value_buf>value_buf[i+1] )
/*0249*/ {
/*0250*/ temp = value_buf;
/*0251*/ value_buf = value_buf[i+1];
/*0252*/ value_buf[i+1] = temp;
/*0253*/ }
/*0254*/ }
/*0255*/ }
/*0256*/ for(count=1;count
/*0257*/ sum += value[count];
/*0258*/ return (char)(sum/(N-2));
/*0259*/ }
/*0260*/
/*0261*/ 6、限幅平均滤波法
/*0262*/ /*
<font color=#646400>|*0263*| */</font>
/*0264*/ 略 参考子程序1、3
/*0265*/
/*0266*/ 7、一阶滞后滤波法
/*0267*/ /* 为加快程序处理速度假定基数为100,a=0~100 */
/*0268*/
/*0269*/ #define a 50
/*0270*/
/*0271*/ char value;
/*0272*/
/*0273*/ char filter()
/*0274*/ {
/*0275*/ char new_value;
/*0276*/ new_value = get_ad();
/*0277*/ return (100-a)*value + a*new_value;
/*0278*/ }
/*0279*/
/*0280*/ 8、加权递推平均滤波法
/*0281*/ /* coe数组为加权系数表,存在程序存储区。*/
/*0282*/
/*0283*/ #define N 12
/*0284*/
/*0285*/ char code coe[N] = {1,2,3,4,5,6,7,8,9,10,11,12};
/*0286*/ char code sum_coe = 1+2+3+4+5+6+7+8+9+10+11+12;
/*0287*/
/*0288*/ char filter()
/*0289*/ {
/*0290*/ char count;
/*0291*/ char value_buf[N];
/*0292*/ int sum=0;
/*0293*/ for (count=0,count
/*0294*/ {
/*0295*/ value_buf[count] = get_ad();
/*0296*/ delay();
/*0297*/ }
/*0298*/ for (count=0,count
/*0299*/ sum += value_buf[count]*coe[count];
/*0300*/ return (char)(sum/sum_coe);
/*0301*/ }
/*0302*/
/*0303*/ 9、消抖滤波法
/*0304*/
/*0305*/ #define N 12
/*0306*/
/*0307*/ char filter()
/*0308*/ {
/*0309*/ char count=0;
/*0310*/ char new_value;
/*0311*/ new_value = get_ad();
/*0312*/ while (value !=new_value);
/*0313*/ {
/*0314*/ count++;
/*0315*/ if (count>=N) return new_value;
/*0316*/ delay();
/*0317*/ new_value = get_ad();
/*0318*/ }
/*0319*/ return value;
/*0320*/ }
/*0321*/
/*0322*/ 10、限幅消抖滤波法
/*0323*/ /*
<font color=#646400>|*0324*| */</font>
/*0325*/ 略 参考子程序1、9
/*0326*/
/*0327*/ 11、IIR滤波例子
/*0328*/
/*0329*/ int BandpassFilter4(int InputAD4)
/*0330*/ {
/*0331*/ int ReturnValue;
/*0332*/ int ii;
/*0333*/ RESLO=0;
/*0334*/ RESHI=0;
/*0335*/ MACS=*PdelIn;
/*0336*/ OP2=1068; //FilterCoeff4[4];
/*0337*/ MACS=*(PdelIn+1);
/*0338*/ OP2=8; //FilterCoeff4[3];
/*0339*/ MACS=*(PdelIn+2);
/*0340*/ OP2=-2001;//FilterCoeff4[2];
/*0341*/ MACS=*(PdelIn+3);
/*0342*/ OP2=8; //FilterCoeff4[1];
/*0343*/ MACS=InputAD4;
/*0344*/ OP2=1068; //FilterCoeff4[0];
/*0345*/ MACS=*PdelOu;
/*0346*/ OP2=-7190;//FilterCoeff4[8];
/*0347*/ MACS=*(PdelOu+1);
/*0348*/ OP2=-1973; //FilterCoeff4[7];
/*0349*/ MACS=*(PdelOu+2);
/*0350*/ OP2=-19578;//FilterCoeff4[6];
/*0351*/ MACS=*(PdelOu+3);
/*0352*/ OP2=-3047; //FilterCoeff4[5];
/*0353*/ *p=RESLO;
/*0354*/ *(p+1)=RESHI;
/*0355*/ mytestmul<<=2;
/*0356*/ ReturnValue=*(p+1);
/*0357*/ for (ii=0;ii<3;ii++)
/*0358*/ {
/*0359*/ DelayInput[ii]=DelayInput[ii+1];
/*0360*/ DelayOutput[ii]=DelayOutput[ii+1];
/*0361*/ }
/*0362*/ DelayInput[3]=InputAD4;
/*0363*/ DelayOutput[3]=ReturnValue;
/*0364*/
/*0365*/ // if (ReturnValue<0)
/*0366*/ // {
/*0367*/ // ReturnValue=-ReturnValue;
/*0368*/ // }
/*0369*/ return ReturnValue;
/*0370*/ } |
|