C数字滤波器

复习数字信号处理,根据IIR滤波器的差分方程写了段相应的C程序,滤波器系数用matlab产生,滤波程序如下:
void IIR(const double *x,double *y)
{
    //滤波器系数,低通,截止频率1KHz
    double B[3]={0,0.116,0.0715};     //分子系数,系统零点
    double A[4]={1,1.6 ,-1.02 ,0.232};//分母系数,系统极点

	int n=0;
	y[0]=B[0]*x[0];
	y[1]=A[1]*y[0]+B[0]*x[1]+B[1]*x[0];
	y[2]=A[1]*y[1]+A[2]*y[0]+B[0]*x[2]+B[1]*x[1]+B[2]*x[0];
	for(n=3;n<N;n++)
	y[n]=A[1]*y[n-1]+A[2]*y[n-2]+A[3]*y[n-3]+B[0]*x[n]+B[1]*x[n-1]+B[2]*x[n-2];
}

 

用matlab产生信号并写入到文件中,在vs2012里用c/c++读取文件数据进行滤波并做FFT,并将结果写入到文件,最后用matlab读取结果文件中的数据绘图,与直接用matlab滤波及FFT做对比,其中C与matlab都是对数据做2048点FFT,C的FFT程序之前已调试成功,这里只将其移植调用。matlab文件程序如下所示:

clc
N=2048;

%向文件中写入原始数据
t=0:0.0001:1;
s=sin(2*pi*100*t)+sin(2*pi*2500*t)+cos(2*pi*800*t);             %??0~pi/2?Sin?;
fidc=fopen('D:\Microsoft Visual Studio 11.0\Projects\TestC++\DIT-FFT\DIT-FFT\InData.txt','wt');       %?"wt"?????,\n???
 for t=1:10000;
 fprintf(fidc,'%f,', s(t));
 end
 fclose(fidc);
 
 %从文件读入数据并显示频谱
x = importdata('D:\Microsoft Visual Studio 11.0\Projects\TestC++\DIT-FFT\DIT-FFT\InData.txt');
y=fft(x*10000/N,N);
y=abs(y(1:N/2));
figure(1)
subplot(1,2,1);
plot(y)
%读入C程序FFT结果并显示
x_fft = importdata('D:\Microsoft Visual Studio 11.0\Projects\TestC++\DIT-FFT\DIT-FFT\InData_FFT.txt');
subplot(1,2,2);
plot(x_fft(1:N/2));

%从文件读入数据,经过matlab滤波并FFT
x = importdata('D:\Microsoft Visual Studio 11.0\Projects\TestC++\DIT-FFT\DIT-FFT\InData.txt');
z=[0 0.116 0.0715];
p=[1 -1.6 1.02 -0.232];
y2=filter(z,p,x);
y3=fft(y2,N);
y3=abs(y3(1:N/2));
figure(2);
subplot(1,2,1);
plot(y3);

%从文件读入经过C滤波并FFT的结果
x_iir_fft = importdata('D:\Microsoft Visual Studio 11.0\Projects\TestC++\DIT-FFT\DIT-FFT\OutData_FFT.txt');
subplot(1,2,2);
plot(x_iir_fft(1:N/2));

matlab的FFT与c程序的FFT:

MATLAB滤波及FFT结果与C滤波及FFT结果:

结果比较程序大致运行正确。


记录用matlab的FDA工具箱产生系数的使用,免得每次都要想一想

maltlab的filter文档里介绍了滤波器实现方式如下


 example:

             用FDA产生二阶高通IIR,参数如下

,系数为a = [1 -1.1429 0.4128],b = [1 2 -1],用matlab代码实现如下;

t=0:0.0001:1;  
s=sin(2*pi*100*t)+sin(2*pi*2500*t)+cos(2*pi*800*t);
figure,plot(abs(fft(s))),title('fft');
b = [1 -2 1];
a = [1 -1.1429 0.4128];
s2 = filter(b,a,s);
s3 = s;
s3(1) = b(1)*s(1);
s3(2) = -1*a(2)*s(1)+b(1)*s(2)+b(2)*s(1);
for i = 3:10000
    s3(i) = -1*(a(1+1)*s3(i-1)+a(1+2)*s3(i-2))+b(0+1)*s(i)+b(1+1)*s(i-1)+b(2+1)*s(i-2);
end
figure,plot(abs(fft(s2))) ,title('filter');
figure,plot(abs(fft(s3))),title('diff')

容易弄错的地方,matlab是以以下形式给出的系数,对应的z变化形式分母为


对应的差分方程为

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值