stm32 matlab 滤波器,STM32实现IIR滤波器,可用matlab生成的头文件

回复: 151

e5a73b6a7586c690ae7a720f72a4e733.png

ccfb3c64a5000ccc1971125e1fdae7b2.png

20f7beba86b4a360a2108c8a34a4ebf3.png

STM32实现IIR滤波器,可用matlab生成的头文件

8480dea4bb301f7b540dedff82032028.png

(336208888)

出0入0汤圆

电梯直达

ac34f29e61779188a50d361fdeae2c1f.png

4e3a061a6cee689711774664b8e32641.png

发表于 2010-7-21 22:41:09

|

只看该作者

8d1228179cec554492e4b5a60a447513.gif

|倒序浏览

|阅读模式

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

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

趁着放假有时间,摸索了几天,终于搞定。希望阿莫给条裤子。

该程序已经用于心电采集实验

导联aVF,带宽1-25Hz

thread-4165021-1-1.html

实验过程中图片 (原文件名:DSCF6003.JPG)

thread-4165021-1-1.html

液晶截图 (原文件名:aVF_LCD.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

保存好的文件如下:

//一大堆注释

//然后:

/* General type conversion for MATLAB generated C-code  */

#include "tmwtypes.h"

/*

* Expected path to tmwtypes.h

* C:\Program Files\MATLAB\R2010a\extern\include\tmwtypes.h

*/

/*

* Warning - Filter coefficients were truncated to fit specified data type.

*   The resulting response may not match generated theoretical response.

*   Use the Filter Design & Analysis Tool to design accurate

*   single-precision filter coefficients.

*/

#define MWSPT_NSEC 9

const int NL[MWSPT_NSEC] = { 1,3,1,3,1,3,1,3,1 };

const real32_T IIR_B[MWSPT_NSEC][3] = {

{

0.8641357422,              0,              0

},

{

1,             -2,              1

},

{

0.9949035645,              0,              0

},

{

1,   -1.999938965,              1

},

{

0.9985351563,              0,              0

},

{

1,    -1.99987793,              1

},

{

0.9996337891,              0,              0

},

{

1,    -1.99987793,              1

},

{

1,              0,              0

}

};

const int DL[MWSPT_NSEC] = { 1,3,1,3,1,3,1,3,1 };

const real32_T IIR_A[MWSPT_NSEC][3] = {

{

1,              0,              0

},

{

1,   -1.938049316,   0.9401855469

},

{

1,              0,              0

},

{

1,   -1.989501953,   0.9900512695

},

{

1,              0,              0

},

{

1,   -1.996887207,   0.9971923828

},

{

1,              0,              0

},

{

1,   -1.999084473,   0.9993286133

},

{

1,              0,              0

}

};

第三步:

打开iir_coefs.h把MWSPT_NSEC替换成IIR_NSEC,

NL、DL数组删除掉,real32_T改成float ,

其中有一个#include "twmtypes.h",不要它了,删掉

改完的文件如下:

#define IIR_NSEC 9

//原来叫做MWSPT_NSEC

const float IIR_B[IIR_NSEC][3] = {

//为什么改为float很明显了吧

{

0.8641357422,              0,              0

},

{

1,            -2,              1

},

{

0.9949035645,              0,              0

},

{

1,  -1.999938965,              1

},

{

0.9985351563,              0,              0

},

{

1,    -1.99987793,              1

},

{

0.9996337891,              0,              0

},

{

1,    -1.99987793,              1

},

{

1,              0,              0

}

};

const float IIR_A[IIR_NSEC][3] = {

{

1,              0,              0

},

{

1,  -1.938049316,  0.9401855469

},

{

1,              0,              0

},

{

1,  -1.989501953,  0.9900512695

},

{

1,              0,              0

},

{

1,  -1.996887207,  0.9971923828

},

{

1,              0,              0

},

{

1,  -1.999084473,  0.9993286133

},

{

1,              0,              0

}

};

保存文件,然后使用以下代码进行滤波

这段代码是根据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.c

#include "datatype.h"

#include "iir_filter.h"

#include "iir_coefs.h"

static float y[IIR_NSEC][3];

static float x[IIR_NSEC+1][3];

int16 iir_filter(int16 in)

{

uint16 i;

x[0][0] = in;

for(i=0;i

{

y[0] =x[0]*IIR_B[0]+x[1]*IIR_B[1]+x[2]*IIR_B[2]-y[1]*IIR_A[1]-y[2]*IIR_A[2];

y[0] /= IIR_A[0];

y[2]=y[1];y[1]=y[0];

x[2]=x[1];x[1]=x[0];

x[i+1][0] = y[0];

}

if( x[IIR_NSEC][0]>32767)  x[IIR_NSEC][0]=32767;

if( x[IIR_NSEC][0]

return  ((int16)x[IIR_NSEC][0]);

}

//复位滤波器

void iir_reset(void)

{

uint16 i,j;

for(i=0;i

{

for(j=0;j<3;j++)

{

x[j]=0;

}

}

for(i=0;i

{

for(j=0;j<3;j++)

{

y[j]=0;

}

}

}

//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();

3d8a93a5aff363f22ee0e2db4cca7488.png

(336206645)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-7-21 23:18:32

|

只看该作者

沙发  佩服  高中生就会这这些了 但愿学习没有拉下

41_avatar_middle.jpg

(336162315)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-7-22 11:37:22

|

只看该作者

很不简单啊,楼主高中能搞明白什么是IIR滤波器,是个人才

3d6582786bf2a991e9f15fdc8116377e.png

(336160987)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-7-22 11:59:30

|

只看该作者

高中生……

b8c56482d2a9dbe31ab8436a7308cabc.png

(336160879)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-7-22 12:01:18

|

只看该作者

我不如楼主。

当前离线

精华汤圆VIP

{*}

417ed852d27e8c159716eac4e3779f56.gif

6a2998aa99c7810fd9429e496f617838.png

(336160085)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-7-22 12:14:32

|

只看该作者

沙发  佩服  高中生就会这这些了 但愿学习没有拉下

fd03560974437e01596bc24d55937834.png

(336157875)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-7-22 12:51:22

|

只看该作者

值得学习

3d8a3aa0ecb4b211cc5a4208f03b55d0.png

(336157535)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-7-22 12:57:02

|

只看该作者

高中生!

精华汤圆中级会员

{*}

417ed852d27e8c159716eac4e3779f56.gif

acc2c2daaed11e790149b5eafcbe8b3f.png

(336146431)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-7-22 16:02:06

|

只看该作者

mark

32_avatar_middle.jpg

(335561277)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-7-29 10:34:40

|

只看该作者

回复【2楼】franklinjin

很不简单啊,楼主高中能搞明白什么是iir滤波器,是个人才

-----------------------------------------------------------------------

是啊,怀疑原理搞懂没。

不过这样做iir stm32够呛

8480dea4bb301f7b540dedff82032028.png

(335521294)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2010-7-29 21:41:03

|

只看该作者

回复【9楼】yzak_juel

回复【2楼】franklinjin

很不简单啊,楼主高中能搞明白什么是iir滤波器,是个人才

-----------------------------------------------------------------------

是啊,怀疑原理搞懂没。

不过这样做iir stm32够呛

-----------------------------------------------------------------------

我并不记得系数怎么计算了。。。只记得各种算法的特性,反正有fdatool用着

IIR基本上靠椭圆函数法,FIR则靠等纹波,这2种算法的各项特性都比较好。

然后根据系数和结构把方程写出来,改成程序就ok了。

如果是传递函数也能变换成系数。

stm32还算好,几百条指令而已,IIR阶数少,吃得消的,而且采样率越高IIR需要的阶数越少,计算量增加不多。

尽量不要用定点系数,本底噪声太大,即使是int32型也很厉害,经常比要滤掉的噪声还大。FIR则可以用定点

82_avatar_middle.jpg

(334602577)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-8-9 12:53:00

|

只看该作者

楼主你把你做这个的完整资料来一份吧 我佩服高中生。。。

91_avatar_middle.jpg

(334602450)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-8-9 12:55:07

|

只看该作者

回复【10楼】warmonkey

-----------------------------------------------------------------------

佩服

8480dea4bb301f7b540dedff82032028.png

(334577487)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2010-8-9 19:51:10

|

只看该作者

回复【11楼】rayz82

楼主你把你做这个的完整资料来一份吧 我佩服高中生。。。

-----------------------------------------------------------------------

整个工程就不发过来了

帖子里的代码复制出来直接就能用的,作为一个模块。

对AD采样进行滤波效果非常好,能够有效减弱特定的干扰

4e3a061a6cee689711774664b8e32641.png

发表于 2010-8-9 20:50:00

|

只看该作者

楼主是个MIT的料!

0408cddfb6887793f130222f54eb44e2.png

(334562499)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-8-10 00:00:58

|

只看该作者

楼主方法用的挺前沿,在掌握点基础就MIT了~

d3c832ac36cfab3a2f02c123170de310.png

(334135121)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-8-14 22:43:56

|

只看该作者

呵呵,看到你的帖子不错!!

a33ce1ef356d1eb398d2a81921b25021.png

(334085822)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-8-15 12:25:35

|

只看该作者

mark

58_avatar_middle.jpg

(333632746)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-8-20 18:16:51

|

只看该作者

楼主真不错!

f3daeba6db2f1afcefd9797abdf6c0ec.png

(332103921)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-9-7 10:57:16

|

只看该作者

你厉害高中生都懂这些了,高三不要读了,直接申请进大学吧.

精华汤圆VIP

{*}

417ed852d27e8c159716eac4e3779f56.gif

1eb34efcf14ae0e1bb68ac620b5ebef6.png

(331895917)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-9-9 20:44:00

|

只看该作者

可以直接读研了。

8f986e8644234367cba35ca34dba88a2.png

(331891656)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-9-9 21:55:01

|

只看该作者

回复【20楼】showgu

可以直接读研了。

-----------------------------------------------------------------------

同上!

当前离线积分

精华汤圆注册会员

{*}

417ed852d27e8c159716eac4e3779f56.gif

26_avatar_middle.jpg

(331554522)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-9-13 19:33:55

|

只看该作者

楼主真是个人才,直接读研吧

34a438fb2033c61e524a02f1cd544425.png

(331536495)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-9-14 00:34:22

|

只看该作者

人才啊,想办法出国吧

bbbed4ad05f8329c1af1e75e9023e259.png

(329386267)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-10-8 21:51:30

|

只看该作者

现在的高中生真实不得了啊,真实很羡慕。这么年轻就发现了自己的兴趣方向。

58_avatar_middle.jpg

(328366683)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-10-20 17:04:34

|

只看该作者

不错

4e3a061a6cee689711774664b8e32641.png

发表于 2010-10-21 00:27:13

|

只看该作者

建议置酷贴

77_avatar_middle.jpg

(328337046)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-10-21 01:18:31

|

只看该作者

记得我高二研究的是linux,

matlib只看了看语法,

高三考完了才用matlab,siclab,g什么的弄了弄fft,架了个数据库分析股票,

95abb47923cd7531f15f37fab84cac38.png

(328282156)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-10-21 16:33:21

|

只看该作者

MARK

86_avatar_middle.jpg

(328271033)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-10-21 19:38:44

|

只看该作者

条件所致,走的早和走的远没什么必然联系

98b534a9e47568a82371a1f2eaadeea9.png

(328270142)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-10-21 19:53:35

|

只看该作者

mark

61902f2ffe7008f20c08996701f1ee67.png

(328266257)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-10-21 20:58:20

|

只看该作者

茶具啊~

44_avatar_middle.jpg

(326129266)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-11-15 14:34:51

|

只看该作者

4e3a061a6cee689711774664b8e32641.png

发表于 2010-11-22 15:46:08

|

只看该作者

mark

77_avatar_middle.jpg

(325254531)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-11-25 17:33:46

|

只看该作者

试了下,楼主的程序有问题,

编译通不过的

我上传个经过修改整理的

把滤波器常数直接放到了iir.h

iirourdev_600415YQIMLR.rar(文件大小:2K) (原文件名:iir.rar)

thread-4165021-1-1.html

效果 (原文件名:j.jpg)

8480dea4bb301f7b540dedff82032028.png

(325252395)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2010-11-25 18:09:22

|

只看该作者

LS的仁兄说一下报了什么错?我这个代码在发上来之前刚刚编译通过了。

另外,系数还是要分开放,iir.h文件中放置系数可能会导致错误,必须保证整个工程中iir_coefs.h只被iir.c包含。

77_avatar_middle.jpg

(325251878)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-11-25 18:17:59

|

只看该作者

for(i=0;i

{

y[0] =x[0]*IIR_B[0]+x[1]*IIR_B[1]+x[2]*IIR_B[2]-y[1]*IIR_A[1]-y[2]*IIR_A[2];

y[0] /= IIR_A[0];

y[2]=y[1];y[1]=y[0];

x[2]=x[1];x[1]=x[0];

x[i+1][0] = y[0];

}

y[0]是数组吧

x[0],IIR_B[0]也是数组.

这里面全是数组相乘相加,我用arduino(gcc-avr编译器)编译报错,

根据数据结构这里应该是

x[0],IIR_B[0],y[0]

我只是把系数全部复制到iir.h中,不再include原来导出的.h

另外刚才在atmega168上试用这个处理个29阶的,可能是溢出了,芯片资源要求还是比较多的

另外,这个库是你自己写的还是其他地方找的?找了很久都没找到c的算法。你有没有fir的库?

85553929e04e1904d289e6b2262cf44d.png

(325242342)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-11-25 20:56:55

|

只看该作者

mark

7f6cc1cbd921d098c276519b940dceb6.png

(325242163)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-11-25 20:59:54

|

只看该作者

mark

8480dea4bb301f7b540dedff82032028.png

(325184071)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2010-11-26 13:08:06

|

只看该作者

大囧。。。严重失误。。。我复制错了文件

这个是正确代码,也包含了直接型FIR滤波器。

FIR&IIR Filterourdev_600574LYM1IF.rar(文件大小:2K) (原文件名:filter.rar)

核心部分:

//iir_filter.c

#include "../platform.h"

//#include "iir_coefs.float.flat.h"

//#include "iir_coefs.float.sharp.h"

#include "iir_coefs_pass@2Hz_stop@0.8Hz.h"

#include "iir_filter.h"

static float y[IIR_NSEC][3];

static float x[IIR_NSEC+1][3];

//IIR_NSEC阶直接型II IIR滤波器

//IIR_NSEC个二阶biquad串联

int16 iir_filter(int16 in)

{

uint16 i;

x[0][0] = in;

for(i=0;i

{

//  y[0] = x[0]*IIR_B[0] +x[1]*IIR_B[1] +x[2]*IIR_B[2]-y[1]*IIR_A[1]-y[2]*IIR_A[2];

y[0] = 0;

if(IIR_B[0] == 1) y[0]+=x[0];

else if(IIR_B[0] == -1) y[0]-=x[0];

else if(IIR_B[0] == -2) y[0]=y[0]-x[0]-x[0];

else if(IIR_B[0] == 0);

else y[0] += x[0]*IIR_B[0];

if(IIR_B[1] == 1) y[0]+=x[1];

else if(IIR_B[1] == -1) y[0]-=x[1];

else if(IIR_B[1] == -2) y[0]=y[0]-x[1]-x[1];

else if(IIR_B[1] == 0);

else y[0] += x[1]*IIR_B[1];

if(IIR_B[2] == 1) y[0]+=x[2];

else if(IIR_B[2] == -1) y[0]-=x[2];

else if(IIR_B[2] == -2) y[0]=y[0]-x[2]-x[2];

else if(IIR_B[2] == 0);

else y[0] += x[2]*IIR_B[2];

if(IIR_A[1] == 1) y[0]-=y[1];

else if(IIR_A[1] == -1) y[0]+=y[1];

else if(IIR_A[1] == -2) y[0]=y[0]+y[1]+y[1];

else if(IIR_A[1] == 0);

else y[0] -= y[1]*IIR_A[1];

if(IIR_A[2] == 1) y[0]-=y[2];

else if(IIR_A[2] == -1) y[0]+=y[2];

else if(IIR_A[2] == -2) y[0]=y[0]+y[2]+y[2];

else if(IIR_A[2] == 0);

else y[0] -= y[2]*IIR_A[2];

if(IIR_A[0] != 1) y[0] /= IIR_A[0];

y[2]=y[1];y[1]=y[0];

x[2]=x[1];x[1]=x[0];

x[i+1][0] = y[0];

}

if( x[IIR_NSEC][0]>32767)  x[IIR_NSEC][0]=32767;

if( x[IIR_NSEC][0]

return  ((int16)x[IIR_NSEC][0]);

}

//复位滤波器

void iir_reset(void)

{

uint16 i,j;

for(i=0;i

{

for(j=0;j<3;j++)

{

x[j]=0;

}

}

for(i=0;i

{

for(j=0;j<3;j++)

{

y[j]=0;

}

}

}

如果是给AVR单片机应用,请把float改成int32,并且在fdatool中进行系数舍入和稳定性检验。

由于int32的系数经常通不过稳定性检验(红字显示unstable),我才用float

这个库完全是由我自己完成的

8480dea4bb301f7b540dedff82032028.png

(325183958)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2010-11-26 13:09:59

|

只看该作者

thread-4165021-1-1.html

新的效果图 (原文件名:DSCF6773.jpg)

77_avatar_middle.jpg

(325180455)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-11-26 14:08:22

|

只看该作者

晕~

你改了之后多出来的if是干什么的?好像意思和原来一样的,提高代码效率?

const float IIR_B[IIR_NSEC][3] = {

{

0.02256447077,              0,              0

},

{

1,              2,              1

},

{

0.01625524461,              0,              0

},

{

1,              2,              1

},

{

0.03617158905,              0,              0

},

{

1,              2,              1

},

{

0.02432162315,              0,              0

},

{

1,              2,              1

},

{

1,              0,              0

}

};代码中有else if(IIR_B[0] == -2),但是我的参数表中有2没有-2,只不过比较了下,输出值和我修改的那个是完全一样

8480dea4bb301f7b540dedff82032028.png

(325076194)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2010-11-27 19:06:03

|

只看该作者

if是提高效率的,为了改善通用性,我直接全部写上了。目前我生成出来的系数记得只有1.0.-1.-2这4个常见的整数

004dfd9abfa677fa615e67119f60a644.png

(322684395)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-12-25 11:29:22

|

只看该作者

佩服楼主,这个年纪就这么厉害了。

FIR.c好像不太对啊。。

根据fir滤波器的公式y(n)=∑h(m)x(n-m);(m: 0~(N-1)),楼主的程序和这个公式不太一样哦

8480dea4bb301f7b540dedff82032028.png

(322644697)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2010-12-25 22:31:00

|

只看该作者

FIR是正确的

int16 fir_filter(uint16 taps,const int16 *coefs,int32 coefs_div,int16 *input)

{

uint16 count;

int64 sum=0;

for(count=0;count

{

sum += input[count]*coefs[count];

//其实是一样的,在t=n时调用函数,sum == y[n]

// = h(0)*x(n) + h(1)*x(n-1) + ... + h(m)*x(n-m) + ... + h(taps-1)*x(n-taps-1)

//也就是m=[0,taps-1],而h(m) == coefs[m]      --楼上写的N应该为抽头系数个数

//taps(抽头系数个数)== 阶数N  +1

//表达式乱七八糟,千万别吐槽了~

}

sum /= coefs_div;

if(sum>32767) sum=32767;

if(sum

return sum;

}

http://zh.wikipedia.org/zh-cn/%E6%9C%89%E9%99%90%E8%84%89%E5%86%B2%E5%93%8D%E5%BA%94

96_avatar_middle.jpg

(322573338)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-12-26 18:20:19

|

只看该作者

我不如楼主。

004dfd9abfa677fa615e67119f60a644.png

(322560679)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-12-26 21:51:18

|

只看该作者

回复【44楼】warmonkey

-----------------------------------------------------------------------

有空帮研究一下 maximally flat FIR low pass filter的公式?居然没找到哪个和matlab对应的。。

8480dea4bb301f7b540dedff82032028.png

(322220485)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2010-12-30 20:21:12

|

只看该作者

带内最平坦是butterworth吧。。。如果要带内带外都平坦,就得损失截止的锐利程度

一般把带内搞定就可以了

e10b353e2229b9c5b7260c1e21ff395d.png

(322219415)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2010-12-30 20:39:02

|

只看该作者

mark一下,真的太佩服楼主了。

004dfd9abfa677fa615e67119f60a644.png

(321943104)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-1-3 01:24:13

|

只看该作者

有相位失真的,对波形要求不高的情况下,IIR的确很好

不过真没找到如何导出matlab的方程的方法

8480dea4bb301f7b540dedff82032028.png

(321822761)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2011-1-4 10:49:56

|

只看该作者

如果是FIR肯定得几百阶才能做出来,延迟太大。椭圆函数法设计的高通,相位特性较其他方法好。例如这次应用的1Hz低通,在0.8Hz处相位滞后不到10度,也就是不到23ms的延迟,问题不大。

如果把数据保存下来进行处理,可以做成零相移滤波,但这里是实时监护。

现在已经换成了3次函数插值法,高通仅仅是纠正AD的偏移,所以现在已经算是彻底解决了延迟问题

77_avatar_middle.jpg

(321777693)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-1-4 23:21:04

|

只看该作者

回复【49楼】powerpan

-----------------------------------------------------------------------

好像只能导出参数为头文件

导出C好像比较复杂

ae925055b13a28d31a386a1333c1e90d.png

(321773306)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-1-5 00:34:11

|

只看该作者

Mark

8480dea4bb301f7b540dedff82032028.png

(321721156)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2011-1-5 15:03:21

|

只看该作者

我没找到导出C的选项,似乎matlab不支持这个功能。

下次用汇编写个FIR代码,库里面那个限制太多了。

6ac91e7c40ca6169ea2132cda969aa8d.png

(320866110)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-1-15 12:34:07

|

只看该作者

太强了,有点像研究生论文,MARK!

995bf5fa2613c864f63d280f5ecef770.png

(320578719)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-1-18 20:23:58

|

只看该作者

给力的哇,楼上多个人参加探讨就是不一样,可惜我还不行

8480dea4bb301f7b540dedff82032028.png

(320146534)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2011-1-23 20:27:03

|

只看该作者

回复【46楼】powerpan

回复【44楼】warmonkey

-----------------------------------------------------------------------

有空帮研究一下 maximally flat fir low pass filter的公式?居然没找到哪个和matlab对应的。。

-----------------------------------------------------------------------

汗,记错了,IIR的maximally flat 才是butterworth,fir的不清楚。其实这个可以看fdatool的源码。

另外,simulink模型是可以导出为C的,也就是说要先把滤波器导出到simulink,再用simulink变换成C源码

3b45af3493153107a3fa217268906928.png

(318523662)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-2-11 15:14:55

|

只看该作者

...高中用fir,matlab?神啦!

哦,提醒一下,关于心电图还有一种经典算法,自适应滤波。

5498a30c7caafb451762dc44368b9b0d.png

(318494750)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-2-11 23:16:47

|

只看该作者

回复【10楼】warmonkey

回复【9楼】yzak_juel

回复【2楼】franklinjin

很不简单啊,楼主高中能搞明白什么是iir滤波器,是个人才

-----------------------------------------------------------------------

是啊,怀疑原理搞懂没。

不过这样做iir stm32够呛

-----------------------------------------------------------------------

我并不记得系数怎么计算了。。。只记得各种算法的特性,反正有fdatool用着

iir基本上靠椭圆函数法,fir则靠等纹波,这2种算法的各项特性都比较好。

然后根据系数和结构把方程写出来,改成程序就ok了。

如果是传递函数也能变换成系数。

stm32还算好,几百条指令而已,iir阶数少,吃得消的,而......

-----------------------------------------------------------------------

佩服楼主的能力,如果将来发展好的话,肯定是个了不起的人才。

不过我还是要泼点冷水:一定要注重基础知识!

你现在用的工具,毕竟是别人的。我怀疑你是否参透了其中最基本的原理。不要光知道怎么做,不知道为什么,只知道皮毛,不知道深入的原理。

我的经历和你相似,从小动手能力很强,而且很早接触电子。大二的时候,我的电设作品,全国一等奖,而且是得分最高的,也就是说是第1名。但同时,我对自己的理论水平不满,我放下手里的东西,研究了一年的理论知识。于是,很自然的觉得自己以前很肤浅。之后的实践,因为有了理论的基础,自然有了质的飞跃。

我同样见证过,理论知识欠缺而实践能力很强的工程师,悲剧的结果,后期的发展非常受限。

说什么,工程师不需要很高的理论水平,纯属悲剧人物发表的悲剧的言论。

看到你在做数学信号方面的课题,留给你几个问题,看看你对DSP是不是真的理解了:

(1)z变换和频率特性的关系;

(2)z变换和稳定性的关系;

(3)s域传递函数和z域的传递函数联系,如何转化;

(4)DFT、FFT、离散信号傅里叶变换、连续信号傅里叶变换,四者的关系及相应的频率和时域特点;

(5)什么是窗函数,有什么特点.

以上不是考试题目,考题比这个要难。但如果是真正把理论和实践同时掌握好的工程师,一定不难回答。

39_avatar_middle.jpg

(318460545)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-2-12 08:46:52

|

只看该作者

mark

62_avatar_middle.jpg

(317934330)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-2-18 10:57:07

|

只看该作者

armk

8480dea4bb301f7b540dedff82032028.png

(314885325)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2011-3-25 17:53:52

|

只看该作者

还真的不太清楚,我尝试着回答一下吧:

(1)z变换和频率特性的关系;

变换为差分方程,计算离散化的白噪声信号激励下,输出进行FFT获得频谱。

或者对于每个频点,计算离散的正弦波激励下,输出的幅度。

(2)z变换和稳定性的关系;

极点都在单位圆内则稳定。

(3)s域传递函数和z域的传递函数联系,如何转化;

s域传函转换为典型环节的组合,再用Z域的典型环节表示。

(4)DFT、FFT、离散信号傅里叶变换、连续信号傅里叶变换,四者的关系及相应的频率和时域特点;

连续信号傅立叶变换把连续信号从时域变换到频域,也就是把输入分解为一系列正弦波的叠加。

DFT(离散信号傅里叶变换)把离散信号从时域变换到频域。

fft是dft的快速算法,利用信号的连续性,简化了计算。

(5)什么是窗函数,有什么特点.

将一段信号“变换”为无限长,不断重复的信号。窗函数会导致信号频谱发生变化。不同窗函数对原始信号的“歪曲”不同。

5498a30c7caafb451762dc44368b9b0d.png

(314880689)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-3-25 19:11:08

|

只看该作者

回复【61楼】warmonkey

了解LZ的情况了

特别提一下(1)、(3)和(4):

(1)z变换和频率特性的关系;

其实将z = e ^ (jω / fs)代入z变换中,就得到了频幅特性;

(3)s域传递函数和z域的传递函数联系,如何转化;

设计IIR滤波器的时候,简单的可以用脉冲响应不变法来转化;

至于两者的关系:

s和z都是复数算子,在s变化中,e ^ (-st) = e ^ (σ + jω) * t,

z变化中,z ^ (-n) = e ^ (σ + jω) / fs * n.

因此,当σ = 0时,s平面中,正好位于虚轴,    z平面中,正好位于单位圆上;

当σ < 0时,s平面中,正好位于左半平面,z平面中,正好位于单位圆内;

当σ > 0时,s平面中,正好位于右半平面,z平面中,正好位于单位圆外.

(注意,这里的s平面指的是s平面上从 -fs/2 到 fs/2 之间的部分)

至于z域传递函数和稳定性的关系,对应的用s域来解释就太容易了,那就是e ^ σt这个指数函数的收敛性问题了.

(4)dft、fft、离散信号傅里叶变换、连续信号傅里叶变换,四者的关系及相应的频率和时域特点;

“DFT”和“离散信号傅里叶变换”是两回事:“DFT”是离散化的傅里叶变化,是对有限长的离散信号而言的;“离散信号傅里叶变换”是对无限长的离散信号而言的.

再加上傅里叶级数,这个问题就完整了. 另外,FFT是DFT在K = 2 ^ N时的简单情况,放在一边不做讨论.

四者的关系如下:

输入                           输出

傅里叶级数                有限长连续信号(周期信号)       无限长离散频谱

连续信号傅里叶变换        无限长连续信号                 无限长连续频谱

离散信号傅里叶变换        无限长离散信号                 周期性连续频谱

DFT                       有限长离散信号(视为周期信号)   周期性离散频谱

注:个人理解.

e113737f52ead09fe2824084b71eebdb.png

(314463092)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-3-30 15:11:05

|

只看该作者

mark

e113737f52ead09fe2824084b71eebdb.png

(314463082)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-3-30 15:11:15

|

只看该作者

mark

8480dea4bb301f7b540dedff82032028.png

(314109743)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2011-4-3 17:20:14

|

只看该作者

回复【62楼】mitchell

-----------------------------------------------------------------------

汗,看来没仔细学过离散系统确实不行。。。求大虾联系方式,以后多聊聊,谢谢了。

精华汤圆中级会员

{*}

417ed852d27e8c159716eac4e3779f56.gif

06_avatar_middle.jpg

(314108669)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-4-3 17:38:08

|

只看该作者

mark

93869fbf5c37fa68322c5e23ed8a6f28.png

(314104083)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-4-3 18:54:34

|

只看该作者

回复【62楼】mitchell

-----------------------------------------------------------------------

麻省大神求拜师学艺。。。

d97b711fa7b8bfdae115431c90b832f6.png

(314101061)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-4-3 19:44:56

|

只看该作者

大神啊,都是。

5498a30c7caafb451762dc44368b9b0d.png

(313841219)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-4-6 19:55:38

|

只看该作者

回复【65楼】warmonkey

-----------------------------------------------------------------------

谦虚了~

不敢当, 我QQ: 799842867, 随时交流

回复【67楼】reloaded 电子浪人

-----------------------------------------------------------------------

您太客气了,mitchell是我中文名字的音译

3b45af3493153107a3fa217268906928.png

(312011826)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-4-28 00:05:31

|

只看该作者

回复【楼主位】warmonkey

-----------------------------------------------------------------------

“这个函数比STM32 DSP库中的函数要好很多,DSP库中的2个IIR滤波函数都不能连续处理数据流。 ”

可以吧?这个biquad 代码写的相当不错,可以随意剪成1个sector或者增加更多。

273aa6bf58a9b42a01c137a2bd4c2b18.png

(311995708)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-4-28 04:34:09

|

只看该作者

神人~mark!

a5d56a8849adbb27ddbe47ccf2a2ac33.png

(310988807)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-5-9 20:15:50

|

只看该作者

神人

积分

精华汤圆新注册者

{*}

417ed852d27e8c159716eac4e3779f56.gif

91_avatar_middle.jpg

(310987927)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-5-9 20:30:30

|

只看该作者

从楼主的这只手来看不像高中生的...

dc7d81006f88f95860e73d7cc1b41a2a.png

(310191263)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-5-19 01:48:14

|

只看该作者

现在matlab 主推基于模型的设计 m3内核的芯片也开始支持,第三方软件rapidstm32

3b45af3493153107a3fa217268906928.png

(310155404)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-5-19 11:45:53

|

只看该作者

回复【77楼】tiandewen

-----------------------------------------------------------------------

这个不错,下来看看。

7645874d4640548e32c27e51ec7c55ad.png

(305286506)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-7-14 20:14:11

|

只看该作者

mark

1a79f82d1e0e28111ecaf6a408e64c86.png

(305115477)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-7-16 19:44:40

|

只看该作者

mark

05_avatar_middle.jpg

(302871934)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-8-11 18:57:03

|

只看该作者

MARK

c37bae79d1d5800340e990bcd5fe6e62.png

(302871546)

出625入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-8-11 19:03:31

|

只看该作者

佩服,研究一下

6fa92a7c957e8d906173aa0a7eee89b5.png

(302867454)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-8-11 20:11:43

|

只看该作者

mark

7cb969efa2d8c5be0dd98a17365707c3.png

(302826314)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-8-12 07:37:23

|

只看该作者

mark

eb85a474f5087a3decaeadb149b59b64.png

(301597674)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-8-26 12:54:43

|

只看该作者

mark......................

739d666802751c87bf9ca66d32288c3a.png

(301595841)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-8-26 13:25:16

|

只看该作者

mark

a33ce1ef356d1eb398d2a81921b25021.png

(301592797)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-8-26 14:16:00

|

只看该作者

mark

04_avatar_middle.jpg

(301585422)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-8-26 16:18:55

|

只看该作者

MARK

头像被屏蔽

(301518608)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-8-27 10:52:29

|

只看该作者

提示: 作者被禁止或删除 内容自动屏蔽

06_avatar_middle.jpg

(299060132)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-9-24 21:47:05

|

只看该作者

服得很,不得不顶

26_avatar_middle.jpg

(297593819)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-10-11 21:05:38

|

只看该作者

回复【楼主位】warmonkey

-----------------------------------------------------------------------

楼主莫怪啊,我想问问你是用什么采集心跳信号的,用的换能器?

72_avatar_middle.jpg

(297158190)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-10-16 22:06:07

|

只看该作者

楼主真是个人才

1a2befb3fed067f72ee7ed4d67fd8790.png

(296679084)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-10-22 11:11:13

|

只看该作者

MARK,楼主强人

4d0bdb2dfdf8e5415c3f8a3db6c1e5fe.png

(296160943)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-10-28 11:06:54

|

只看该作者

mark!

8480dea4bb301f7b540dedff82032028.png

(295562942)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2011-11-4 09:13:35

|

只看该作者

回复【89楼】chao8828276

心电信号的实际波行我不太清楚,不过我也搞过fir,我没搞过算法,我也是用matlab产生的系数,但是32阶的fir来处理已经效果很好了,我当时仿真了一下,32阶处理掉50hz以及以上的频率信号是没问题的,当然截止频率要很低

-----------------------------------------------------------------------

我说的是高通滤波

c37bae79d1d5800340e990bcd5fe6e62.png

(295201342)

出625入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-11-8 13:40:15

|

只看该作者

楼主,请教个问题

#define MWSPT_NSEC 9

这个是什么意思

那个数组为什么定义成 MWSPT_NSEC行3列?这个有点没看懂

5c948ce23b5536147cb09b22b20426e2.png

(292338125)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-12-11 17:00:32

|

只看该作者

mark!这个是用的纯数字滤波么?是不是直接把信号放大,然后AD转换?

积分

精华汤圆注册会员

{*}

417ed852d27e8c159716eac4e3779f56.gif

f5ab9996539825985fda0c9e33f4ecb4.png

(292258025)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-12-12 15:15:32

|

只看该作者

mark

a77fc48e6602514816a739f937108c99.png

(290806656)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-12-29 10:25:01

|

只看该作者

过来佩服一下楼主

e0d55b4fe06060c3e92d380a8564389b.png

(290796244)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-12-29 13:18:33

|

只看该作者

自愧不如

b2c110dc2186c733d285b9668ec8eb5f.png

(290794535)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-12-29 13:47:02

|

只看该作者

mark,自勉

71b3076bdfd612d1d47432cb8e839502.png

(290687224)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2011-12-30 19:35:33

|

只看该作者

。。。全部看完了。。。

启示:继续潜水

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值