常用7种软件滤波文档格式.docx
《常用7种软件滤波文档格式.docx》由会员分享,可在线阅读,更多相关《常用7种软件滤波文档格式.docx(11页珍藏版)》请在冰豆网上搜索。
付表
2.
中值滤波法即对某一参数连续采样N次(一般N为奇数),然后把N次采样值按从小到大排队,再取中间值作为本次采样值。
设DATA为存放采样值的内存单元首地址,SAMP为存放滤波值的内存单元地址,N为采样值个数,用MCS-51指令编写的中值滤波子程序如下:
副表
3.算术平均值滤波算法
算术平均滤波法就是连续取N次采样值进行算术平均,其数学表达式是:
Y=∑yi
~y=1/N∑yi
i=1……N
~y——N个采样值的算术平均值;
Yi——第i个采样值;
设8次采样值依次存放在地址DATA开始的连续单元中,滤波结果保留在累加器A中,程序如下:
4.加权平均滤波法
算术平均滤波法存在前面所说的平滑和灵敏度之间的矛盾。
采样次数太少,平滑效果差,次数太多,灵敏度下降,对参数的变化趋势不敏感。
协调两者关系,可采用加权平均滤波,对连续N次采样值,分别乘上不同的加权系数之后再求累加和,加权系数一般先小后大,以突出后面若干采样的效果,加强系统对参数的变化趋势的辩识,各个加权系数均为小于1的小数,且满足总和等于1的约束条件,这样,加权运算之后的累加和即为有效采样值。
为方便计算,可取各个加权系数均为整数,且总和为256,加权运算后的累加和除以256(即舍去低字节)后便是有效采样值。
设每批采样8个数据,依次存放在地址DATA开始的单元中,各加权系数是用一个表格存放在ROM中,MCS-51指令编写的算术平均滤波程序如下:
5.滑动平均滤波法:
以上介绍的各种平均滤波算法有一个共同点,即每取得一个有效采样值必须连续进行若干次采样,当采样速度较慢(如双积分型A/D转换)或目标参数变化较快时,系统的实时性不能保证,滑动平均滤波算法只采样一次,将这一次采样值和过去的若干次采样值一起求平均,得到的有效采样值即可投入使用,如果取N个采样值求平均,RAM中必须开辟N个数据的暂存区。
每新采样一个数据便存入暂存区,同时去掉一个最老的数据,保持这N个数据始终是最近的数据,这种数据存放方式可以用环行队列结构方便的实现。
设环行队列为40H-4FH连续16个单元,RO作为队尾指针,滤波程序如下:
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(小数)中。
滤波程序如下:
结束语:
微型计算机在仪器仪表系统中的成功应用,使传统的电子仪器以及复杂的跟踪测量装置发生了许多革命性变化。
其中一个突出表现就是一个系统中包含了智能性运作。
微机具有很强的分析和运算能力,智能系统可完成复杂的数据处理,智能系统采用软件硬件想结合的方法进行随机误差的数字滤波和系统误差的修正,可以实现实时修正,较准测量数据,这些都是传统仪器难以比拟的。
#include<
stdio.h>
absacc.h>
intrins.h>
./Atmel/at89x52.h>
#include"
source.h"
main()
{
filter_1();
filter_2();
filter_3();
filter_4();
filter_5();
filter_6();
filter_7();
filter_8();
filter_9();
filter_10();
}
unsignedcharget_ad(void){
staticunsignedchari;
returni++;
voiddelay(void){
unsignedchari=0;
while
(1){
i++;
if(i>
20)return;
#defineA10//设置两次采样允许的最大偏差值
charvalue;
//上次采用后的有效值变量
charfilter_1(void){
char
new_value;
//本次采样值变量
new_value=get_ad();
//读入本次采样值
if((new_value-value>
A)||(value-new_value>
A))//比较是否超出最大偏差值
return
value;
//如果超出,返回上次的有效值作为本次的有效值
//如果没有超出,返回本次的采样值作为本次的有效值
#defineN11//设置连续采样的次数
charfilter_2(void){
value_buf[N];
//缓存N次采样值的存储变量
count,i,j,temp;
//i,j是冒泡排序的下标变量,count是采样数据读入的下标变量
//temp是临时变量
for(count=0;
count<
N;
count++)//连续读入N个采样值
value_buf[count]=get_ad();
delay();
for(j=0;
j<
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;
returnvalue_buf[(N-1)/2];
//将排序后N个采样值的中间值作为最后结果返回
#undefN
#defineN12//设置每组参与平均运算的采样值个数
charfilter_3(){
int
sum=0;
//求和变量,用于存储采样值的累加值
charcount;
//采样数据读入的下标变量
count++)//连续读入N个采样值,并累加
sum+=get_ad();
return(char)(sum/N);
//讲累加值进行平均计算作为返回值
#defineN12//设置FIFO队列的长度
//FIFO队列变量
i=0;
//队列的下标变量
charfilter_4(){
value_buf[i++]=get_ad();
if(i==N)
count++)
sum+=value_buf[count];
return(char)(sum/N);
#defineN12//设置每组采样值的数量
charfilter_5()
charcount,i,j,temp;
charvalue_buf[N];
//缓冲N个采样值的存储变量
for
(count=0;
value_buf[count]=get_ad();
for(j=0;
N-1;
for(i=0;
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;
sum+=value_buf[count];
//去掉两端的最小和最大采样值,对中间的N-2个采样值求和
return(char)(sum/(N-2));
//返回中间N-2个采样值的平均值
#undefA
charfilter_6()
new_value=value;
sum+=new_value;
//累加采样的有效值
value=new_value;
//将累加值进行平均计算作为返回值
#defineCOE50//定义加权系数
//上一个采样值变量
charfilter_7()
new_value=get_ad();
return(100-COE)*value+COE*new_value;
//返回的本次滤波结果
#defineN12
//设置FIFO队列的长度
charcodecoe[N]={1,2,3,4,5,6,7,8,9,10,11,12};
//加权系数
charcodesum_coe=1+2+3+4+5+6+7+8+9+10+11+12;
charfilter_8()
//采样数据读入的下标变量
//缓存N个采样值的存储变量
for(count=0;
//读入采样值
sum+=value_buf[count]*coe[count];
//累加采样值和系数的乘积
return(char)(sum/sum_coe);
//累加值与系数和相除作为返回结果
#defineN12//设置计数器溢出值
charfilter_9()
charcount=0;
//计数变量
charnew_value;
while(value!
=new_value);
count++;
//计数器加1
if(count>
=N)
returnnew_value;
//如果本次采样值与当前有效值不相等,
//且计数器溢出,返回本次采样值
returnvalue;
//如果本次采样值与当前有效值相等,则返回当前有效值
//有效值变量
charfilter_10()
//如果超出,返回有效值作为本次的采样有效值
THANKS!
!
致力为企业和个人提供合同协议,策划案计划书,学习课件等等
打造全网一站式需求
欢迎您的下载,资料仅供参考