STM32F4 DSP库学习笔记9-DSP库函数中IIR滤波器的实现和效果
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
STM32F4 DSP库学习笔记9-DSP库函数中IIR滤波器的
实现和效果
我们来实际操作STM32F4 DSP库的IIR滤波器。
与IIR滤波器函数有关的源文件如下图所示:
STM32F4 DSP库中采用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里的计算就是按照上面的式子计算的,但是STM32F4 DSP库里的系数a1,a2是取反的。
下面就介绍如何使用MATLAB设计IIR滤波器。
举个例子,我们要设计一个采样率为1kHz,4阶,截止频率100Hz的巴特沃斯滤波器。
首先和设计FIR滤波器一样,首先在MATLAB命令窗口输入fdatool,调出滤波器设计窗口
按照方框所示设置好参数:
点击Design Filter:
注意红框里面是直接II型,我们要把他改为直接I型。
点击Edit->Convert Structure,选择I型:
转化好后,点击File-Export,
第一项选择Coefficient File(ASCII):第一项选择好以后,第二项选择Decimal:
点击Export,保存后生成如下文件:
系数对应如下:
1 2 1 1 -1.3209134308194264 0.63273879288527657
b0 b1 b2 a0 a1 a2
1 2 1 1 -1.0485995763626117 0.29614035756166951
b0 b1 b2 a0 a1 a2
实际使用ARM官方的IIR函数调用的时候要将a1和a2取反。
把a0去掉Scale Values表示每个biquad的增益系数。
所以最后用STM32计算后,要乘以这两个系数。
设计滤波器系数之后,我们来看STM32的IIR滤波器函数:
主要介绍下arm_biquad_cascade_df1_f32
函数定义如下:
void arm_biquad_cascade_df1_f32(
const arm_biquad_casd_df1_inst_f32 * S,
float32_t * pSrc,
float32_t * pDst,
uint32_t blockSize)
参数:
*S points to an instance of the floating-point Biquad cascade struct ure.
*pSrc points to the block of input data.
*pDst points to the block of output data.
blockSize number of samples to process per call.
介绍下结构体arm_biquad_casd_df1_inst_f32
typedef struct
{
//< number of 2nd order stages in the filter. Overall order is 2*numStages .
uint32_t numStages;
//< Points to the array of state coefficients. The array is of length 4*numS tages. float32_t *pState;
//< Points to the array of coefficients. The array is of length 5*numStage s.
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 *)&IIRCoeff s32LP[0], (float32_t *)&IIRStateF32[0]);
arm_biquad_cascade_df1_f32(&S, testInput_f32, testOutput, TEST_LEN GTH_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滤波器的计算结果还是令人满意的。