搜索
bottom↓
回复: 149

10种简单的数字滤波算法(C语言源程序)

  [复制链接]

出0入0汤圆

发表于 2012-2-20 23:19:13 | 显示全部楼层 |阅读模式
假定从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-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、算术平均滤波法
/*
*/

#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-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、限幅平均滤波法
/*
*/
略 参考子程序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

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入228汤圆

发表于 2012-4-23 17:38:20 | 显示全部楼层
抄来的

单片机利用软件抗干扰的几种滤波方法:

1、限幅滤波法(又称程序判断滤波法)
    A、方法:
        根据经验判断,确定两次采样允许的最大偏差值(设为A)
        每次检测到新值时判断:
        如果本次值与上次值之差<=A,则本次值有效
        如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值
    B、优点:
        能有效克服因偶然因素引起的脉冲干扰
    C、缺点
        无法抑制那种周期性的干扰
        平滑度差
   
2、中位值滤波法
    A、方法:
        连续采样N次(N取奇数)
        把N次采样值按大小排列
        取中间值为本次有效值
    B、优点:
        能有效克服因偶然因素引起的波动干扰
        对温度、液位的变化缓慢的被测参数有良好的滤波效果
    C、缺点:
        对流量、速度等快速变化的参数不宜

3、算术平均滤波法
    A、方法:
        连续取N个采样值进行算术平均运算
        N值较大时:信号平滑度较高,但灵敏度较低
        N值较小时:信号平滑度较低,但灵敏度较高
        N值的选取:一般流量,N=12;压力:N=4
    B、优点:
        适用于对一般具有随机干扰的信号进行滤波
        这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动
    C、缺点:
        对于测量速度较慢或要求数据计算速度较快的实时控制不适用
        比较浪费RAM
        
4、递推平均滤波法(又称滑动平均滤波法)
    A、方法:
        把连续取N个采样值看成一个队列
        队列的长度固定为N
        每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则)
        把队列中的N个数据进行算术平均运算,就可获得新的滤波结果
        N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4
    B、优点:
        对周期性干扰有良好的抑制作用,平滑度高
        适用于高频振荡的系统   
    C、缺点:
        灵敏度低
        对偶然出现的脉冲性干扰的抑制作用较差
        不易消除由于脉冲干扰所引起的采样值偏差
        不适用于脉冲干扰比较严重的场合
        比较浪费RAM
        
5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
    A、方法:
        相当于“中位值滤波法”+“算术平均滤波法”
        连续采样N个数据,去掉一个最大值和一个最小值
        然后计算N-2个数据的算术平均值
        N值的选取:3~14
    B、优点:
        融合了两种滤波法的优点
        对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差
    C、缺点:
        测量速度较慢,和算术平均滤波法一样
        比较浪费RAM


6、限幅平均滤波法
    A、方法:
        相当于“限幅滤波法”+“递推平均滤波法”
        每次采样到的新数据先进行限幅处理,
        再送入队列进行递推平均滤波处理
    B、优点:
        融合了两种滤波法的优点
        对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差
    C、缺点:
        比较浪费RAM

7、一阶滞后滤波法
    A、方法:
        取a=0~1
        本次滤波结果=(1-a)*本次采样值+a*上次滤波结果
    B、优点:
        对周期性干扰具有良好的抑制作用
        适用于波动频率较高的场合
    C、缺点:
        相位滞后,灵敏度低
        滞后程度取决于a值大小
        不能消除滤波频率高于采样频率的1/2的干扰信号
        
8、加权递推平均滤波法
    A、方法:
        是对递推平均滤波法的改进,即不同时刻的数据加以不同的权
        通常是,越接近现时刻的数据,权取得越大。
        给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低
    B、优点:
        适用于有较大纯滞后时间常数的对象
        和采样周期较短的系统
    C、缺点:
        对于纯滞后时间常数较小,采样周期较长,变化缓慢的信号
        不能迅速反应系统当前所受干扰的严重程度,滤波效果差

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

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

出0入0汤圆

发表于 2012-4-24 08:26:29 | 显示全部楼层
这种基础知识好啊。

出0入0汤圆

发表于 2012-4-28 13:24:41 | 显示全部楼层
楼主的滑动滤波法不对,应该是:
#define N 12
char value_buf[N];
char i=0;
int sum=0;
char filter()
{
  char Temp_Value;

  Temp_Value = get_ad();
  sum += value_buf[i] - Temp_Value;
  value_buf[i++] = Temp_Value;
  if ( i == N ) i = 0;
  return (char)(sum/N);
}//注意 value_buf全部初始化为第一次采集的值!!

出0入0汤圆

发表于 2012-4-28 14:47:44 | 显示全部楼层
學習中.. 謝謝..

出0入0汤圆

发表于 2012-6-15 15:32:16 | 显示全部楼层
学习学习 顶下

出0入0汤圆

发表于 2012-7-11 13:56:16 | 显示全部楼层
仔细研究下

出0入0汤圆

发表于 2012-7-11 14:25:46 | 显示全部楼层
顶。学习了。

出0入0汤圆

发表于 2012-7-11 14:55:57 | 显示全部楼层
受教了!~~~~~~~~~

出0入0汤圆

发表于 2012-7-11 16:13:27 | 显示全部楼层
mark, 谢谢分享

出0入0汤圆

发表于 2012-7-11 17:14:18 | 显示全部楼层
mark too !

出0入0汤圆

发表于 2012-7-11 22:23:34 来自手机 | 显示全部楼层
写得太好了!

出0入0汤圆

发表于 2012-7-11 22:34:12 | 显示全部楼层
基本的东西,我几乎都是混合用的。

出0入0汤圆

发表于 2012-7-11 22:57:01 | 显示全部楼层
好好学习一下

出0入0汤圆

发表于 2012-7-12 06:05:12 来自手机 | 显示全部楼层
写得太好了!

出0入0汤圆

发表于 2012-7-23 14:02:35 | 显示全部楼层
不错,支持~~~

出0入0汤圆

发表于 2012-7-23 15:52:57 | 显示全部楼层
收了~~谢谢~~学习一下·

出0入0汤圆

发表于 2012-7-23 16:08:51 | 显示全部楼层
mark,好东西呀~

出0入0汤圆

发表于 2012-7-23 16:10:23 | 显示全部楼层
mark,好东西呀~

出0入0汤圆

发表于 2012-7-26 01:02:44 | 显示全部楼层
记号,等要用ADC的时候学习

出0入0汤圆

发表于 2012-8-12 10:46:20 | 显示全部楼层
学习。。。。

出0入0汤圆

发表于 2012-8-12 10:51:20 | 显示全部楼层
谢谢,学习了

出0入0汤圆

发表于 2012-8-12 12:35:16 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2012-8-12 12:39:55 | 显示全部楼层
学习                             

出0入0汤圆

发表于 2012-8-12 14:23:49 | 显示全部楼层
做个记号

出0入0汤圆

发表于 2012-12-21 14:04:19 | 显示全部楼层
先复制,留在之后测试!

出0入0汤圆

发表于 2012-12-21 14:33:23 | 显示全部楼层
很好,正 好用到,顶。

出0入0汤圆

发表于 2012-12-21 21:21:45 | 显示全部楼层
这是好资料

出0入0汤圆

发表于 2012-12-22 10:06:22 | 显示全部楼层
mark~~~

出0入0汤圆

发表于 2012-12-23 13:47:19 | 显示全部楼层
感谢楼主分享

出0入0汤圆

发表于 2013-3-6 16:53:50 | 显示全部楼层
收藏,感谢楼主分享

出0入0汤圆

发表于 2013-3-6 22:02:33 来自手机 | 显示全部楼层
不错,学习学习

出0入0汤圆

发表于 2013-3-6 22:29:25 | 显示全部楼层
挺好的 积累下
头像被屏蔽

出0入0汤圆

发表于 2013-3-6 23:20:58 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2013-3-6 23:27:00 来自手机 | 显示全部楼层
不错,学习了

出0入0汤圆

发表于 2013-3-7 00:15:09 来自手机 | 显示全部楼层
好东西哈!mark备用

出0入0汤圆

发表于 2013-3-10 00:10:10 | 显示全部楼层
不错。。。。

出0入0汤圆

发表于 2013-3-10 00:26:34 | 显示全部楼层
学习mark

出0入0汤圆

发表于 2013-3-12 17:41:59 来自手机 | 显示全部楼层
还可以论坛需要这样基础的东西

出0入0汤圆

发表于 2013-3-13 08:10:00 来自手机 | 显示全部楼层
好东西。支持一下

出0入0汤圆

发表于 2013-3-13 13:27:50 | 显示全部楼层
都是8位计算呀?

出0入0汤圆

发表于 2013-3-13 13:28:15 | 显示全部楼层
采样值要是10位的怎么弄呢?

出0入0汤圆

发表于 2013-3-13 19:03:30 | 显示全部楼层
学习了。。。。

出0入0汤圆

发表于 2013-3-14 08:50:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2013-3-14 09:03:12 | 显示全部楼层
很好很好,正要搞一搞滤波算法呢,楼主很给力

出0入0汤圆

发表于 2013-3-14 09:04:38 | 显示全部楼层
学习一下

出0入8汤圆

发表于 2013-3-16 20:28:52 来自手机 | 显示全部楼层
初学,谢谢分享!

出0入0汤圆

发表于 2013-3-18 17:27:43 | 显示全部楼层
留爪印,学习!!

出0入0汤圆

发表于 2013-3-18 17:29:21 | 显示全部楼层
wxws 发表于 2012-4-23 17:38
抄来的

单片机利用软件抗干扰的几种滤波方法:

谢谢楼主啊,很好的资料

出0入0汤圆

发表于 2013-3-21 21:39:58 | 显示全部楼层
最好再来个汇编板的

出0入0汤圆

发表于 2013-3-21 21:43:36 | 显示全部楼层
谢谢,学习一下。

出0入0汤圆

发表于 2013-3-25 22:43:41 | 显示全部楼层
简单,实用的基础知识啊,好

出0入0汤圆

发表于 2013-9-26 10:19:32 | 显示全部楼层
好东西,收藏了

出0入0汤圆

发表于 2013-9-26 22:12:27 来自手机 | 显示全部楼层
记号,学习了

出0入0汤圆

发表于 2013-9-26 22:38:34 | 显示全部楼层
不错,留个记号,备用

出0入0汤圆

发表于 2013-9-26 22:40:01 | 显示全部楼层
谢谢楼主,学习了。

出0入0汤圆

发表于 2013-10-12 22:34:50 | 显示全部楼层
mark,下次用到来拿。支持

出0入0汤圆

发表于 2013-10-13 00:08:30 | 显示全部楼层
wxws 发表于 2012-4-23 17:38
抄来的

单片机利用软件抗干扰的几种滤波方法:

写的非常好 非常有效

出0入0汤圆

发表于 2013-10-13 18:57:12 | 显示全部楼层
MARK

出0入0汤圆

发表于 2013-10-13 22:17:13 | 显示全部楼层
好贴,顶一个

出0入0汤圆

发表于 2014-3-27 23:17:33 | 显示全部楼层
不错的资料

出0入0汤圆

发表于 2014-3-27 23:41:43 来自手机 | 显示全部楼层
Mark一下哈

出0入0汤圆

发表于 2014-3-28 00:27:11 | 显示全部楼层
不错,对于没有算法经验的人讲解很详细实用

出0入0汤圆

发表于 2014-3-31 16:05:00 | 显示全部楼层
mark。。。

出0入0汤圆

发表于 2014-4-1 08:36:35 | 显示全部楼层
收藏以后用

出0入0汤圆

发表于 2014-4-7 16:40:32 | 显示全部楼层
很好,正是我要找的资料!

出0入0汤圆

发表于 2014-4-7 21:44:42 | 显示全部楼层
謝謝 分享!!10种简单的数字滤波算法(C语言源程序)

出0入0汤圆

发表于 2014-4-8 13:51:34 | 显示全部楼层
根据需要做权衡

出0入0汤圆

发表于 2014-4-8 14:01:14 | 显示全部楼层
呵呵,中位值滤波,为什么要排序?简单的东西,复杂化了。中位值无非就是去掉最大最小值而已,排序太麻烦了。贴上我自己的做法,给大家参考
//
//------------------------------
//
//  ÖÐλֵÂ˲¨
//  
//------------------------------
//
u16 GetTheMiddleValue(u16 *Pointer,u8 Length)
{
    u8 i;
    u32 temp32 = 0;

    u16 MaxVal = 0x0000;
    u16 MinVal = 0xffff;

    if ( Length>2 )
    {
        for ( i=0;i<Length;i++ )
        {
            if ( Pointer[i]> MaxVal)
            {
                MaxVal = Pointer[i];
            }
            if ( Pointer[i]<MinVal )
            {
                MinVal = Pointer[i];
            }
            temp32 += Pointer[i];
        }
        temp32 = (temp32-MaxVal-MinVal)/(Length-2);
    }
    else
    {
        for ( i=0;i<Length;i++ )
        {
            temp32 += Pointer[i];
        }
        temp32 = temp32/Length;
    }

    return (u16)temp32;
}

出0入0汤圆

发表于 2014-4-8 17:26:12 | 显示全部楼层
收藏收藏!

出0入0汤圆

发表于 2014-4-9 18:06:29 | 显示全部楼层
好的,学习了,谢谢楼主,收藏了

出500入8汤圆

发表于 2014-4-10 10:20:15 | 显示全部楼层
mark mark mark mark

出0入0汤圆

发表于 2014-4-10 11:06:09 来自手机 | 显示全部楼层
学习学习,谢谢

出0入0汤圆

发表于 2014-4-10 11:51:02 | 显示全部楼层
标记

出0入0汤圆

发表于 2014-4-12 12:52:48 | 显示全部楼层
继续这方面的资料,谢谢

出0入0汤圆

发表于 2014-4-12 13:10:55 | 显示全部楼层
go2deathward 发表于 2014-4-8 14:01
呵呵,中位值滤波,为什么要排序?简单的东西,复杂化了。中位值无非就是去掉最大最小值而已,排序太麻烦了 ...

+1  我也是这样用的。

出0入0汤圆

发表于 2014-4-12 13:17:23 | 显示全部楼层
学习,mark

出0入0汤圆

发表于 2014-5-5 13:34:59 | 显示全部楼层
不错,学习了

出0入0汤圆

发表于 2014-5-8 10:17:45 | 显示全部楼层
好东西 学习了

出0入0汤圆

发表于 2014-5-8 10:39:49 | 显示全部楼层
mark学习一下

出0入0汤圆

发表于 2014-5-10 13:16:49 | 显示全部楼层
收藏了。

出0入0汤圆

发表于 2014-5-10 14:57:06 | 显示全部楼层
收藏学习。

出0入0汤圆

发表于 2014-5-11 09:49:53 | 显示全部楼层
这么好的东西  留着

出0入0汤圆

发表于 2014-5-12 00:27:34 | 显示全部楼层
非常感谢!!!

出0入0汤圆

发表于 2014-6-27 14:48:02 | 显示全部楼层
mark++++++++++++++

出0入0汤圆

发表于 2014-7-12 16:23:20 | 显示全部楼层

mark,好东西呀~

出0入0汤圆

发表于 2014-7-12 21:52:48 | 显示全部楼层
学习了,不过挺基本的

出0入0汤圆

发表于 2014-7-13 02:23:06 | 显示全部楼层
go2deathward 发表于 2014-4-8 14:01
呵呵,中位值滤波,为什么要排序?简单的东西,复杂化了。中位值无非就是去掉最大最小值而已,排序太麻烦了 ...

没怎么看懂啊!

出0入0汤圆

发表于 2014-7-13 02:23:50 | 显示全部楼层
大家知道一阶滞后滤波常用在什么地方吗?

出0入0汤圆

发表于 2014-8-13 13:48:36 | 显示全部楼层
挺详细的,学习了。

出0入0汤圆

发表于 2014-8-20 01:41:42 | 显示全部楼层
mark  haodongxi

出0入0汤圆

发表于 2014-8-20 01:47:28 | 显示全部楼层
好东西, 收常了

出0入0汤圆

发表于 2014-8-24 19:32:36 | 显示全部楼层
挺好东西

出0入4汤圆

发表于 2014-8-25 11:13:27 | 显示全部楼层
mark,字数补丁!

出0入0汤圆

发表于 2014-10-31 15:55:50 | 显示全部楼层
收藏,谢谢分享

出0入0汤圆

发表于 2014-10-31 16:05:26 | 显示全部楼层
收藏,谢谢分享

出0入0汤圆

发表于 2014-10-31 16:06:27 | 显示全部楼层
mark,标记。。。

出0入0汤圆

发表于 2014-11-1 10:25:12 | 显示全部楼层
收藏,学习

出0入0汤圆

发表于 2014-11-1 10:30:24 | 显示全部楼层
谢谢分享。。。学学习

出0入0汤圆

发表于 2014-11-1 13:25:31 | 显示全部楼层
wxws 发表于 2012-4-23 17:38
抄来的

单片机利用软件抗干扰的几种滤波方法:

Mark for after days to read
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 15:04

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表