天天看點

單片機中常用的一些濾波算法

0 引言

在單片機的資料采集系統中,測量通道串入随機幹擾是難免的,進而使A/D轉換送入單片機的資料存在誤差,這種因随機幹擾産生的誤差稱為随機誤差。随機誤差雖然無法預測,但多次測量結果是符合統計規律的。為克服随機幹擾産生的誤差,可以采用硬體抗幹擾的方法,也可以采用按統計規律用軟體方法實作,即采用數字濾波的方法來抑制有效信号中的幹擾成分,進而消除随機誤差。

1 常用的數字濾波算法及實作

在單片機的資料采集系統中,常用的數字濾波算法有限幅濾波、中位值濾波、算術平均濾波、移動平均濾波、權重平均濾波、低通濾波、中位值平均濾波等。以下就分别介紹其原理及濾波程式。

1.1 限幅濾波

限幅濾波的基本原理是把兩次相鄰時刻(n和n-1)的采樣值Yn和Yn-1相減,求出其內插補點,以絕對值表示,然後将這個內插補點與兩次采樣允許的最大偏內插補點ΔY比較,如果兩次采樣值的內插補點超過了允許的最大偏內插補點ΔY,則認為發生了随機幹擾,并認為最後一次采樣值Yn非法,應予剔除。剔除Yn後,可用Yn-1代替Yn;若未超過允許的最大偏內插補點範圍,則認為本次采樣值有效。可用如下公式表示:

|Yn-Yn-1|≤ΔY;則Yn有效

|Yn-Yn-1|>ΔY;則Yn-1有效

此算法的樣例子程式如下:

#define A 10   //A值可根據實際情況調整

char data;    //上一次的資料

char filter_1()

{

char datanew;  //新資料變量

datanew=get_data();   //獲得新資料

//濾波算法

if ((datanew-data>A)||(data-datanew>A) 

return data;

return datanew;

}

    該算法主要用于處理變化比較緩慢的資料,如溫度、物體的位置等。使用時關鍵在于最大偏內插補點的Δy的選擇,通常可根據經驗獲得,也可按照輸出參數可能的最大變化速度Vmax及采樣周期T來決定ΔY的值[1],即ΔY=VmaxT。

1.2 中位值濾波

中位值濾波是先對某一參數連續采樣N次(一般N取奇數),然後把N次采樣值按從小到大排列,取中間值為本次采樣值。

該濾波方法實際上是一種排序方法,文獻[2,7,9]采用的是冒泡法排序。由于在冒泡法排序中,每出現一次前者資料大于後者資料,就要進行二者資料的交換,效率很低,故在驗證時改用選擇排序法。

該算法的樣例子程式如下:

#define N 11  //N值可根據實際情況調整

char filter_2()

{

char value_buf[];

char count,i,j,k,temp;

for(count=0;count<N;count++) //擷取資料

{

value_buf[count]=get_data();

delay();

}

for(i=0;i<N-1;i++) //選擇排序

 {k=i; 

for(j=i+1;j<N;j++)

      if(value_buf[j]<value_buf[k]) k=j;

      temp=value_buf[k];

      value_buf[k]=value_buf[i];

      value_buf[i]=temp;

      }

return value_buf[(N-1)/2];

}

中位值濾波能有效地克服偶然因素引起的波動或采樣器不穩定引起的誤碼等脈沖幹擾。對溫度、液位等緩慢變化的被測參數采用此算法能收到良好的濾波效果,但對于流量、壓力等快速變化的資料,不宜采用中位值濾波。

1.3 算術平均濾波

算術平均濾波法是要按輸入的N個采樣資料Xi(i從1到N),尋找這樣一個Y,使Y與各采樣值之間的偏差的平方和最小,即

                     (1)

由一進制函數求極值的原理,可得

                    (2)

此即為算術平均濾波的基本算式。具體實作此算法的子程式如下:

#define N 12

char filter_3()

{

int count;

int sum=0;

for(count=0;count<N;count++)

 {

  sum+=get_ad();

  delay();

  }

 return (char)(sum/N);

}

算術平均濾波适用于對一般具有随機幹擾的信号進行濾波。這種信号的特點是有一個平均值,信号在某一數值範圍附近做上下波動,在這種情況下僅取一個采樣值做依據顯然是不準确的。算術平均濾波對信号的平滑程式完全取決于N,當N較大時,平滑度高,但靈敏度低;當N較小時,平滑度低,但靈敏度高,應視具體情況選取N,以便既少占用計算時間,又達到最好的效果。

1.4 移動平均濾波

算術平均濾波需要連續采樣若幹次後,才能進行運算而獲得一個有效的資料,因而速度較慢。為了克服這一缺點,可采用移動平均濾波。即先在RAM中建立一個資料緩沖區,按順序存放N次采樣資料,然後每采進一個新資料,就将最早采集的資料去掉,最後再求出目前RAM緩沖區中的N個資料的算術平均值。這樣,每進行一次采樣,就可計算出一個新的平均值,即測量資料取一丢一[3],測量一次便計算一次平均值,大大加快了資料處理的能力。具體的濾波程式如下:

#define N 12

char value_buf[N];

char i=0;

char filter_4()

{

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);

}

移動平均濾波對周期性幹擾有良好的抑制作用,平滑度高,靈敏度低,但對偶然出現的脈沖性幹擾抑制作用差,是以它不适用于脈沖幹擾比較嚴重的場合,而适用于高頻振蕩的系統。通過觀察不同N值下移動平均的輸出響應來選取N值,以便既少占用單片機的時間,又能達到最好的濾波效果。

1.5 權重平均濾波

在算術平均濾波和移動平均濾波中,N次采樣值在輸出結果中的權重是均等的,取1/N。用這樣的濾波算法,對于時變信号會引入滞後,N值越大,滞後越嚴重[1,4]。為了增加新采樣資料在移動平均中的權重,以提高系統對目前采樣值中所受幹擾的靈敏度,可采用權重平均濾波,它是移動平均濾波算法的改進。

權重平均濾波是對連續N次采樣值分别乘上不同的權重系統之後再求累加和,權重系統一般先小後大,以突出後面若幹采樣的效果,加強系統對參數變化趨勢的辨識。各個權重系統均為小于1的小數,且滿足總和等于1的限制條件。這樣,權重運算之後的累加和即為有效采樣值。

為友善計算,可取各權重系數均為整數,且總和為256,權重運算後的累加和除以256,即舍去低位元組後便是有效采樣值。具體的樣例子程式如下:

//code數組為權重系統表,存在ROM區。

#define N 12

char code jq[N]={1,2,3,4,5,6,7,8,9,10,11

,12}; 

char code sum_jp=1+2+3+4+5+6+7+8+9+10+11

+12;

char filter_5()

{

char count;

char value_buf[N];

int sum=0;

for(count=0;count<N;count++)

{

value_buf[count]=get_data();

delay();

}

for(count=0;count<N;count++)

sum+=value_buf[count]*jq[count];

return (char)(sum/sum_jq);

}

1.6 中位值平均濾波

該算法的基本原理是,對連續的n個資料進行排序,去掉其中最大和最小的2個資料,将剩餘資料求平均值。

為了加快資料處理速度,n可以取值6,而對于具有較快速度的處理器,n值可以适當取大一些。但最好是n=2k+2[5],k為整數,因為這樣可以在求平均值時用移位的方法,加快處理速度。

上述算法存在的一個不足之處就是每采集一個資料就要進行一次排序,這樣會大量占用系統寶貴的時間,文獻[8]的算法程式即是如此。

可以通過存儲目前資料中的最大值和最小值來改進,具體做法是:

系統中用兩個變量來存儲目前n個資料中最大值和最小值在數組中的偏移量。這樣隻有在目前輸入的資料将要覆寫的資料正好是目前的最大值或最小值時,才在下個數組中查找最大值或最小值,而其他情況下,則隻要将輸入的資料與最大值和最小值比較就可以修改最大值和最小值了,而且不用進行資料排序。

改進後的算法程式如下:

#define dtype unsigned int 

#define uint8 char

#define LEN  6 

#define SHIFT 2

uint8 pdata;

uint8 pmax,pmin; 

dtype datas[LEN];

dtype szlb(dtype _data)

uint8 i;

dtype average=0;

pdata=(pdata+1)%LEN; 

datas[pdata]=_data; 

for(i=0;i<LEN;i++)

average+=datas[i]; 

if(_data>datas[pmax])

pmax=pdata;

else if(_data<datas[pmin])

pmin=pdata; 

if(pdata==pmax) 

 { for(i=0;i<LEN;i++)

   if(datas[i]>datas[pmax])

   pmax=i;

 }

 else if(pdata==pmin) 

{

 for(i=0;i<LEN;i++)

 if(datas[i]<datas[pmin])

 pmin=i;

 }

average=average-datas[pmax]-datas[pmin]; 

 return (average>>SHIFT);  

}

這種濾波方法相容了移動平均濾波算法和中位值濾波算法的優點,是以無論對緩慢變化的信号,還是對快速變化的信号,都能取得較好的濾波效果。

1.7低通濾波

将描述模拟RC低通濾波特性的微分方程用差分方程來表示,便可以用軟體算法來實作模拟濾波的功能[4]。

最簡單的一階RC低通濾波器描述其輸入x(t)與輸出y(t)的微分方程為

                (3)

以采樣周期T對x(t)、y(t)進行采樣得

yn=y(Nt)

xn=x(Nt)

如果T<<RC,則由微分方程可得差分方程

               (4)

令                    (5)

可得yn=axn+(1-a)yn-1,其中:

xn:目前的資料

yn-1:上次的濾波輸出值

a:濾波系統

yn:本次的濾波輸出值

由上式可以看出,本次濾波的輸出值主要取決于上次濾波的輸出值,這和權重平均濾波是有本質差別的,本次采樣值對濾波輸出的貢獻是比較小的,但多少有些修正作用,這種算法便模拟了具有較大慣性[6]的低能濾波功能。當目标參數為變化很慢的實體量時,這是很有效的。

低通濾算法程式和權重平均濾波相似,但權重系統隻有兩個:a和1-a,因為隻有兩項,a和1-a均以立即數的形式編入程式中,不另設表格。雖然采樣值為單元位元組,為保證運算精度,濾波輸出值用雙位元組表示,其中一位元組整數,一位元組小數,否則有可能因為每次舍去尾數而使輸出不會變化。

低通濾波的程式如下:

//為加快程式處理速度,假定基數為100,//a=0~100

#define a 50

char value;

char filter_6()

{

char new_value;

new_value=get_data();

return(100-a)*value+a*new_value;

}

一階低通濾波算法對周期性幹擾具有良好的抑制作用,适用于波動頻繁的參數濾波,其不足之處是帶來了相位滞後,靈敏度低。滞後的程度取決于a值的大小。同時,它不能濾除頻率高于采樣頻率1/2(奈奎斯特頻率)的幹擾信号[7],對于高于奈奎斯特頻率的幹擾信号,應該采用模拟濾波器。