标题: STM32F4-DSP库学习-DSP库函数中IIR滤波器的实现和效果 [打印本页]
作者: dakunhui 时间: 2017-8-23 09:51
标题: STM32F4-DSP库学习-DSP库函数中IIR滤波器的实现和效果
我们来实际操作STM32F4DSP库的IIR滤波器。
与IIR滤波器函数有关的源文件如下图所示:
STM32F4DSP库中采用biquad作为一个单元。一个biquad是2阶,n个biquad串联之后就是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库里的系数a1,a2是取反的。
下面就介绍如何使用MATLAB设计IIR滤波器。
举个例子,我们要设计一个采样率为1kHz,4阶,截止频率100Hz的巴特沃斯滤波器。
首先和设计FIR滤波器一样,首先在MATLAB命令窗口输入fdatool,调出滤波器设计窗口
按照方框所示设置好参数:
点击DesignFilter:
注意红框里面是直接II型,我们要把他改为直接I型。
点击Edit->ConvertStructure,选择I型:
转化好后,点击File-Export,
第一项选择CoefficientFile(ASCII):
第一项选择好以后,第二项选择Decimal:
点击Export,保存后生成如下文件:
系数对应如下:
1211-1.32091343081942640.63273879288527657
b0b1b2a0a1a2
1211-1.04859957636261170.29614035756166951
b0b1b2a0a1a2
实际使用ARM官方的IIR函数调用的时候要将a1和a2取反。把a0去掉
ScaleValues表示每个biquad的增益系数。所以最后用STM32计算后,要乘以这两个系数。
设计滤波器系数之后,我们来看STM32的IIR滤波器函数:
主要介绍下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指向的数组长度是4倍numStages长度
pCoeffs指向的数组长度是5倍numStages长度,a0默认为1,不需要放入
numStages表示biquad个数;
好,接下来我们就可以使用这个函数了
- #define numStages 2
- #define TEST_LENGTH_SAMPLES 1024
- float32_t testInput_f32[TEST_LENGTH_SAMPLES];
- float32_t testOutput[TEST_LENGTH_SAMPLES];
- float32_t IIRStateF32[4*numStages];
- const float32_t IIRCoeffs32LP[5*numStages] =
- {
- 1.0f, 2.0f, 1.0f, 1.3209134308194264f, -0.63273879288527657f,
- 1.0f, 2.0f, 1.0f, 1.0485995763626117f, -0.29614035756166951f
- };
- void arm_iir_f32_lp(void)
- {
- uint32_t i;
- arm_biquad_casd_df1_inst_f32 S;
- float32_t ScaleValue;
- for(i=0;i<TEST_LENGTH_SAMPLES;i++)
- {
- testInput_f32[i]=1.2f*arm_sin_f32(2*PI*50*i/1000)+arm_sin_f32(2*PI*250*i/1000)+1;
-
- printf("%frn", testInput_f32[i]);
- }
- arm_biquad_cascade_df1_init_f32(&S, numStages, (float32_t *)&IIRCoeffs32LP[0], (float32_t *)&IIRStateF32[0]);
- arm_biquad_cascade_df1_f32(&S, testInput_f32, testOutput, TEST_LENGTH_SAMPLES);
- ScaleValue = 0.077956340516462552f * 0.061885195299764481f;
- for(i=0; i<TEST_LENGTH_SAMPLES; i++)
- {
- printf("%frn", testOutput[i]*ScaleValue);
- }
- }
复制代码
把原始信号和过滤后信号打印出来,导入到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('过滤后信号频谱图');
运行结果:
可以看出STM32的IIR滤波器的计算结果还是令人满意的。
全部资料下载地址:
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |