原帖刊载于ourdev:
XXXXXXXXXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXml原帖代码搞错,在这里重新发一遍。
这里提供用于AVR和STM32的IIR滤波器代码下载,保证可用,不需要额外修改。
放假实在无聊,即将到来的高三非常恐怖,先偷闲一把。matlab的fdatool是好东西,不过很多人不知道该怎么使用它生成的C头文件。
该程序已经用于心电采集实验
不多说,切入正题
这里有个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
保存好的文件如下:
第三步:
打开iir_coefs.h把MWSPT_NSEC替换成IIR_NSEC,
NL、DL数组删除掉,real32_T改成float ,
其中有一个#include "twmtypes.h",不要它了,删掉
改完的文件如下:
#define IIR_NSEC 9
//原来叫做MWSPT_NSEC
保存文件,然后使用以下代码进行滤波
这段代码是根据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.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();
ourdev_600574LYM1IF.rar
2.27KB
RAR
49次下载
200字以内,仅用于支线交流,主线讨论请采用回复功能。