【炒冷饭】STM32实现IIR滤波器,可用matlab生成的头文件
warmonkey2013/08/21软件综合 IP:广东
原帖刊载于ourdev:XXXXXXXXXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXml

原帖代码搞错,在这里重新发一遍。
这里提供用于AVR和STM32的IIR滤波器代码下载,保证可用,不需要额外修改。

放假实在无聊,即将到来的高三非常恐怖,先偷闲一把。

matlab的fdatool是好东西,不过很多人不知道该怎么使用它生成的C头文件。

该程序已经用于心电采集实验
all.jpg
   Filter.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

保存好的文件如下:


第三步:
打开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();


attachment icon ourdev_600574LYM1IF.rar 2.27KB RAR 49次下载
+500  科创币    科创网    2013/08/21 楼主辛苦了
来自:计算机科学 / 软件综合
8
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
张静茹
11年6个月前 IP:未同步
562480
看见stm32我就来了,不过软件滤波我用不上.....
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
量子隧道
11年6个月前 IP:未同步
562517
楼主高二时玩matlab;我高二时玩basic。。。[s:274]
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
warmonkey作者
11年6个月前 IP:未同步
562718
回 1楼(张静茹) 的帖子
来个最简单的IIR滤波器
float first_order_iir_lowpass(float x)
{
static const float k = 0.1;
static float last_y = 0;
y = x * k + last_y * (1.0 - k);
//90%的上次输出,混合10%的输入值,得到新的输出
//如果用在仪表盘上,会使得仪表指针看起来像有惯性
last_y = y;
return y;
}
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
daxus
11年6个月前 IP:未同步
562755
回 3楼(warmonkey) 的帖子
我记得这好像叫 “一阶滞后滤波”

特意查了一下:
XXXXXXXXXXXXXXXXXXXt/wangjunfeng0000/article/details/4463249
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
量子隧道
11年6个月前 IP:未同步
562831
回 4楼(daxus) 的帖子
这确实是种IIR滤波器。IIR数字滤波器的特征就是有回馈(feedback)。
模拟的IIR滤波器,比如RC一阶滤波器,也有无限冲激响应,也算IIR滤波器。
+10
科创币
daxus
2013-08-23
明白了,多谢! 悲剧的是俺大学学的的信号与系统都还老师了。。。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
daxus
11年5个月前 IP:未同步
563092
明白了,多谢!
悲剧的是俺大学学的的信号与系统都还老师了。。。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
海狼
11年5个月前 IP:未同步
563259
[s:219] 对楼主的心电采集更感兴趣
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
warmonkey
学者 机友
文章
363
回复
8003
学术分
12
2008/10/11注册,11时58分前活动

Cubesat

主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:未同步
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}