今天出了点岔子,底噪不知怎么变大了很多,
估计是程序问题,也可能是模拟电路的故障,示波器不在手边,难办。
IIR高通改为全浮点计算,能直接支持matlab生成的系数,哇哈哈。
附上代码(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<IIR_NSEC;i++)
{
y[i][0] =x[i][0]*IIR_B[i][0]+x[i][1]*IIR_B[i][1]+x[i][2]*IIR_B[i][2]-y[i][1]*IIR_A[i][1]-y[i][2]*IIR_A[i][2];
y[i][0] /= IIR_A[i][0];
y[i][2]=y[i][1];y[i][1]=y[i][0];
x[i][2]=x[i][1];x[i][1]=x[i][0];
x[i+1][0] = y[i][0];
}
if( x[IIR_NSEC][0]>32767) x[IIR_NSEC][0]=32767;
if( x[IIR_NSEC][0]<-32768) x[IIR_NSEC][0]=-32768;
return ((int16)x[IIR_NSEC][0]);
}
//复位滤波器
void iir_reset(void)
{
uint16 i,j;
for(i=0;i<IIR_NSEC+1;i++)
{
for(j=0;j<3;j++)
{
x[i][j]=0;
}
}
for(i=0;i<IIR_NSEC;i++)
{
for(j=0;j<3;j++)
{
y[i][j]=0;
}
}
}
系数生成方法
用fdatool设计一个IIR滤波器,然后点击菜单中的Edit->Convert Structure 选择Direct Form I ,SOS,(必须是Direct Form I,II不行)
注意这里千万不要点击Convert to single section 这一项。
然后选择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项要删掉,那个twwtypes.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
}
};
最后调用iir_filter函数,就可以得到滤波后的结果