always123456 发表于 2012-2-20 23:19:13

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

假定从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;
        char count,i,j,temp;
        for ( count=0;count<N;count++)
        {
                value_buf = get_ad();
                delay();
        }
        for (j=0;j<N-1;j++)
        {
                for (i=0;i<N-j;i++)
                {
                        if ( value_buf>value_buf )
                        {
                                temp = value_buf;
                                value_buf = value_buf;
                                value_buf = 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;
char i=0;
char filter()
{
        char count;
        int sum=0;
        value_buf = get_ad();
        if ( i == N ) i = 0;
        for ( count=0;count<N,count++)
        sum = value_buf;
        return (char)(sum/N);
}

5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
/*
*/

#define N 12
char filter()
{
        char count,i,j;
        char value_buf;
        int sum=0;
        for (count=0;count<N;count++)
        {
                value_buf = get_ad();
                delay();
        }
        for (j=0;j<N-1;j++)
        {
                for (i=0;i<N-j;i++)
                {
                        if ( value_buf>value_buf )
                        {
                                temp = value_buf;
                                value_buf = value_buf;
                                value_buf = temp;
                        }
                }
        }
        for(count=1;count<N-1;count++)
        sum += value;
        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 = {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;
        int sum=0;
        for (count=0,count<N;count++)
        {
                value_buf = get_ad();
                delay();
        }
        for (count=0,count<N;count++)
        sum += value_buf*coe;
        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

wxws 发表于 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、缺点:
      对于快速变化的参数不宜

xue_pic 发表于 2012-4-24 08:26:29

这种基础知识好啊。

xuanke 发表于 2012-4-28 13:24:41

楼主的滑动滤波法不对,应该是:
#define N 12
char value_buf;
char i=0;
int sum=0;
char filter()
{
char Temp_Value;

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

et009.tw 发表于 2012-4-28 14:47:44

學習中.. 謝謝..

holyfire 发表于 2012-6-15 15:32:16

学习学习 顶下

moouse 发表于 2012-7-11 13:56:16

仔细研究下

lyg407 发表于 2012-7-11 14:25:46

顶。学习了。
{:lol:}

chenfzg 发表于 2012-7-11 14:55:57

受教了!~~~~~~~~~

lzy4072 发表于 2012-7-11 16:13:27

mark, 谢谢分享

downtoearth 发表于 2012-7-11 17:14:18

mark too !{:smile:}

fly_02827 发表于 2012-7-11 22:23:34

写得太好了!

蜂巢 发表于 2012-7-11 22:34:12

基本的东西,我几乎都是混合用的。

太阳哥 发表于 2012-7-11 22:57:01

好好学习一下

fly_02827 发表于 2012-7-12 06:05:12

写得太好了!

Yanna 发表于 2012-7-23 14:02:35

不错,支持~~~

miyadai 发表于 2012-7-23 15:52:57

收了~~谢谢~~学习一下·

孩子莫悲伤 发表于 2012-7-23 16:08:51

{:handshake:} mark,好东西呀~

易冰 发表于 2012-7-23 16:10:23

mark,好东西呀~

zhdo1983 发表于 2012-7-26 01:02:44

记号,等要用ADC的时候学习

浪漫朝霞 发表于 2012-8-12 10:46:20

学习。。。。

boling 发表于 2012-8-12 10:51:20

谢谢,学习了

司马朝阳007 发表于 2012-8-12 12:35:16

学习学习{:smile:}

mysunmax 发表于 2012-8-12 12:39:55

学习                           

tonyone 发表于 2012-8-12 14:23:49

做个记号

30zero 发表于 2012-12-21 14:04:19

先复制,留在之后测试!

welcome_cool 发表于 2012-12-21 14:33:23

很好,正 好用到,顶。

烂泥桑 发表于 2012-12-21 21:21:45

这是好资料

nixiu520 发表于 2012-12-22 10:06:22

mark~~~{:victory:}

yuanpooo 发表于 2012-12-23 13:47:19

感谢楼主分享

hjs666 发表于 2013-3-6 16:53:50

收藏,感谢楼主分享

jz701209李 发表于 2013-3-6 22:02:33

不错,学习学习

电子爱好者_MCU 发表于 2013-3-6 22:29:25

挺好的 积累下

3110411119 发表于 2013-3-6 23:20:58

gao_hailong 发表于 2013-3-6 23:27:00

不错,学习了

361ygzzj 发表于 2013-3-7 00:15:09

好东西哈!mark备用

rogerjw 发表于 2013-3-10 00:10:10

不错。。。。{:smile:}

wcm_e 发表于 2013-3-10 00:26:34

学习mark

cvi670 发表于 2013-3-12 17:41:59

还可以论坛需要这样基础的东西

随风允诺 发表于 2013-3-13 08:10:00

好东西。支持一下

dengxm2009 发表于 2013-3-13 13:27:50

都是8位计算呀?

dengxm2009 发表于 2013-3-13 13:28:15

采样值要是10位的怎么弄呢?

Baldwin 发表于 2013-3-13 19:03:30

学习了。。。。

andy520 发表于 2013-3-14 08:50:51

{:tongue:}mark

wangyeqing333 发表于 2013-3-14 09:03:12

很好很好,正要搞一搞滤波算法呢,楼主很给力

xiaojun2019 发表于 2013-3-14 09:04:38

学习一下

Jmhh247 发表于 2013-3-16 20:28:52

初学,谢谢分享!

biqi 发表于 2013-3-18 17:27:43

留爪印,学习!!{:loveliness:}

wallacer 发表于 2013-3-18 17:29:21

wxws 发表于 2012-4-23 17:38 static/image/common/back.gif
抄来的

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


谢谢楼主啊,很好的资料

一刀断天下 发表于 2013-3-21 21:39:58

最好再来个汇编板的

propor123 发表于 2013-3-21 21:43:36

谢谢,学习一下。

llz0734 发表于 2013-3-25 22:43:41

简单,实用的基础知识啊,好

夏末一直很在乎 发表于 2013-9-26 10:19:32

好东西,收藏了{:handshake:}

zy0818 发表于 2013-9-26 22:12:27

记号,学习了

贪吃的蚂蚁 发表于 2013-9-26 22:38:34

不错,留个记号,备用

Solar_Gao 发表于 2013-9-26 22:40:01

谢谢楼主,学习了。

jj632856828 发表于 2013-10-12 22:34:50

mark,下次用到来拿。支持

number007cool 发表于 2013-10-13 00:08:30

wxws 发表于 2012-4-23 17:38 static/image/common/back.gif
抄来的

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


写的非常好 非常有效

yangbing2020 发表于 2013-10-13 18:57:12

MARK{:lol:}{:lol:}{:lol:}

夕阳无限好 发表于 2013-10-13 22:17:13

好贴,顶一个

hj312192758 发表于 2014-3-27 23:17:33

不错的资料

huangguimina4 发表于 2014-3-27 23:41:43

Mark一下哈

元帅 发表于 2014-3-28 00:27:11

{:smile:}不错,对于没有算法经验的人讲解很详细实用

zjk 发表于 2014-3-31 16:05:00

mark。。。

bai2011 发表于 2014-4-1 08:36:35

收藏以后用

oxyying 发表于 2014-4-7 16:40:32

很好,正是我要找的资料!

clarkewayne 发表于 2014-4-7 21:44:42

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

waothom 发表于 2014-4-8 13:51:34

根据需要做权衡

go2deathward 发表于 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> MaxVal)
            {
                MaxVal = Pointer;
            }
            if ( Pointer<MinVal )
            {
                MinVal = Pointer;
            }
            temp32 += Pointer;
      }
      temp32 = (temp32-MaxVal-MinVal)/(Length-2);
    }
    else
    {
      for ( i=0;i<Length;i++ )
      {
            temp32 += Pointer;
      }
      temp32 = temp32/Length;
    }

    return (u16)temp32;
}

ZHW0117 发表于 2014-4-8 17:26:12

收藏收藏!

lf8013 发表于 2014-4-9 18:06:29

好的,学习了,谢谢楼主,收藏了

673835452 发表于 2014-4-10 10:20:15

mark mark mark mark

jz701209李 发表于 2014-4-10 11:06:09

学习学习,谢谢

pentagon 发表于 2014-4-10 11:51:02

{:lol:}{:lol:}标记

zpc2013 发表于 2014-4-12 12:52:48

继续这方面的资料,谢谢

wuguoyan 发表于 2014-4-12 13:10:55

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

+1我也是这样用的。

ZYBing 发表于 2014-4-12 13:17:23

学习,mark

随影 发表于 2014-5-5 13:34:59

不错,学习了

胡文剑 发表于 2014-5-8 10:17:45

好东西 学习了

glacier1 发表于 2014-5-8 10:39:49

mark学习一下

a752109494 发表于 2014-5-10 13:16:49

收藏了。

xiaohuixh 发表于 2014-5-10 14:57:06

收藏学习。

tangjiaqq 发表于 2014-5-11 09:49:53

这么好的东西留着

peter_zj 发表于 2014-5-12 00:27:34

非常感谢!!!

zh313212 发表于 2014-6-27 14:48:02

mark++++++++++++++

211LIRUISHUO 发表于 2014-7-12 16:23:20


mark,好东西呀~

耗子董 发表于 2014-7-12 21:52:48

学习了,不过挺基本的

木桥 发表于 2014-7-13 02:23:06

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

没怎么看懂啊!

木桥 发表于 2014-7-13 02:23:50

大家知道一阶滞后滤波常用在什么地方吗?

huangxuankui 发表于 2014-8-13 13:48:36

挺详细的,学习了。

ranyanhao 发表于 2014-8-20 01:41:42

markhaodongxi

gy54321 发表于 2014-8-20 01:47:28

好东西, 收常了

wshg 发表于 2014-8-24 19:32:36

挺好东西

zqf441775525 发表于 2014-8-25 11:13:27

mark,字数补丁!

yuzhongbing121 发表于 2014-10-31 15:55:50

收藏,谢谢分享

fm0826 发表于 2014-10-31 16:05:26

收藏,谢谢分享

zjk 发表于 2014-10-31 16:06:27

mark,标记。。。

hzpj001 发表于 2014-11-1 10:25:12

收藏,学习

second_chan 发表于 2014-11-1 10:30:24

谢谢分享。。。学学习

chiefdh 发表于 2014-11-1 13:25:31

wxws 发表于 2012-4-23 17:38
抄来的

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


Mark for after days to read
页: [1] 2
查看完整版本: 10种简单的数字滤波算法(C语言源程序)