1、限幅濾波法 *函數(shù)名稱:AmplitudeLimiterFilter()-限幅濾波法 *優(yōu)點:能有效克服因偶然因素引起的脈沖干擾 *缺點:無法抑制那種周期性的干擾,且平滑度差 *說明: 1、調(diào)用函數(shù) GetAD(),該函數(shù)用來取得當前值 2、變量說明 Value:最近一次有效采樣的值,該變量為全局變量 NewValue:當前采樣的值 ReturnValue:返回值 3、常量說明 A:兩次采樣的最大誤差值,該值需要使用者根據(jù)實際情況設(shè)置 *入口:Value,上一次有效的采樣值,在主程序里賦值 *出口:ReturnValue,返回值,本次濾波結(jié)果 ****************************************************/ #define A 10 unsigned char Value unsigned char AmplitudeLimiterFilter() { unsigned char NewValue; unsigned char ReturnValue; NewValue=GatAD(); if(((NewValue-Value)>A))||((Value-NewValue)>A))) ReturnValue=Value; else ReturnValue=NewValue; return(ReturnValue); }
2、中位值濾波法 /**************************************************** *函數(shù)名稱:MiddlevalueFilter()-中位值濾波法 *優(yōu)點:能有效克服因偶然因素引起的波動干擾;對溫度、液 位等變化緩慢的被測參數(shù)有良好的濾波效果 *缺點:對流量,速度等快速變化的參數(shù)不宜 *說明: 1、調(diào)用函數(shù) GetAD(),該函數(shù)用來取得當前值 Delay(),基本延時函數(shù) 2、變量說明 ArrDataBuffer[N]:用來存放一次性采集的N 組數(shù)據(jù) Temp:完成冒泡法試用的臨時寄存器 i,j,k:循環(huán)試用的參數(shù)值 3、常量說明 N:數(shù)組長度 *入口: *出口:value_buf[(N-1)/2],返回值,本次濾波結(jié)果 *****************************************************/ #define N 11 unsigned char MiddlevalueFilter() { unsigned char value_buf[N]; unsigned char i,j,k,temp; for(i=0;i<N;i++) { value_buf[i] = get_ad(); delay(); } for (j=0;j<N-1;j++) { for (k=0;k<N-j;k++) { if(value_buf[k]>value_buf[k+1]) { temp = value_buf[k]; value_buf[k] = value_buf[k+1]; value_buf[k+1] = temp; } } } return value_buf[(N-1)/2]; }
3、算術(shù)平均濾波法 /********************************************************* 說明:連續(xù)取N 個采樣值進行算術(shù)平均運算 優(yōu)點:試用于對一般具有隨機干擾的信號進行濾波。這種信號的特點是 有一個平均值,信號在某一數(shù)值范圍附近上下波動。 缺點:對于測量速度較慢或要求數(shù)據(jù)計算較快的實時控制不適用。 **********************************************************/ #define N 12 char filter() { unsigned int sum = 0; unsigned char i; for (i=0;i<N;i++) { sum + = get_ad(); delay(); } return(char)(sum/N); }
4、遞推平均濾波法(又稱滑動平均濾波法) /*************************************************** 說明:把連續(xù)N 個采樣值看成一個隊列,隊列長度固定為N。 每次采樣到一個新數(shù)據(jù)放入隊尾,并扔掉隊首的一 次數(shù)據(jù)。把隊列中的N 各數(shù)據(jù)進行平均運算,既獲得 新的濾波結(jié)果。 優(yōu)點:對周期性干擾有良好的抑制作用,平滑度高;試用于高頻振蕩的系統(tǒng) 缺點:靈敏度低;對偶然出現(xiàn)的脈沖性干擾的抑制作用較差,不適于脈沖干 擾較嚴重的場合 ****************************************************/ #define N 12 unsigned char value_buf[N]; unsigned char filter() { unsigned char i; unsigned char value; int sum=0; value_buf[i++] = get_ad(); //采集到的數(shù)據(jù)放入最高位 for(i=0;i<N;i++) { value_buf[i]=value_buf[i+1]; //所有數(shù)據(jù)左移,低位扔掉 sum += value_buf[i]; } value = sum/N; return(value); }
5、中位值平均濾波法(又稱防脈沖干擾平均濾波法) /******************************************** 說明:采一組隊列去掉最大值和最小值 優(yōu)點:融合了兩種濾波的優(yōu)點。對于偶然出現(xiàn)的脈沖性干擾,可消 除有其引起的采樣值偏差。對周期干擾有良好的抑制作用, 平滑度高,適于高頻振蕩的系統(tǒng)。 缺點:測量速度慢 *********************************************/ #define N 12 uchar filter() { unsigned char i,j,k,l; unsigned char temp,sum=0,value; unsigned char value_buf[N],; for(i=0;i<N;i++) { value_buf[i] = get_ad(); delay(); } //采樣值從小到大排列(冒泡法) for(j=0;j<N-1;j++) { for(i=0;i<N-j;i++) { if(value_buf[i]>value_buf[i+1]) { temp = value_buf[i]; value_buf[i] = value_buf[i+1]; value_buf[i+1] = temp; } } } for(i=1;i<N-1;i++) sum += value_buf[i]; value = sum/(N-2); return(value); }
6、遞推中位值濾波法 /************************************************ 優(yōu)點:對于偶然出現(xiàn)的脈沖性干擾,可消除由其引起的采樣值偏差。 對周期性干擾有良好的抑制作用,平滑度高;試用于高頻振蕩 的系統(tǒng) 缺點:測量速度慢 *************************************************/ char filter(char new_data,char queue[],char n) { char max,min; char 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=sum+queue[i]; queue[i]=queue[i-1]; } i=n-2; sum=sum-max-min+i/2; //說明:+i/2 的目的是為了四舍五入 sum=sum/i; return(sum); }
7、限幅平均濾波法 /************************************************ 優(yōu)點:對于偶然出現(xiàn)的脈沖性干擾,可消除有其引起的采樣值偏差。 *************************************************/ #define A 10 #define N 12 unsigned char data[]; unsigned char filter(data[]) { unsigned char i; unsigned char value,sum; data[N]=GetAD(); if(((data[N]-data[N-1])>A||((data[N-1]-data[N])>A)) data[N]=data[N-1]; //else data[N]=NewValue; for(i=0;i<N;i++) { data[i]=data[i+1]; sum+=data[i]; } value=sum/N; return(value); }
8、一階滯后濾波法 /**************************************************** *函數(shù)名稱:filter()-一階滯后濾波法 *說明: 1、調(diào)用函數(shù) GetAD(),該函數(shù)用來取得當前值 Delay(),基本延時函數(shù) 2、變量說明 Or_data[N]:采集的數(shù)據(jù) Dr0_flag、Dr1_flag:前一次比較與當前比較的方向位 coeff:濾波系數(shù) F_count:濾波計數(shù)器 3、常量說明 N:數(shù)組長度 Thre_value:比較門檻值 *入口: *出口: *****************************************************/ #define Thre_value 10 #define N 50 float Or_data[N]; unsigned char Dr0_flag=0,Dr1_flag=0; void abs(float first,float second) { float abs; if(first>second) { abs=first-second; Dr1_flag=0; } else { abs=second-first; Dr1_flag=1; } return(abs); } void filter(void) { uchar i=0,F_count=0,coeff=0; float Abs=0.00; //確定一階濾波系數(shù) for(i=1;i<N;i++) { Abs=abs(Or_data[i-1],Or_data[i]); if(!(Dr1_flag^Dr0_flag)) //前后數(shù)據(jù)變化方向一致 { F_count++; if(Abs>=Thre_value) { F_count++; F_count++; }
if(F_count>=12) F_count=12; coeff=20*F_count; } else //去抖動 coeff=5; //一階濾波算法 if(Dr1_flag==0) //當前值小于前一個值 Or_data[i]=Or_data[i-1]-coeff*(Or_data[i-1]-Or_data[i])/256; else Or_data[i]=Or_data[i-1]+coeff*(Or_data[i]-Or_data[i-1])/256; F_count=0; //濾波計數(shù)器清零 Dr0_flag=Dr1_flag; } }
9、加權(quán)遞推平均濾波法 /************************************************************ coe:數(shù)組為加權(quán)系數(shù)表,存在程序存儲區(qū)。 sum_coe:加權(quán)系數(shù)和 ************************************************************/ #define N 12 const char code coe[N] = {1,2,3,4,5,6,7,8,9,10,11,12}; const char code sum_coe = 1+2+3+4+5+6+7+8+9+10+11+12; unsigned char filter() { unsigned char i; unsigned char value_buf[N]; int sum=0; for (i=0;i<N;i++) { value_buf[i] = get_ad(); delay(); } for (i=0,i<N;i++) { value_buf[i]=value_buf[i+1]; sum += value_buf[i]*coe[i]; } sum/=sum_coe; value=sum/N; return(value); }
10、消抖濾波法 /************************************************ *************************************************/ #define N 12 unsigned char filter() { unsigned char i=0; unsigned char new_value; new_value = get_ad(); if(value !=new_value); { i++; if (i>N) { i=0; value=new_value; } } else i=0; return(value); }
|