十大濾波演算法程式大全(精心整理版)
1、限幅濾波法
*函式名稱:AmplitudeLimiterFilter()-限幅濾波法
*優點:能有效克服因偶然因素引起的脈衝干擾
*缺點:無法抑制那種週期性的干擾,且平滑度差
*說明:
1、呼叫函式
GetAD(),該函式用來取得當前值
2、變數說明
Value:最近一次有效取樣的值,該變數為全域性變數
NewValue:當前取樣的值
ReturnValue:返回值
3、常量說明
A:兩次取樣的最大誤差值,該值需要使用者根據實際情況設定
*入口:Value,上一次有效的取樣值,在主程式裡賦值
理解:使用前提是已知採回來的數值應該在什麼範圍或精確值
2、中位值濾波法
/*****************************************************函式名稱:MiddlevalueFilter()-中位值濾波法 *優點:能有效克服因偶然因素引起的波動干擾;對溫度、液 位等變化緩慢的被測引數有良好的濾波效果 *缺點:對流量,速度等快速變化的引數不宜 *說明: 1、呼叫函式 GetAD(),該函式用來取得當前值 Delay(),基本延時函式 2、變數說明 ArrDataBuffer[N]:用來存放一次性採集的N組資料 Temp:完成冒泡法試用的臨時暫存器 i,j,k:迴圈試用的引數值 3、常量說明 N:陣列長度 *入口: *出口:value_buf[(N-1)/2],返回值,本次濾波結果
#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]; }
是不是需要的執行時間比較長 放在定時中斷或者DMA中斷都會影響12864的顯示速度
就像在DMA 中斷里加了一個printf語句
3、算術平均濾波法
/*********************************************************說明:連續取N個取樣值進行算術平均運算 優點:試用於對一般具有隨機干擾的訊號進行濾波。這種訊號的特點是 有一個平均值,訊號在某一數值範圍附近上下波動。 缺點:對於測量速度較慢或要求資料計算較快的實時控制不適用。 **********************************************************/
#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、遞推平均濾波法(又稱滑動平均濾波法)
/***************************************************說明:把連續N個取樣值看成一個佇列,佇列長度固定為N。 每次取樣到一個新資料放入隊尾,並扔掉隊首的一 次資料。把佇列中的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(); //採集到的資料放入最高位 for(i=0;i<N;i++) { value_buf[i]=value_buf[i+1]; //所有資料左移,低位扔掉 sum += value_buf[i]; } value = sum/N; return(value); }
5、中位值平均濾波法(又稱防脈衝干擾平均濾波法)
/******************************************** 說明:採一組佇列去掉最大值和最小值 優點:融合了兩種濾波的優點。對於偶然出現的脈衝性干擾,可消 除有其引起的取樣值偏差。對週期干擾有良好的抑制作用, 平滑度高,適於高頻振盪的系統。 缺點:測量速度慢 *********************************************/
#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、遞推中位值濾波法 /************************************************ 優點:對於偶然出現的脈衝性干擾,可消除由其引起的取樣值偏差。 對週期性干擾有良好的抑制作用,平滑度高;試用於高頻振盪 的系統 缺點:測量速度慢 *************************************************/
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、限幅平均濾波法
/************************************************ 優點:對於偶然出現的脈衝性干擾,可消除有其引起的取樣值偏差。 *************************************************/ #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、一階滯後濾波法
/*****************************************************函式名稱:filter()-一階滯後濾波法 *說明: 1、呼叫函式 GetAD(),該函式用來取得當前值 Delay(),基本延時函式 2、變數說明 Or_data[N]:採集的資料 Dr0_flag、Dr1_flag:前一次比較與當前比較的方向位 coeff:濾波係數 F_count:濾波計數器 3、常量說明 N:陣列長度 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;
//確定一階濾波係數 for(i=1;i<N;i++) { Abs=abs(Or_data[i-1],Or_data[i]);/*C語言中的逗號有2種意思: 1.表示"分隔號"的意思,就和語文中的逗號一個意思; 2.表示"逗號運算子"的意思,用它將2個表示式連線起來.例如: 3+5,6+8 就稱為逗號表示式,又稱為"順序求值運算子".逗號表示式的一般形式為 表示式1,表示式2 逗號表示式的求解過程是:先求解表示式1,再求解表示式2.整個逗號表示式的值是表示式2的值.例如,上面的表示式"3+5,6+8"的值是14.*/
if(!(Dr1_flag^Dr0_flag)) //前後資料變化方向一致 ^異或運算子 { 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; //濾波計數器清零 Dr0_flag=Dr1_flag; } }
9、加權遞推平均濾波法
A、方法:
是對遞推平均濾波法的改進,即不同時刻的資料加以不同的權
通常是,越接近現時刻的資料,權取得越大。
給予新取樣值的權係數越大,則靈敏度越高,但訊號平滑度越低
B、優點:
適用於有較大純滯後時間常數的物件
和取樣週期較短的系統
C、缺點:
對於純滯後時間常數較小,取樣週期較長,變化緩慢的訊號
不能迅速反應系統當前所受干擾的嚴重程度,濾波效果差
/************************************************************ coe:陣列為加權係數表,存在程式儲存區。 sum_coe:加權係數和 ************************************************************/
#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、消抖濾波法
A、方法:
設定一個濾波計數器
將每次取樣值與當前有效值比較:
如果取樣值=當前有效值,則計數器清零
如果取樣值<>當前有效值,則計數器+1,並判斷計數器是否>=上限N(溢位)
如果計數器溢位,則將本次值替換當前有效值,並清計數器
B、優點:
對於變化緩慢的被測引數有較好的濾波效果,
可避免在臨界值附近控制器的反覆開/關跳動或顯示器上數值抖動
C、缺點:
對於快速變化的引數不宜
如果在計數器溢位的那一次取樣到的值恰好是干擾值,則會將干擾值當作有效值匯入系統
/************************************************
*************************************************/ #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); }