单片机滤波程序_中位值平均滤波法单片机程序 - CSDN
  • 下面主要是介绍如何用单片机实现数字滤波。 在单片机进行数据采集时,会遇到数据的随机误差,随机误差是由随机干扰引起的,其特点是在相同条件下测量同一量时,其大小和符号会现无规则的变化而无法预测,但多次...

    单片机主要作用是控制外围的器件,并实现一定的通信和数据处理。但在某些特定场合,不可避免地要用到数学运算,尽管单片机并不擅长实现算法和进行复杂的运算。下面主要是介绍如何用单片机实现数字滤波。

     

    在单片机进行数据采集时,会遇到数据的随机误差,随机误差是由随机干扰引起的,其特点是在相同条件下测量同一量时,其大小和符号会现无规则的变化而无法预测,但多次测量的结果符合统计规律。为克服随机干扰引起的误差,硬件上可采用滤波技术,软件上可采用软件算法实现数字滤波。滤波算法往往是系统测控算法的一个重要组成部分,实时性很强。

     

    采用数字滤波算法克服随机干扰的误差具有以下优点:

     

    1、数字滤波无需其他的硬件成本,只用一个计算过程,可靠性高,不存在阻抗匹配问题。尤其是数字滤波可以对频率很低的信号进行滤波,这是模拟滤波器做不到的。

     

    2、数字滤波使用软件算法实现,多输入通道可共用一个滤波程序,降低系统开支。

     

    3、只要适当改变滤波器的滤波程序或运算,就能方便地改变其滤波特性,这对于滤除低频干扰和随机信号会有较大的效果。

     

    4、在单片机系统中常用的滤波算法有限幅滤波法、中值滤波法、算术平均滤波法、加权平均滤波法、滑动平均滤波等。

     

    (1)限幅滤波算法

     

    该运算的过程中将两次相邻的采样相减,求出其增量,然后将增量的绝对值,与两次采样允许的最大差值A进行比较。A的大小由被测对象的具体情况而定,如果小于或等于允许的最大差值,则本次采样有效;否则取上次采样值作为本次数据的样本。

     

    算法的程序代码如下:

    #defineA //允许的最大差值chardata; //上一次的数据char filter(){chardatanew; //新数据变量datanew=get_data(); //获得新数据变量if((datanew-data)>A||(data-datanew>A))return data;elsereturndatanew;}

     

    说明:限幅滤波法主要用于处理变化较为缓慢的数据,如温度、物体的位置等。使用时,关键要选取合适的门限制A。通常这可由经验数据获得,必要时可通过实验得到。

     

    (2)中值滤波算法

     

    该运算的过程是对某一参数连续采样N次(N一般为奇数),然后把N次采样的值按从小到大排列,再取中间值作为本次采样值,整个过程实际上是一个序列排序的过程。

     

    算法的程序代码如下:

    #define N11 //定义获得的数据个数char filter(){charvalue_buff[N]; //定义存储数据的数组char count,i,j,temp;for(count=0;count{value_buf[count]=get_data();delay(); //如果采集数据比较慢,那么就需要延时或中断}for(j=0;j{for(value_buff[i]>value_buff[i+1]{temp=value_buff[i];value_buff[i]=value_buff[i+1];value_buff[i+1]=temp;}}returnvalue_buff[(N-1)/2];}

     

    说明:中值滤波比较适用于去掉由偶然因素引起的波动和采样器不稳定而引起的脉动干扰。若被测量值变化比较慢,采用中值滤波法效果会比较好,但如果数据变化比较快,则不宜采用此方法。

     

    (3)算术平均滤波算法

     

    该算法的基本原理很简单,就是连续取N次采样值后进行算术平均。

     

    算法的程序代码如下:

    char filter(){int sum=0;for(count=0;count{sum+=get_data();delay():}return (char)(sum/N);}

     

    说明:算术平均滤波算法适用于对具有随机干扰的信号进行滤波。这种信号的特点是有一个平均值,信号在某一数值附近上下波动。信号的平均平滑程度完全到决于N值。当N较大时,平滑度高,灵敏度低;当N较小时,平滑度低,但灵敏度高。为了方便求平均值,N一般取4、8、16、32之类的2的整数幂,以便在程序中用移位操作来代替除法。

     

    (4)加权平均滤波算法

     

    由于前面所说的“算术平均滤波算法”存在平滑度和灵敏度之间的矛盾。为了协调平滑度和灵敏度之间的关系,可采用加权平均滤波。它的原理是对连续N次采样值分别乘上不同的加权系数之后再求累加,加权系数一般先小后大,以突出后面若干采样的效果,加强系统对参数变化趋势的认识。各个加权系数均小于1的小数,且满足总和等于1的结束条件。这样加权运算之后的累加和即为有效采样值。设D为N个采样值的加权平均值:XN-i为第N-i次采样值;N为采样次数;Ci为加权系数。加权系数Ci体现了各种采样值在平均值中所占的比例。一般来说采样次数越靠后,取的比例越大,这样可增加新采样在平均值中所占的比重。加权平均值滤波法可突出一部分信号抵制另一部分信号,以提高采样值变化的灵敏度。

     

    样例程序代码如下:

    char codejq[N]={1,2,3,4,5,6,7,8,9,10,11,12}; //code数组为加权系数表,存在程序存储区char codesum_jq=1+2+3+4+5+6+7+8+9+10+11+12;char filter(){char count;char value_buff[N];int sum=0;for(count=0;count{value_buff[count]=get_data();delay();}for(count=0;countsum+=value_buff[count]*jq[count];return(char)(sum/sum_jq);}

     

    (5)滑动平均滤波算法

     

    以上介绍和各种平均滤波算法有一个共同点,即每获取一个有效采样值必须连续进行若干次采样,当采速度慢时,系统的实时得不到保证。这里介绍的滑动平均滤波算法只采样一次,将一次采样值和过去的若干次采样值一起求平均,得到的有效采样值即可投入使用。如果取N个采样值求平均,存储区中必须开辟N个数据的暂存区。每新采集一个数据便存入暂存区中,同时去掉一个最老数据,保存这N个数据始终是最新更新的数据。采用环型队列结构可以方便地实现这种数据存放方式。

     

    程序代码如下:

    char value_buff[N];char i=0;char filter(){char count;int sum=0;value_buff[i++]=get_data();if(i==N)i=0;for(count=0;countsum=value_buff[count];return (char)(sum/N);}

     

    (6)低通滤波

     

    将普通硬件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以上的干搅信号应采用其他方式滤除,低通滤波算法程序于加权平均滤波相似,但加权系数只有两个:a和1-a。为计算方便,a取一整数,1-a用256-a,来代替,计算结果舍去最低字节即可,因为只有两项,a和1-a,均以立即数的形式编入程序中,不另外设表格。虽然采样值为单元字节(8位A/D)。为保证运算精度,滤波输出值用双字节表示,其中一个字节整数,一字节小数,否则有可能因为每次舍去尾数而使输出不会变化。

     

    设Yn-1存放在30H(整数)和31H(小数)两单元中,Yn存放在32H(整数)和33H(小数)中。

     

    小结一下吧:数字滤波器,说白了,就是多次采样求平均值的一个过程,精确一点的,就是再顺序排列,去掉首位再求平均值,就是求平均数!

    展开全文
  • 提供几种C语言滤波方法,平均方法,这是我从网上下载下来的,觉得很有用,所以也共享一下
  • 单片机常用滤波算法

    2018-12-14 10:46:59
    一、 限幅滤波法(又称程序判断滤波法)  A、方法:   根据经验判断,确定两次采样允许的最大偏差值(设为 A)   每次检测到新值时判断:   如果本次值与上次值之差<=A,则本次值有效   如...


    说明:假定从 8位 AD中读取数据(如果是更高位的 AD可定义数据类型为 int),子程序为 get_ad();  
     
    一、  限幅滤波法(又称程序判断滤波法) 
    A、方法: 
              根据经验判断,确定两次采样允许的最大偏差值(设为 A) 
              每次检测到新值时判断: 
              如果本次值与上次值之差<=A,则本次值有效 
              如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次 
    B、优点: 
              能有效克服因偶然因素引起的脉冲干扰 
    C、缺点 
              无法抑制那种周期性的干扰 
              平滑度差 
    D、示例 

    #define A 10 
    char value; 
    char filter() 
    { 
        char new_value; 
        new_value = get_ad(); 
        if ( ( new_value - value > A ) || ( value - new_value > A ) 
            return value; 
        return new_value; 
    } 


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

    /* N值可根据实际情况调整排序采用冒泡法*/  
    #define N 11 
    char filter() 
    { 
        char value_buf[N]; 
        char 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 > value_buf[i + 1] ) 
                { 
                    temp = value_buf; 
                    value_buf = value_buf[i + 1];  
                    value_buf[i + 1] = temp; 
                } 
            } 
        }
     
        return value_buf[(N-1)/2]; 
    }  


     
    三、  算术平均滤波法 
    A、方法: 
              连续取N 个采样值进行算术平均运算 
              N值较大时:信号平滑度较高,但灵敏度较低 
              N值较小时:信号平滑度较低,但灵敏度较高 
              N值的选取:一般流量,N=12;压力:N=4 
    B、优点: 
              适用于对一般具有随机干扰的信号进行滤波 
              这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动 
    C、缺点: 
              对于测量速度较慢或要求数据计算速度较快的实时控制不适用 
              比较浪费 RAM 
    D、示例 

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


     
    四、  递推平均滤波法(又称滑动平均滤波法) 
    A、方法: 
              把连续取 N个采样值看成一个队列 
              队列的长度固定为N 
              每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则) 
              把队列中的N 个数据进行算术平均运算,就可获得新的滤波结果 
              N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4 
    B、优点: 
              对周期性干扰有良好的抑制作用,平滑度高 
              适用于高频振荡的系统 
    C、缺点: 
              灵敏度低 
              对偶然出现的脉冲性干扰的抑制作用较差 
              不易消除由于脉冲干扰所引起的采样值偏差 
              不适用于脉冲干扰比较严重的场合 
              比较浪费 RAM 
    D、示例 

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


     
    五、  中位值平均滤波法(又称防脉冲干扰平均滤波法) 
    A、方法: 
              相当于“中位值滤波法”+“算术平均滤波法” 
              连续采样 N个数据,去掉一个最大值和一个最小值 
              然后计算 N-2个数据的算术平均值 
              N值的选取:3~14 B、优点: 
              融合了两种滤波法的优点 
              对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差 
    C、缺点: 
              测量速度较慢,和算术平均滤波法一样 
              比较浪费 RAM 
    D、示例 

    #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] = get_ad(); 
            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)); 
    } 


     
    六、  限幅平均滤波法 
    A、方法: 
              相当于“限幅滤波法”+“递推平均滤波法” 
              每次采样到的新数据先进行限幅处理, 
              再送入队列进行递推平均滤波处理 
    B、优点: 
              融合了两种滤波法的优点 
              对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差 
    C、缺点:           比较浪费 RAM 
    D、示例 
        略 参考子程序1、3 
     
    七、  一阶滞后滤波法 
    A、方法: 
              取 a=0~1 
              本次滤波结果=(1-a)*本次采样值+a*上次滤波结果 
    B、优点: 
              对周期性干扰具有良好的抑制作用 
              适用于波动频率较高的场合 
    C、缺点: 
              相位滞后,灵敏度低 
              滞后程度取决于 a值大小 
              不能消除滤波频率高于采样频率的 1/2的干扰信号 
    D、示例 

    /* 为加快程序处理速度假定基数为 100,a=0~100 */ 
    #define a 50 
    char value; 
    char filter() 
    { 
        char new_value; 
        new_value = get_ad(); 
        return (100-a)*value + a*new_value;  
    } 


     
    八、  加权递推平均滤波法 
    A、方法: 
              是对递推平均滤波法的改进,即不同时刻的数据加以不同的权 
              通常是,越接近现时刻的数据,权取得越大。 
              给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低 
    B、优点: 
              适用于有较大纯滞后时间常数的对象 
              和采样周期较短的系统 
    C、缺点: 
              对于纯滞后时间常数较小,采样周期较长,变化缓慢的信号 
              不能迅速反应系统当前所受干扰的严重程度,滤波效果差 
    D、示例 

    /* coe 数组为加权系数表,存在程序存储区。*/ 
    #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 filter() 
    {
        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); 
    } 


     
    九、  消抖滤波法 
    A、方法: 
              设置一个滤波计数器 
              将每次采样值与当前有效值比较: 
              如果采样值=当前有效值,则计数器清零 
              如果采样值<>当前有效值,则计数器+1,并判断计数器是否>=上限 N(溢出) 
                    如果计数器溢出,则将本次值替换当前有效值,并清计数器 
    B、优点: 
              对于变化缓慢的被测参数有较好的滤波效果, 
              可避免在临界值附近控制器的反复开/关跳动或显示器上数值抖动 
    C、缺点: 
              对于快速变化的参数不宜 
              如果在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当作有
    效值导入系统。 
    D、示例 
     

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

     


     十、  限幅消抖滤波法 
    A、方法: 
              相当于“限幅滤波法”+“消抖滤波法” 
              先限幅,后消抖 
    B、优点: 
              继承了“限幅”和“消抖”的优点 
              改进了“消抖滤波法”中的某些缺陷,避免将干扰值导入系统 
    C、缺点: 
              对于快速变化的参数不宜 
    D、示例 
        参考1、9 

    展开全文
  • 单片机学习笔记_10种软件滤波方法的示例程序 假定从8位AD中读取数据(如果是更高位的AD可定义数据类型为int),子程序为get_... 滤波程序返回有效的实际值 */ #define A 10 char value; char filter() {  char ne...

    单片机学习笔记_10种软件滤波方法的示例程序
    假定从8位AD中读取数据(如果是更高位的AD可定义数据类型为int),子程序为get_ad();

    1、限副滤波
    /*  A值可根据实际情况调整
        value为有效值,new_value为当前采样值
        滤波程序返回有效的实际值  */
    #define A 10

    char value;

    char filter()
    {
      char  new_value;
      new_value = get_ad();
      if ( ( new_value - value > A ) || ( value - new_value > A )
           return value;
           return new_value;

    }

    2、中位值滤波法
    /*  N值可根据实际情况调整
        排序采用冒泡法*/
    #define N  11

    char filter()
    {
    char value_buf[N];
      char count,i,j,temp;
      for ( count=0; count<N    ; count++)
      {
        value_buf[count] = get_ad();
        delay();
      }

      for (j=0; j <N  ; j++)
      {
        for (i=0; i < N-1 ; 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、算术平均滤波法
    /*
    */

    #define N 12

    char filter()
    {
      int  sum = 0;
      for ( count=0; count<N ; count++)
      {
        sum + = get_ad();
        delay();
      }
      return (char)(sum/N);
    }

    4、递推平均滤波法(又称滑动平均滤波法)
    /*
    */
    #define N 12

    char value_buf[N];
    char i=0;

    char filter()
    {
      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);
    }

    5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
    /*
    */
    #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] = get_ad();
        delay();
      }
      
      
      for (j=0; j < N ; j++)
      {
        for (i=0; i < N-1 ; 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  ; count++)
        sum += value[count];
      return (char)(sum/(N-2));
    }


    6、限幅平均滤波法
    /*
    */
    略 参考子程序1、3

    7、一阶滞后滤波法
    /* 为加快程序处理速度假定基数为100,a=0~100 */

    #define a 50

    char value;

    char filter()
    {
      char  new_value;
      new_value = get_ad();
      return (100-a)*value + a*new_value;
    }

    8、加权递推平均滤波法
    /* coe数组为加权系数表,存在程序存储区。*/

    #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 filter()
    {
      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、消抖滤波法

    #define N 12

    char filter()
    {
      char count=0;
      char new_value;
      new_value = get_ad();
      
      while (value != new_value);
      {
        count++;
        if (count>=N)   return new_value;
        delay();
        new_value = get_ad();
      }
      return value;
    }


    10、限幅消抖滤波法
    /*
    */
    略 参考子程序1、9

    11、IIR滤波例子

    int  BandpassFilter4(int InputAD4)
    {
      int  ReturnValue;
      int  ii;
      RESLO=0;
      RESHI=0;
      MACS=*PdelIn;
      OP2=1068; //FilterCoeff4[4];
      MACS=*(PdelIn+1);
      OP2=8;    //FilterCoeff4[3];
      MACS=*(PdelIn+2);
      OP2=-2001;//FilterCoeff4[2];
      MACS=*(PdelIn+3);
      OP2=8;    //FilterCoeff4[1];
      MACS=InputAD4;
      OP2=1068; //FilterCoeff4[0];
      MACS=*PdelOu;
      OP2=-7190;//FilterCoeff4[8];
      MACS=*(PdelOu+1);
      OP2=-1973; //FilterCoeff4[7];
      MACS=*(PdelOu+2);
      OP2=-19578;//FilterCoeff4[6];
      MACS=*(PdelOu+3);
      OP2=-3047; //FilterCoeff4[5];
      *p=RESLO;
      *(p+1)=RESHI;
      mytestmul<<=2;
      ReturnValue=*(p+1);
      for  (ii=0; ii<3; ii++)
      {
        DelayInput[ii]=DelayInput[ii+1];
        DelayOutput[ii]=DelayOutput[ii+1];
      }
      DelayInput[3]=InputAD4;
      DelayOutput[3]=ReturnValue;

      //  if (ReturnValue<0)
      //  {
      //  ReturnValue=-ReturnValue;
      //  }
      return ReturnValue;
    }

    展开全文
  • 6种常见的单片机数字滤波算法

    千次阅读 2018-01-26 15:32:43
    下面主要是介绍如何用单片机实现数字滤波。 在单片机进行数据采集时,会遇到数据的随机误差,随机误差是由随机干扰引起的,其特点是在相同条件下测量同一量时,其大小和符号会现无规则的变化而无法预测,但多次...

    单片机主要作用是控制外围的器件,并实现一定的通信和数据处理。但在某些特定场合,不可避免地要用到数学运算,尽管单片机并不擅长实现算法和进行复杂的运算。下面主要是介绍如何用单片机实现数字滤波。


    在单片机进行数据采集时,会遇到数据的随机误差,随机误差是由随机干扰引起的,其特点是在相同条件下测量同一量时,其大小和符号会现无规则的变化而无法预测,但多次测量的结果符合统计规律。为克服随机干扰引起的误差,硬件上可采用滤波技术,软件上可采用软件算法实现数字滤波。滤波算法往往是系统测控算法的一个重要组成部分,实时性很强。


    采用数字滤波算法克服随机干扰的误差具有以下优点


    1、数字滤波无需其他的硬件成本,只用一个计算过程,可靠性高,不存在阻抗匹配问题。尤其是数字滤波可以对频率很低的信号进行滤波,这是模拟滤波器做不到的。


    2、数字滤波使用软件算法实现,多输入通道可共用一个滤波程序,降低系统开支。


    3、只要适当改变滤波器的滤波程序或运算,就能方便地改变其滤波特性,这对于滤除低频干扰和随机信号会有较大的效果。


    4、在单片机系统中常用的滤波算法有限幅滤波法、中值滤波法、算术平均滤波法、加权平均滤波法、滑动平均滤波等。


    (1)限幅滤波算法

    该运算的过程中将两次相邻的采样相减,求出其增量,然后将增量的绝对值,与两次采样允许的最大差值A进行比较。A的大小由被测对象的具体情况而定,如果小于或等于允许的最大差值,则本次采样有效;否则取上次采样值作为本次数据的样本。


    算法的程序代码如下:


    #defineA //允许的最大差值

    chardata; //上一次的数据

    char filter()

    {

    chardatanew; //新数据变量

    datanew=get_data(); //获得新数据变量

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

    return data;

    else

    returndatanew;

    }


    说明:限幅滤波法主要用于处理变化较为缓慢的数据,如温度、物体的位置等。使用时,关键要选取合适的门限制A。通常这可由经验数据获得,必要时可通过实验得到。


    (2)中值滤波算法

    该运算的过程是对某一参数连续采样N次(N一般为奇数),然后把N次采样的值按从小到大排列,再取中间值作为本次采样值,整个过程实际上是一个序列排序的过程。


    算法的程序代码如下:


    #define N11 //定义获得的数据个数

    char filter()

    {

    charvalue_buff[N]; //定义存储数据的数组

    char count,i,j,temp;

    for(count=0;count

    {

    value_buf[count]=get_data();

    delay(); //如果采集数据比较慢,那么就需要延时或中断

    }

    for(j=0;j

    {

    for(value_buff[i]>value_buff[i+1]

    {

    temp=value_buff[i];

    value_buff[i]=value_buff[i+1];

    value_buff[i+1]=temp;

    }

    }

    returnvalue_buff[(N-1)/2];

    }


    说明:中值滤波比较适用于去掉由偶然因素引起的波动和采样器不稳定而引起的脉动干扰。若被测量值变化比较慢,采用中值滤波法效果会比较好,但如果数据变化比较快,则不宜采用此方法。


    (3)算术平均滤波算法

    该算法的基本原理很简单,就是连续取N次采样值后进行算术平均。


    算法的程序代码如下:


    char filter()

    {

    int sum=0;

    for(count=0;count

    {

    sum+=get_data();

    delay():

    }

    return (char)(sum/N);

    }


    说明:算术平均滤波算法适用于对具有随机干扰的信号进行滤波。这种信号的特点是有一个平均值,信号在某一数值附近上下波动。信号的平均平滑程度完全到决于N值。当N较大时,平滑度高,灵敏度低;当N较小时,平滑度低,但灵敏度高。为了方便求平均值,N一般取4、8、16、32之类的2的整数幂,以便在程序中用移位操作来代替除法。


    (4)加权平均滤波算法

    由于前面所说的“算术平均滤波算法”存在平滑度和灵敏度之间的矛盾。为了协调平滑度和灵敏度之间的关系,可采用加权平均滤波。它的原理是对连续N次采样值分别乘上不同的加权系数之后再求累加,加权系数一般先小后大,以突出后面若干采样的效果,加强系统对参数变化趋势的认识。各个加权系数均小于1的小数,且满足总和等于1的结束条件。这样加权运算之后的累加和即为有效采样值。其中加权平均数字滤波的数学模型是:


    式中:D为N个采样值的加权平均值:XN-i为第N-i次采样值;N为采样次数;Ci为加权系数。加权系数Ci体现了各种采样值在平均值中所占的比例。一般来说采样次数越靠后,取的比例越大,这样可增加新采样在平均值中所占的比重。加权平均值滤波法可突出一部分信号抵制另一部分信号,以提高采样值变化的灵敏度。

    样例程序代码如下:


    char codejq[N]={1,2,3,4,5,6,7,8,9,10,11,12}; //code数组为加权系数表,存在程序存储区

    char codesum_jq=1+2+3+4+5+6+7+8+9+10+11+12;

    char filter()

    {

    char count;

    char value_buff[N];

    int sum=0;

    for(count=0;count

    {

    value_buff[count]=get_data();

    delay();

    }

    for(count=0;count

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

    return(char)(sum/sum_jq);

    }


    (5)滑动平均滤波算法

    以上介绍和各种平均滤波算法有一个共同点,即每获取一个有效采样值必须连续进行若干次采样,当采速度慢时,系统的实时得不到保证。这里介绍的滑动平均滤波算法只采样一次,将一次采样值和过去的若干次采样值一起求平均,得到的有效采样值即可投入使用。如果取N个采样值求平均,存储区中必须开辟N个数据的暂存区。每新采集一个数据便存入暂存区中,同时去掉一个最老数据,保存这N个数据始终是最新更新的数据。采用环型队列结构可以方便地实现这种数据存放方式。


    程序代码如下:


    char value_buff[N];

    char i=0;

    char filter()

    {

    char count;

    int sum=0;

    value_buff[i++]=get_data();

    if(i==N)

    i=0;

    for(count=0;count

    sum=value_buff[count];

    return (char)(sum/N);

    }


    (6)低通滤波

    将普通硬件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以上的干搅信号应采用其他方式滤除,低通滤波算法程序于加权平均滤波相似,但加权系数只有两个:a和1-a。为计算方便,a取一整数,1-a用256-a,来代替,计算结果舍去最低字节即可,因为只有两项,a和1-a,均以立即数的形式编入程序中,不另外设表格。虽然采样值为单元字节(8位A/D)。为保证运算精度,滤波输出值用双字节表示,其中一个字节整数,一字节小数,否则有可能因为每次舍去尾数而使输出不会变化

    展开全文
  • 单片机 滤波 滤波汇编程序 滑动滤波单片机 滤波 滤波汇编程序 滑动滤波单片机 滤波 滤波汇编程序 滑动滤波 很好,很详细的程序
  • 滤波方式,单片机滤波,汇编程序滤波方式,单片机滤波,汇编程序滤波方式,单片机滤波,汇编程序
  • 一个非常适合单片机滤波算法

    千次阅读 2015-04-17 11:55:54
    连接:http://bbs.21ic.com/icview-170880-1-1.html -------------------------------------------------以下为原文 ------------------- 连接:...单片机大多资源小,算法占用
  • MCS51单片机滤波程序MCS51单片机滤波程序MCS51单片机滤波程序MCS51单片机滤波程序MCS51单片机滤波程序MCS51单片机滤波程序MCS51单片机滤波程序MCS51单片机滤波程序MCS51单片机滤波程序
  • C51程序实现移动平均滤波,比平均值滤波更具效率
  • 单片机滤波算法

    2019-10-10 19:20:49
    下面我们来简单介绍一下软件是如何进行单片机滤波的,这就要引出我们今天的主题--滤波算法。 滤波算法是什么呢?既然是算法,那就要运用到数学公式了,即通过算法将我们检测到误差大的数据进行处理,从而达到滤波...
  • 这篇把单片机数字滤波算法讲绝了

    千次阅读 2018-01-28 13:59:04
    下面主要是介绍如何用单片机实现数字滤波。在单片机进行数据采集时,会遇到数据的随机误差,随机误差是由随机干扰引起的,其特点是在相同条件下测量同一量时,其大小和符号会现无规则的变化而无法预测,但多次测量的...
  • /************************************************************** 函数名称:NtcAD_Testing() 函数功能:温度传感器采样函数 入口参数: 出口参数:Flag_Ntc_OneAd,AdResult 备 注:采样NTC的AD值,采样6次...
  • 单片机实现软件滤波

    2015-04-29 14:07:43
    单片机实现软件滤波  1、限幅滤波法(又称程序判断滤波法)  A、方法:  根据经验判断,确定两次采样允许的最大偏差值(设为A)  每次检测到新值时判断:  如果本次值与上次值之差  如果本次值与...
  • 在AD采集中经常要用到数字滤波,而不同情况下又有不同的滤波需求,下面是10种经典的软件滤波方法的程序和优缺点分析:  1、限幅滤波法(又称程序判断滤波法)  2、中位值滤波法  3、算术平均滤波法  4、递推...
  • 单片机数字滤波 的 一段 代码程序

    千次阅读 2014-02-02 19:13:40
    unsigned int filter_method(void) {  unsigned int new_value,value;  aa=ReadADC();... if(value > 8366) //这个值是一个你不要的值 如果字在 8342-8366 之间跳 这个 8366肯定是我们不要的直接去掉 ...
  • 单片机常用滤波算法  说明:假定从8位AD中读取数据(如果是更高位的AD可定义数据类型为int),子程序为get_ad(); 1、限幅滤波法 (又称程序判断滤波法) A、方法: 根据经验判断,确定两次采样允许的最大偏差值...
  • 用于c51单片机编程,用于消除adc转化时的抖动。
  • 限幅滤波法(又称程序判断滤波法) 中位值滤波法 算术平均滤波法 递推平均滤波法(又称滑动平均滤波法) 中位值平均滤波法(又称防脉冲干扰平均滤波法) 限幅平均滤波法 一阶滞后滤波法 加权递推平均滤波法 ...
1 2 3 4 5 ... 20
收藏数 2,884
精华内容 1,153
关键字:

单片机滤波程序