赞
踩
本次我们学习一下AD采集的一些简单的软件滤波算法并分析优缺点
本篇博客大部分是自己收集和整理,如有侵权请联系我删除。
AD采样点的电压多少有点起伏波动,经运放放大后电压的波动如果超过ADC的分辩率,则显示的值会出现波动。波动如果十分大的话, 建议在硬件上滤波,相反,如果波动较小,你可以用软件滤波方法解决这个问题。
- /* A值根据实际调,Value有效值,new_Value当前采样值,程序返回有效的实际值 */
- #define A 10
- char Value;
- char filter()
- {
- char new_Value;
- new_Value = get_ad(); //获取采样值
- if( abs(new_Value - Value) > A) return Value; //abs()取绝对值函数
- return new_Value;
- }
- #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[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];
- }
- #define N 12
- char filter()
- {
- int sum = 0;
- for(count = 0;count<N;count++)
- sum += get_ad();
- return (char)(sum/N);
- }
- /* A值根据实际调,Value有效值,new_Value当前采样值,程序返回有效的实际值 */
- #define A 10
- char Value;
- char filter()
- {
- char new_Value;
- new_Value = get_ad(); //获取采样值
- if( abs(new_Value - Value) > A) return Value; //abs()取绝对值函数
- return new_Value;
- }
- /***************************************************
- 函数名:FILTER_recursive
- 描 述:递推平均滤波:把连续取N个采样值看成一个队列,
- 队列的长度固定为N,每次采样到一个新数据放入队尾,并
- 扔掉原来队首的一次数据,把队列中得N个数据进行算术平
- 均运算,就可以获得新的滤波结果。
- 适用范围:对周期性干扰有良好的抑制作用,平滑度高,
- 适用于高频振荡的系统。缺点是灵敏度低,对偶然出现的
- 脉冲性干扰的抑制作用较差,不易消除由于脉冲干扰所引
- 起的采样值偏差,不适用于脉冲干扰比较严重的场合
- 输入值:无
- 返回值:sum:滤波结果
- 备注:N=2^x次方 为宜
- ***************************************************/
- unsigned short int FILTER_recursive() //递推平均滤波 N为队列长度
- {
- unsigned short int sum=0;
- unsigned char count=0;
- static unsigned char i=0,num=0;
- static unsigned short int value_temp[N];
- do{
- if(i<N) //每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据。(先进先出原则)
- { //把队列中的N个数据进行算术平均运算,就可获得新的滤波结果
- value_temp[i] = AD_VALUE;
- i++;
- i=(i==N)?0:i; //三目运算 i清零
- }
- num++;
- num=num<N?num:N;
- }while(num<N);
- for(count=0;count<N;count++)
- sum += value_temp[count];
-
- sum = sum/N;
- return sum;
- }
- char filter()
- {
- char count,i,j;
- char Value_buf[N];
- int sum=0;
- for(count=0;count<N;count++)
- Value_buf[count]= get_ad();
- 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;
- }
- for(count =1;count<N-1;count++)
- sum += Value_buf[count];
- return (char)(sum/(N-2));
- }
- /*****************************************************
- 函数名:FILTER_median
- 描 述:中位值滤波:连续采样N次(N取奇数),
- 把N次采样值按大小排列,取中间值为本次有效值。
- 适用范围能有效克服因偶然因素引起的波动干扰,
- 对温度、液位的变化缓慢的被测参数有良好的滤波效果。
- 不过对流量、速度等快速变化的参数不宜。
-
- 中位值平均滤波:连续采用N个数据,去掉一个最大值
- 和一个最小值,然后计算N-2个数据的算术平均值。
- 适用范围:对应偶然出现的脉冲性干扰,可消除由于脉冲
- 干扰所引起的采样值偏差。但是测量速度较慢, 比较浪费RAM。
-
- 输入值:Flag:选择中位值滤波或中位值平均滤波
- ON:中位值平均滤波 OFF:中位值滤波
- 返回值:滤波结果
- 备注:中位值滤波:N取奇数,N=2^x次方+1 为宜
- 中位值平均滤波:N=2^x次方+2 为宜
- ******************************************************/
- unsigned short int FILTER_median(TYPE_STATE Flag) //中位值滤波 中位值平均滤波 N为采样次数,取奇数 Flag:中位值平均滤波使能
- {
- unsigned short int value_buf[N],temp=0;
- #if(Flag)
- unsigned short int sum=0;
- #endif
- unsigned char count,i,j;
-
- for (count=0;count<N;count++)
- {
- value_buf[count] = AD_VALUE;
- Delay(300); //等待AD转换
- }
-
- for(j=0;j<N-1;j++) //排序
- {
- for(i=0;i<N-j-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;
- }
- }
- }
- #if(Flag)
- for(count=1;count<N-1;count++) //中位求平均 由Flag标志控制
- sum+=value_buf[count];
- return (uint16_t)(sum/(N-2));
- #endif
- return value_buf[(N-1)/2]; //中位值
- }
- #define A 10
- #define N 12
- char value,i=0;
- char value_buf[N];
- char filter()
- {
- char new_value,sum=0;
- new_value=get_ad();
- if(Abs(new_value-value)<A)
- value_buf[i++]=new_value;
- if(i==N)i=0;
- for(count =0 ;count<N;count++)
- sum+=value_buf[count];
- return (char)(sum/N);
- }
- /*为加快程序处理速度,取a=0~100*/
- #define a 30
- char value;
- char filter()
- {
- char new_value;
- new_value=get_ad();
- return ((100-a)*value + a*new_value);
- }
- /*****************************************************************
- 函数名:FILTER_firstorder
- 描 述:一阶滞后滤波:取a=(0,1)
- 本次滤波结果result=(1-a)*本次采样值+a*上次值
- 对周期性干扰具有良好的抑制作用,
- 适用于波动频率较高得场合。缺点就是相位滞后,灵敏度低,
- 滞后程度取决于a的大小,不能消除滤波频率高于采样频率1/21/2的干扰信号
- 输入值:无
- 返回值:value:滤波结果
- 备注:A取值0——100 A值越小,滤波结果越平稳,但是灵敏度越低
- A值越大,灵敏度越高,但是滤波结果越不稳定
- *****************************************************************/
- unsigned short int FILTER_firstorder() //一阶滞后滤波,A取值0——100
- {
- static unsigned short int value=0;
- unsigned short int new_value;
- value = (value==0)?AD_VALUE:value; // 三目运算,避免第一次采样value值为0
- new_value = AD_VALUE;
-
- value = (100-A)*value/100 + A*new_value/100;
- return value;
- }
- /* 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();
- }
- for(count=0;count<N;count++)
- sum+=value_buf[count]*coe[count];
- return (char)(sum/sum_coe);
- }
- #define N 12
- char filter()
- {
- char count=0,new_value;
- new_value=get_ad();
- while(value!=new_value)
- {
- count++;
- if(count>=N) return new_value;
- new_value=get_ad();
- }
- return value;
- }
- #define A 10
- #define N 12
- char value;
- char filter()
- {
- char new_value,count=0;
- new_value=get_ad();
- while(value!=new_value)
- {
- if(Abs(value-new_value)<A)
- {
- count++;
- if(count>=N) return new_value;
- new_value=get_ad();
- }
- return value;
- }
- }
版权声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。
点赞收藏关注博主,不定期分享单片机知识,互相学习交流。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。