首页 > 技术文章 > 简单常用滤波算法C语言实现

lwwBKY 2020-12-01 21:58 原文

 

采用数字滤波算法克服随机干扰的误差具有以下优点:
a.数字滤波无需其他的硬件成本,只用一个计算过程,可靠性高,不存在阻抗匹配问题。尤其是数字滤波可以对频率很低的信号进行滤波,这是模拟滤波器做不到的。
b.数字滤波使用软件算法实现,多输入通道可共用一个滤波程序,降低系统开支。
c.只要适当改变滤波器的滤波程序或运算,就能方便地改变其滤波特性,这对于滤除低频干扰和随机信号会有较大的效果。
d.在单片机系统中常用的滤波算法有限幅滤波法、中值滤波法、算术平均滤波法、加权平均滤波法、滑动平均滤波等。

1.限幅滤波算法(程序判断滤波算法)

方法解析:
根据经验判断,确定两次采样允许的最大偏差值(设定为A),每次检测到新值时判断:
如果本次值与上次值之差<=A,则本次值有效,
如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值。
优点:
能有效克服因偶然因素引起的脉冲干扰。
缺点:
无法抑制那种周期性的干扰,平滑度差。

#define  A     10     //允许的最大差值
unsigend short value; //上一次数据
unsigend short filter(void)
{
unsigend short new_value;
new_value
= get_ad();//获取新数据 if((new_value - value > A) || (value - new_value > A) return value; return new_value; }

2.中位值滤波法

方法解析:
连续采样N次(N取奇数),把N次采样值按大小排列,取中间值为本次有效值。
优点:
能有效克服因偶然因素引起的波动干扰,对温度,液位的变化缓慢的被测参数有良好的滤波效果。
缺点:
对流量,速度等快速变化的参数不宜。

#define  N     11            //定义获取的数据个数
unsigned short value_buf[N]; //定义存储数据的数组 unsigned short filter(void) { unsigned short count, i, j, temp; for(count = 0; count < N; count++) { value_buf[count] = 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; } } } return value_buf[(N - 1) / 2]; }

3.算术平均滤波

方法解析:
连续取N个采样值进行平均运算,N值较大时:信号平滑度较高,但灵敏度较低
N值较小时,信号平滑度较低,但灵敏度较高。N值的选取:一般2n左右,以便程序用移位做除法。
优点:
适应于对一般具有随机干扰的信号进行滤波,这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动。
缺点:
对于测量速度较慢或要求数据计算速度较快的实时控制并不适用,比较浪费RAM。

#define  N     8 //获取的数据个数
unsigned short filter(void)
{
  unsigned int sum = 0;
  for(count = 0; count < N; count++)
  {
    sum + = get_ad();
    delay();
  }
  return (unsigned short)(sum / N); 
}

4.滑动平均滤波法

方法解析:
把连续取N个采样值看成一个队列,队列的长度固定为N,每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据(先进先出)。
把队列中的N个数据进行算术平均运算,就可获得新的滤波结果。N值的选取:一般12。
优点:
对周期性干扰有良好的抑制作用,平滑度高,适应于高频振荡的系统。
缺点:
灵敏度低,对偶然出现的脉冲性干扰的抑制作用较差。不易消除由于脉冲干扰所引起打的采样值偏差,不适用于脉冲干扰比较严重的场合,浪费RAM。

#define  N     12 
unsigned short value_buf[N];
unsigned short i = 0;
unsigned short filter()
{
  unsigned short count;
  unsigned int sum=0;
  value_buf[i++] = get_ad();
  if(i == N) i = 0;
  for(count = 0; count < N, count++)
     sum = value_buf[count];
  return (unsigned short )(sum / N);
}

5.低通数字滤波

方法解析:

将普通硬件RC低通滤波器的微分方程用差分方程来表求,变可以采用软件算法来模拟硬件滤波的功能,经推导,低通滤波算法如下:

Yn=a* Xn+(1-a) *Yn-1
式中 Xn——本次采样值;
Yn-1——上次的滤波输出值;
a——滤波系数,其值通常远小于1;
Yn——本次滤波的输出值。

由上式可以看出,本次滤波的输出值主要取决于上次滤波的输出值(注意不是上次的采样值,这和加权平均滤波是有本质区别的),本次采样值对滤波输出的贡献是比较小的,但多少有些修正作用,这种算法便模拟了具体有教大惯性的低通滤波器功能。滤波算法的截止频率可用以下式计算:

fL=a/2Pit pi为圆周率3.14…;
式中 a——滤波系数;
t——采样间隔时间;
例如:当t=0.5s(即每秒2次),a=1/32时;
fL=(1/32)/(2*3.14*0.5)=0.01Hz;

当目标参数为变化很慢的物理量时,这是很有效的。另外一方面,它不能滤除高于1/2采样频率的干搅信号,本例中采样频率为2Hz,故对1Hz以上的干搅信号应采用其他方式滤除,

#define a   0.01       //滤波系数a(0-1)   
float value;           //滤波后的值  
float new_value;       //新的采样值  
float filter()   
{   
float new_value; new_value = get_ad(); return a * value + (1-a)*new_value;
}

 

推荐阅读