如何使用matlab iir滤波器设计器

IIR滤波器的MATLAB实现(直接型)
在MATLAB中,用filter函数直接实现IIR的直接形式。
例5.1 用直接型实现系统函数为的IIR数字滤波器,求单位脉冲响应和单位阶跃信号的输出。
&图1 直接型单位脉冲响应和输出信号
解:程序清单如下:
余成波-IIR-滤波器
% p157 例5.1
% filename:& ycb_p157_5_1
%-----------------------------------
b=[1,-3,11,27,18];a=[16,12,2,-4,-1];
h=impz(b,a,N);& %直接型单位脉冲响应
x=[ones(1,5),zeros(1,N-5)]; %单位阶跃信号
y=filter(b,a,x);&&&
%直接型输出信号
subplot(1,2,1);stem(h);title('直接型h(n)');
subplot(1,2,2);stem(y);title('直接型y(n)');
参考资料:余成波等,数字信号处理及MATLAB实现(第二版)[M].北京:清华大学出版社,2008.1
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。FIR滤波器和IIR滤波器的区别和选择_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
FIR滤波器和IIR滤波器的区别和选择
阅读已结束,下载文档到电脑
想免费下载更多文档?
定制HR最喜欢的简历
你可能喜欢只需一步,快速开始
扫一扫,访问微社区
后使用快捷导航没有帐号?
手把手教你用matlab生成STM32官方IIR滤波器的系数(三)
查看: 7601|
评论: 0|原作者: mcukey|来自:
摘要: 本节主要介绍如何在STM32上实现一个IIR高通滤波器。在介绍如何实现STM32的IIR滤波程序之前,再看一下用matlab仿真得到的结果,以下是输入300Hz时的输入和输出(下)。将输入频率改为100Hz,再看仿真结果:可以观察到 ...
本节主要介绍如何在STM32上实现一个IIR高通滤波器。在介绍如何实现STM32的IIR滤波程序之前,再看一下用matlab仿真得到的结果,以下是输入300Hz时的输入和输出(下)。将输入频率改为100Hz,再看仿真结果:可以观察到输入300Hz的时候,输出幅值大约为1800,而输入降到100Hz时,输出信号的幅值只有240。IIR的实现主要处理过程如下,STM32通过ADC采集一路正弦波信号,采集完成后立即对数据进行处理,然后将处理之后的数据送到DAC数据寄存器,通过DAC1的引脚将处理后的数据用电平方式体现出来,这样就可以对比输入和滤波之后输出的效果。在了解了IIR滤波器的二阶直接II型结构以后,接下来我们就可以在STM32的DSP库函数中修改IIR的系数了。首先看一下库文件中基于C的IIR函数,如下所示。void&iir_biquad_stm32(u16&*y,&u16&*x,&int16_t&*IIRCoeff,&u16&ny){&&u32&i;&&u32&w1_2&=&0,&w1_1&=&0,&w1;&&for&(i=0;&i&ny-2;&i++)&&{&&&&w1&=&x[2+i]&-&IIRCoeff[0]*w1_1&-&IIRCoeff[1]*w1_2;&&&&y[2+i]&=&(IIRCoeff[2]*w1&+&IIRCoeff[3]*w1_1&+&IIRCoeff[4]*w1_2);&&&&w1_2&=&w1_1;&&&&w1_1&=&w1;&&}}其中y参数表示输出数组指针,x参数表示输入数组指针,IIRCoeff表示IIR滤波器系数数组指针。由于官方给出的函数需要使用到数组,在程序中需要用到缓冲区,这里我们先从简单的着手,即STM32通过ADC采集一次数据之后马上对数据进行IIR滤波处理,所以不必用到缓冲区。在处理完一次数据之后,将输出数据y通过DAC1输出到引脚上,便于示波器观察。这里我们只用了一级二阶滤波,因此将后段的程序注释掉了。另外,由于我们采用浮点数来处理,而官方程序给的是定点处理,再看matlab生成的IIR滤波器内部结构图,该结构对参数进行了归一化处理,不能直接用于IIRCoeff数组,因此还需要对程序进行修改,修改后的程序如下。void&iir_biquad_stm32(float&*y,&float&*x,&float&*IIRCoeff,&u16&ny){&&static&float&w1_2&=&0,&w1_1&=&0,&w1;&&/**&Canonic&form&**/&&/*&1st&section&*/&&&&w1&=&IIRCoeff[0]*x[0]&-&IIRCoeff[1]*w1_1&-&IIRCoeff[2]*w1_2;&&&&y[0]&=&(w1&+&IIRCoeff[3]*w1_1&+&w1_2)*IIRCoeff[4];&&&&w1_2&=&w1_1;&&&&w1_1&=&w1;}通过对比程序和滤波器内部结构图,可以将各个参数对应上,如下图所示。其中w1,w1_1,w1_2表示输入x的过去状态,因此在程序中要使用static将其定义为静态变量,防止下一次调用该函数时将x[N-n]清零。将每个变量的位置搞清楚之后,就可以给IIRCoeff数组赋值了,比如该高通滤波器的系数赋值为float&IIRCoeff[5]&=&{0.698677,-1.01,-2,19.225};由于STM32的ADC只能输入正电压,因此硬件上必须加一个运放将正弦波信号加上一个直流分量,让ADC的输入限制在0~3.3V。现在就可以使用STM32来做一个300Hz的高通滤波器了。首先将STM32的ADC配置为TIM1触发,采集通道为ADC1,每隔8KHz采集一次(必须为8KHz,因为前面在使用matlab设计滤波器时填入的采样率为8KHz,你也可以改为其他采样率,但两者必须保持一致),ADC采集完成中断使能,在ADC中断程序中调用IIR滤波器函数,这里滤波器的输入为x,也即ADC的采样值,输出为y,由于是高通滤波,因此采集到的带直流分量的正弦波信号在通过滤波器后会将直流分量削掉,输出y的范围在-,在将y赋值到DAC数据寄存器之前还要加上一个2048。ADC中断参考程序如下:u16&//ADC临时值void&ADC1_2_IRQHandler(void){&&/*&Clear&ADC1&EOC&pending&interrupt&bit&*/ if(ADC_GetITStatus(ADC1,&ADC_IT_EOC)!=RESET) {
ADC_ClearITPendingBit(ADC1,&ADC_IT_EOC); }& adctmp&=&(ADC_GetConversionValue(ADC1));
x[0]&=&((float)adctmp);
//采集到的整数变成浮点数 iir_biquad_stm32(y,&x,&IIRCoeff,&3);
//调用IIR滤波程序 DAC_SetChannel1Data(DAC_Align_12b_R,((int16_t)y[0])+2048); //DAC1输出滤波后的波形 DAC_SetChannel2Data(DAC_Align_12b_R,adctmp);
//DAC2输出采集到的波形,与DAC1对比}将信号发生器连接到运放的输入,幅值调到合适的位置,频率输入50Hz、100Hz、200Hz、300Hz、500Hz、800Hz,观察DAC1&和DAC2的输出,如下图所示。f&=&50Hzf&=&100Hz&f&=&200Hzf&=&300Hzf&=&500Hz&f&=&800Hz可以直观的看到随着频率从50Hz到800Hz,输出信号的幅度大于300Hz以后基本保持不变,而小于300Hz的信号随频率减小而减小。由于采样率较低,只有8KHz,可以看到输入频率为800Hz时输入量化误差较大,波形出现了变形,解决这一问题的办法就是提高采样率。以上是做的一个一级二阶IIR高通滤波,当然还可以设计4阶、6阶等以上的滤波器,需要注意的是滤波器的处理时间必须在两次采样间隔内完成,否则将出现第一次采集到的数还没处理完毕,第二次采集就已经开始了,这将导致最终的计算错误。
上一篇:下一篇:
Copyright &
Inc. All Rights Reserved.
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,会员在论坛发表的言论仅代表个人观点,不代表论坛立场!
本站所有文章,发表者拥有版权,发表者拥有展示权,未经本站明确许可,任何网站不得非法盗链、转载及抄袭本站资源;转载请注明出处!
本站部分内容及所有资料来自网络,版权归原作者所有,如涉及侵权请联系我们删除;资料仅供学习和科研之用,请在下载后24小时内删除!
本站管理: Email:
本站郑重声明:本论坛不讨论涉及政治敏感话题,一经发现马上删除该贴及封ID
Powered bySTM32实现IIR低通滤波器
我的图书馆
STM32实现IIR低通滤波器
matlab的fdatool是好东西,不过很多人不知道该怎么使用它生成的C头文件。 趁着放假有时间,摸索了几天,终于搞定。希望阿莫给条裤子。 该程序已经用于心电采集实验 导联aVF,带宽1-25Hz
实验过程中图片&(原文件名:DSCF6003.JPG)&
液晶截图&(原文件名:aVF_LCD.jpg)&不多说,切入正题 这里有个fdatool设计的IIR高通滤波器,采样率400Hz时截止频率1Hz。 设计定型之后,要做些调整。 以下说明中的英文名词有些可能对不上fdatool界面上的原文,请大家意会吧 第一步: 点击菜单中的Edit-&Convert&Structure&选择Direct&Form&I&,SOS,(必须是Direct&Form&I,&&II不行) 一般情况下,按照默认设置,fdatool设计都是由二阶部分串联组成的。 这种结构的滤波器稳定性比一个section的要好很多,其他方面的性能也好些。 如果不是的话,点击Convert&to&second&order&sections。 这时,滤波器的结构(structure)应该显示为&Direct&Form&I,second&order&sections 第二步: 选择quantize&filter,精度选择single&precision&floating&point&(单精度浮点) 之所以不用定点是因为噪声太大,也不容易稳定。 点击菜单中的Targets&-&&generate&c&header&,选择export&as:single&precision&floating&point&(单精度浮点) 填写变量名称时,把NUM改成IIR_B,DEN改成IIR_A,其他不用动,保存为iir_coefs.h 保存好的文件如下: //一大堆注释 //然后: /*&General&type&conversion&for&MATLAB&generated&C-code&&*/ #include&"tmwtypes.h" /*& &*&Expected&path&to&tmwtypes.h& &*&C:\Program&Files\MATLAB\R2010a\extern\include\tmwtypes.h& &*/ /* &*&Warning&-&Filter&coefficients&were&truncated&to&fit&specified&data&type.&& &*&&&The&resulting&response&may&not&match&generated&theoretical&response. &*&&&Use&the&Filter&Design&&&Analysis&Tool&to&design&accurate &*&&&single-precision&filter&coefficients. &*/ #define&MWSPT_NSEC&9 const&int&NL[MWSPT_NSEC]&=&{&1,3,1,3,1,3,1,3,1&}; const&real32_T&IIR_B[MWSPT_NSEC][3]&=&{ &{ &&&&&0.,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0& &&}, &&{ &&&&&&&&&&&&&&&&1,&&&&&&&&&&&&&-2,&&&&&&&&&&&&&&1& &&}, &&{ &&&&&0.,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0& &&}, &&{ &&&&&&&&&&&&&&&&1,&&&-1.,&&&&&&&&&&&&&&1& &&}, &&{ &&&&&0.,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0& &&}, &&{ &&&&&&&&&&&&&&&&1,&&&&-1.,&&&&&&&&&&&&&&1& &&}, &{ &&&&&0.,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0& &&}, &&{ &&&&&&&&&&&&&&&1,&&&&-1.,&&&&&&&&&&&&&&1& &&}, &&{ &&&&&&&&&&&&&&&&1,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0& &&} }; const&int&DL[MWSPT_NSEC]&=&{&1,3,1,3,1,3,1,3,1&}; const&real32_T&IIR_A[MWSPT_NSEC][3]&=&{ &&{ &&&&&&&&&&&&&&&&1,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0& &&}, &&{ &&&&&&&&&&&&&&&&1,&&&-1.,&&&0.& &&}, &&{ &&&&&&&&&&&&&&&&1,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0& &&}, &&{ &&&&&&&&&&&&&&&&1,&&&-1.,&&&0.& &&}, &{ &&&&&&&&&&&&&&&&1,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0& &&}, &&{ &&&&&&&&&&&&&&&&1,&&&-1.,&&&0.& &&}, &&{ &&&&&&&&&&&&&&&&1,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0& &&}, &&{ &&&&&&&&&&&&&&&&1,&&&-1.,&&&0.& &&}, &&{ &&&&&&&&&&&&&&&&1,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0& &&} }; 第三步: 打开iir_coefs.h把MWSPT_NSEC替换成IIR_NSEC,& &NL、DL数组删除掉,real32_T改成float&, 其中有一个#include&"twmtypes.h",不要它了,删掉 改完的文件如下: #define&IIR_NSEC&9 &&//原来叫做MWSPT_NSEC const&float&IIR_B[IIR_NSEC][3]&=&{ &&//为什么改为float很明显了吧 &&{ &&&&0.,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0 &&}, &&{ &&&&&&&&&&&&&&&&1,&&&&&&&&&&&&-2,&&&&&&&&&&&&&&1 &&}, &&{ &&&&0.,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0 &&}, &&{ &&&&&&&&&&&&&&&&1,&&-1.,&&&&&&&&&&&&&&1 &&}, &{ &&&&0.,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0 &&}, &&{ &&&&&&&&&&&&&&&&1,&&&&-1.,&&&&&&&&&&&&&&1 &&}, &&{ &&&0.,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0 &&}, &&{ &&&&&&&&&&&&&&&&1,&&&&-1.,&&&&&&&&&&&&&&1 &&}, &&{ &&&&&&&&&&&&&&&&1,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0 &&} }; const&float&IIR_A[IIR_NSEC][3]&=&{ &&{ &&&&&&&&&&&&&&&&1,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0 &&}, &&{ &&&&&&&&&&&&&&&&1,&&-1.,&&0. &&}, &&{ &&&&&&&&&&&&&&&&1,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0 &&}, &&{ &&&&&&&&&&&&&&&&1,&&-1.,&&0. &&}, &&{ &&&&&&&&&&&&&&&&1,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0 &&}, &&{ &&&&&&&&&&&&&&&&1,&&-1.,&&0. &&}, &&{ &&&&&&&&&&&&&&&&1,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0 &&}, &&{ &&&&&&&&&&&&&&&&1,&&-1.,&&0. &&}, &&{ &&&&&&&&&&&&&&&&1,&&&&&&&&&&&&&&0,&&&&&&&&&&&&&&0 &&} }; 保存文件,然后使用以下代码进行滤波 这段代码是根据Direct&Form&I&2阶IIR滤波的差分方程编写的 a0*y[n]&=&b0*x[n]&+&b1*x[n-1]&+&b2*x[n-2]&-&a1*y[n-1]&-a2*y[n-2]; //iir_filter.c #include&"datatype.h" #include&"iir_filter.h" #include&"iir_coefs.h" static&float&y[IIR_NSEC][3]; static&float&x[IIR_NSEC+1][3]; int16&iir_filter(int16&in) { &&&&&&uint16&i; &&&&&&x[0][0]&=& &&&&&&for(i=0;i&IIR_NSEC;i++) &&&&&&{ &&&&&&&&&&y[0]&=x[0]*IIR_B[0]+x[1]*IIR_B[1]+x[2]*IIR_B[2]-y[1]*IIR_A[1]-y[2]*IIR_A[2]; &&&&&&&&&&y[0]&/=&IIR_A[0]; &&&&&&& &&&&&&&&&&y[2]=y[1];y[1]=y[0]; &&&&&&&&&&x[2]=x[1];x[1]=x[0]; &&&&&& &&&&&&&&&&x[i+1][0]&=&y[0]; &&&&&&} &&&&&&if(&x[IIR_NSEC][0]&32767)&&x[IIR_NSEC][0]=32767; &&&&&&if(&x[IIR_NSEC][0]&-32768)&x[IIR_NSEC][0]=-32768; &&&&&&return&&((int16)x[IIR_NSEC][0]);&&& &&& } //复位滤波器 void&iir_reset(void) { &&&&uint16&i,j; &&&&for(i=0;i&IIR_NSEC+1;i++) &&&&{ &&&&&&for(j=0;j&3;j++) &&&&&&{ &&&&&&&&&&x[j]=0; &&&&&&} &&&&} && &&&&for(i=0;i&IIR_NSEC;i++) &&&&{ &&&&&&for(j=0;j&3;j++) &&&&&&{ &&&&&&&&&&y[j]=0; &&&&&&} &&&&} } //iir_filter.h #ifndef&_IIR_FILTER_H__ #define&_IIR_FILTER_H__ int16&iir_filter(int16&x); void&iir_reset(void); #endif 使用方法: 首先写好iir_coefs.h,然后调用iir_filter.c对数据流进行滤波 一个伪代码例子: while(运行中) { 保存到SD卡(iir_filter(读取ADC采样值())); } 这个函数比STM32&DSP库中的函数要好很多,DSP库中的2个IIR滤波函数都不能连续处理数据流。 记得在开始滤波之前重置滤波器 iir_reset();
TA的最新馆藏[转]&[转]&
喜欢该文的人也喜欢【图文】IIR滤波器的DSP实现_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
IIR滤波器的DSP实现
大小:634.50KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢

我要回帖

更多关于 matlab iir滤波器设计 的文章

 

随机推荐