單片機的濾波算法

   關於濾波,我們常常聽說有濾波電路、濾波器、濾波對抗器等等,這些都是有效的解決單片機的信號干擾問題,都是從硬件上進行濾波處理,從而增加檢測值的精確度。下面我們來簡單介紹一下軟件是如何進行單片機濾波的,這就要引出我們今天的主題--濾波算法。

  濾波算法是什麼呢?既然是算法,那就要運用到數學公式了,即通過算法將我們檢測到誤差大的數據進行處理,從而達到濾波作用。下面通過例子來講述幾種常用的濾波算法。

  假設向8位AD中讀取數據,AD獲取程序爲getad(),採用濾波算法增加數據精度。

1.限幅濾波(程序判斷濾波)

   原理:根據經驗確定兩次採樣之間所允許的最大偏差值(假定爲MAX),每次檢測到新值(new_value)時作出判斷。若差值在允許的最大偏差之內,則當前值爲有效值,反之,則用上次值(value)替代當前值。

  優勢:能克服偶然因素引起的脈衝干擾。

代碼示範:

#define MAX 10
char value;
char LimitFileter()
{
char new_value;
new_value = getad();
if((new_value-value>MAX) || (value-new_value>MAX))
  return value;
return new_value;
}

2.中值濾波法

   原理:連續採樣奇數次(N),獲取奇數個數值,並按照大小從左到右進行排序,取中間值爲本次有效值。

   優勢:能夠有效克服偶然因素引起的波動干擾,對於變化緩慢的參數測試有良好的濾波效果。

代碼示範:

#define N 11
char MedFilter()
{
char value_buf[N];
char count,i,j,temp;
for ( count = 0; count < N; count++)
{
value_buf[count] = getad();
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.算術平均濾波

   原理:連續取N個採樣值進行平均運算,N值較大時,信號平滑度較高,靈敏度較低。N值較小時,信號平滑度較低,靈敏度較  高。

   優勢:適用於一般具有隨機干擾的信號進行濾波。

代碼示範:

#define N 12
char AverageFileter()
{
int sum = 0;
for ( count=0;count<N;count++)
{
sum + = getad();
delay();
}
return (char)(sum/N);
}

4.遞推平均濾波法

   原理:將連續採樣N個數據看成一個隊列,隊列長度固定爲N。每次採樣到一個新數據放入隊尾,並向前遞推一位數據,捨棄掉 原來的隊頭(先進先出原則)。再將隊列中N個數據進行算術平均運算。

   優勢:對週期性干擾有良好的抑制作用,適用於高頻振盪的系統。

代碼示範:

char value_buff[N];
char i=0;
char RecAveFileter()
{
char count;
int sum=0;
value_buff[i++]=getdata();
if(i==N)
i=0;
for(count=0;count<N;count++)
sum+=value_buff[count];
return (char)(sum/N);
}

5.中位值平均濾波法

   原理:即結合中位值濾波和算術平均濾波,連續採集N個數據,去掉一個最大值和一個最小值,然後計算剩下的N-2個數據的算術平均值。

   優勢:對於偶然出現的脈衝性干擾,可以消除由於脈衝干擾而引起的採值偏差。

代碼示範:

#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] = getad();
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.限幅平均濾波

   原理:即結合限幅濾波和遞推平均濾波。每次採樣到新數據進行限幅處理,再將有效值添加到隊列進行遞推平均濾波處理。

   優勢:能克服偶然因素引起的脈衝干擾,對週期性干擾有良好的抑制作用。

代碼示範:

#define MAX 10
#define N 12

char value;
char LimitFileter()
{
char new_value;
new_value = getad();
if((new_value-value>MAX) || (value-new_value>MAX))
  return value;
return new_value;
}
char AverageFileter()
{
int sum = 0;
for ( count=0;count<N;count++)
{
sum + = LimitFileter();
delay();
}
return (char)(sum/N);
}

7.一階滯後濾波

   原理:取a = 0~1,濾波結果 = (1-a)*本次採樣值+a*上次濾波結果。

   優勢:對週期性干擾具有良好的抑制作用,適用於波動頻率較高的場合。

代碼示範:

#define a 50
char value;
char FstOrdLagFileter()
{
char new_value;
new_value = get_ad();
return (100-a)*value + a*new_value;
}

8.加權遞推平均濾波

  原理:在遞推平均濾波法上進行的改進,不同時刻的數據加以不同的權,越接近現時刻的數據,權取得越大。新採樣值的權係數越大,靈敏度越高,但平滑度就越低。

  優勢:適用於週期較短的系統,有較大純滯後時間常數的對象。

代碼示範:

#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 WeiRecAveFileter()
{
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.消抖濾波

  原理:設置一個濾波計數器,每次採樣值與當前有效值比較,如果相同,則計數器清零,如果大於或小於當前有效值,則計數器加1,並判斷計數器是否溢出,如果溢出,則將本次值替換當前有效值,並將計數器清零。

  優勢:對於變化緩慢的被測參數有較好的濾波效果,可以避免在臨界值附近控制器的反覆開/關跳動或顯示器上數值的抖動。

代碼示範:

#define N 12
char DitherFileter()
{
char count=0;
char new_value;
new_value = getad();
while (value !=new_value);
{
count++;
if (count>=N) return new_value;
delay();
new_value = get_ad();
}
return value;
}

10.限幅消抖濾波

    原理:先限幅,後消抖。

    優勢:改進了消抖濾波中的一些缺陷,避免將干擾值導入系統。

代碼示範:

#define MAX 10
#define N 12
char value;
char LimitFileter()
{
char new_value;
new_value = getad();
if((new_value-value>MAX) || (value-new_value>MAX))
  return value;
return new_value;
}
char LimDitFileter()
{
char count=0;
char new_value;
new_value = LimitFileter();
while (value !=new_value);
{
count++;
if (count>=N) return new_value;
delay();
new_value = get_ad();
}
return value;
}

以上就是個人總結的10個常用的濾波算法,根據不同的事件,靈活運用這10種算法,能夠減少誤差數據的產生,從而提高自己的代碼質量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章