找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5232|回复: 0
打印 上一主题 下一主题
收起左侧

STM32F4-DSP库学习-DSP库函数中IIR滤波器的实现和效果

[复制链接]
跳转到指定楼层
楼主
ID:228907 发表于 2017-8-23 09:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我们来实际操作STM32F4DSP库的IIR滤波器。
IIR滤波器函数有关的源文件如下图所示:
STM32F4DSP库中采用biquad作为一个单元。一个biquad2阶,nbiquad串联之后就是n阶滤波器。
基本的单元结构如下所示:
我们可以求出一个biquad的差分函数形式是:
y[n]=b0*x[n]+b1*x[n-1]+b2*x[n-2]-a1*y[n-1]-a2*y[n-2]
Matlab里的计算就是按照上面的式子计算的,但是STM32F4DSP库里的系数a1a2是取反的。
下面就介绍如何使用MATLAB设计IIR滤波器。
举个例子,我们要设计一个采样率为1kHz4阶,截止频率100Hz的巴特沃斯滤波器。
首先和设计FIR滤波器一样,首先在MATLAB命令窗口输入fdatool,调出滤波器设计窗口
按照方框所示设置好参数:
点击DesignFilter
注意红框里面是直接II型,我们要把他改为直接I型。
点击Edit->ConvertStructure,选择I型:
转化好后,点击File-Export
第一项选择CoefficientFileASCII):
第一项选择好以后,第二项选择Decimal
点击Export,保存后生成如下文件:
系数对应如下:
1211-1.32091343081942640.63273879288527657
b0b1b2a0a1a2
1211-1.04859957636261170.29614035756166951
b0b1b2a0a1a2
实际使用ARM官方的IIR函数调用的时候要将a1a2取反。把a0去掉
ScaleValues表示每个biquad的增益系数。所以最后用STM32计算后,要乘以这两个系数。
设计滤波器系数之后,我们来看STM32IIR滤波器函数:
主要介绍下arm_biquad_cascade_df1_f32
函数定义如下:
voidarm_biquad_cascade_df1_f32(
constarm_biquad_casd_df1_inst_f32*S,
float32_t*pSrc,
float32_t*pDst,
uint32_tblockSize)
参数:
*Spointstoaninstanceofthefloating-pointBiquadcascadestructure.
*pSrcpointstotheblockofinputdata.
*pDstpointstotheblockofoutputdata.
blockSizenumberofsamplestoprocesspercall.
介绍下结构体arm_biquad_casd_df1_inst_f32
typedefstruct
{
//<numberof2ndorderstagesinthefilter.Overallorderis2*numStages.
uint32_tnumStages;
//<Pointstothearrayofstatecoefficients.Thearrayisoflength4*numStages.float32_t*pState;
//<Pointstothearrayofcoefficients.Thearrayisoflength5*numStages.
float32_t*pCoeffs;
}arm_biquad_casd_df1_inst_f32;
注意下:pState指向的数组长度是4numStages长度
pCoeffs指向的数组长度是5numStages长度,a0默认为1,不需要放入
numStages表示biquad个数;
好,接下来我们就可以使用这个函数了
  1. #define numStages 2
  2. #define TEST_LENGTH_SAMPLES 1024
  3. float32_t testInput_f32[TEST_LENGTH_SAMPLES];
  4. float32_t testOutput[TEST_LENGTH_SAMPLES];
  5. float32_t IIRStateF32[4*numStages];
  6. const float32_t IIRCoeffs32LP[5*numStages] =
  7. {
  8. 1.0f,  2.0f,  1.0f,  1.3209134308194264f,  -0.63273879288527657f,        
  9.   1.0f,  2.0f,  1.0f,  1.0485995763626117f,  -0.29614035756166951f
  10. };
  11. void arm_iir_f32_lp(void)
  12. {
  13. uint32_t i;
  14. arm_biquad_casd_df1_inst_f32 S;
  15. float32_t ScaleValue;
  16. for(i=0;i<TEST_LENGTH_SAMPLES;i++)
  17. {
  18. testInput_f32[i]=1.2f*arm_sin_f32(2*PI*50*i/1000)+arm_sin_f32(2*PI*250*i/1000)+1;

  19.    printf("%frn", testInput_f32[i]);
  20. }
  21. arm_biquad_cascade_df1_init_f32(&S, numStages, (float32_t *)&IIRCoeffs32LP[0], (float32_t *)&IIRStateF32[0]);
  22. arm_biquad_cascade_df1_f32(&S, testInput_f32, testOutput, TEST_LENGTH_SAMPLES);
  23. ScaleValue = 0.077956340516462552f * 0.061885195299764481f;
  24. for(i=0; i<TEST_LENGTH_SAMPLES; i++)
  25. {
  26. printf("%frn", testOutput[i]*ScaleValue);
  27. }
  28. }
复制代码

把原始信号和过滤后信号打印出来,导入到matlab,用下面程序处理:
Fs=1000;
N=1024;
n=0:1:N-1;
f=Fs*n/N;
t=0:1/Fs:(N-1)/Fs;
subplot(2,2,1);
plot(t(1:150),data1(1:150));
xlabel('时间/s');
ylabel('幅度/v');
title('原始信号波形图');
h1=fft(data1,N);
subplot(2,2,2);
plot(t(1:150),data2(1:150));
xlabel('时间/s');
ylabel('幅度/v');
title('过滤后信号波形图');
subplot(2,2,3);
plot(f,abs(h1));
xlabel('频率/Hz');
ylabel('幅度');
title('原始信号频谱图');
subplot(2,2,4);
h2=fft(data2,N);
plot(f,abs(h2));
xlabel('频率/Hz');
ylabel('幅度');
title('过滤后信号频谱图');
运行结果:

可以看出STM32IIR滤波器的计算结果还是令人满意的。

全部资料下载地址:
STM32F4-DSP库学习笔记9-DSP库函数中IIR滤波器的实现和效果.doc (389 KB, 下载次数: 60)



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶2 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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