第1页信号实验一离散傅里叶变换及其快速算法一、实验目的1、掌握计算序列的离散傅里叶变换(FFT)的方法;2、掌握实现时间抽取快速傅里叶变换(FFT)编程方法;3、加深对DFT与序列的傅里叶变换和Z变换之间的关系的理解;4、复习复数序列的运算方法。二、程序设计框图1、码位倒置程序框图输入A[I],MI←0,J←0,N←2MI≥J?T←A[J]A[J]←A[I]A[I]←TK←N/2KJ?J←J←KK←K/2J←J+KI←I+1I=N-1?输出A[I]NoYesNoYesNo接蝶形运算程序Yes第2页2、蝶形图运算程序框图接码位倒置程序L=1LE=2LLE1=LE/2W=1W1=exp(-jπ/LE1)R=0P=RQ=P+LE1T=A[Q]*WA[Q]=A[P]-TA[P]=A[Q]+TP=P+LEPN-1?NoW=W*W1YesR=R+1RLE1-1?L=L+1NoYesLM?No结束Yes第3页三、实验程序实验程序的源代码如下:#includemath.h#includestdio.h/*------------------------------------------------------------------------------------------子函数部分------------------------------------------------------------------------------------------*/voidswap(float*a,float*b)//交换变量子函数{floatT;T=*a;*a=*b;*b=T;}voidfft(floatA[],floatB[],unsignedM)//数组A为序列的实部,数组B为序列的虚部{unsignedlongN,I,J,K,L,LE,LE1,P,Q,R;floatWr,Wi,W1r,W1i,WTr,WTi,theta,Tr,Ti;N=1M;J=0;for(I=0;IN-1;I++){if(JI){swap(&A[I],&A[J]);swap(&B[I],&B[J]);}K=N1;while(K=2&&J=K){J-=K;K=1;}J+=K;}for(L=1;L=M;L++){LE=1L;LE1=LE/2;Wr=1.0;Wi=0.0;theta=(-1)*3.1415926536/LE1;W1r=cos(theta);W1i=sin(theta);第4页for(R=0;RLE1;R++){for(P=R;PN-1;P+=LE){Q=P+LE1;//基本蝶形图的复数运算Tr=Wr*A[Q]-Wi*B[Q];Ti=Wr*B[Q]+Wi*A[Q];A[Q]=A[P]-Tr;B[Q]=B[P]-Ti;A[P]+=Tr;B[P]+=Ti;}WTr=Wr;WTi=Wi;Wr=WTr*W1r-WTi*W1i;Wi=WTr*W1i+WTi*W1r;}}return;}/*------------------------------------------------------------------------------------------主函数部分------------------------------------------------------------------------------------------*/voidmain(){floatA[20],B[20];chart1,t2,file_name[20];intM,N,i,iiff;FILE*fp;/*************************************数据读取部分************************************/printf(请输入文件名:);//输入数据文件名scanf(%s,file_name);printf(FFT变换还是IFFT变换?(FFT:1,IFFT:-1):);//输入变换方式,1为FFT,-1为IFFTscanf(%d,&iiff);while(iiff!=1&&iiff!=-1)//检错:检验上一步的输入是否有错,有错则重新输入{printf(输入错误,请重新输入!);printf(FFTorIFFT?(FFT:1,IFFT:-1):);scanf(%d,&iiff);}fp=fopen(file_name,r);//打开文件并读入数据fscanf(fp,%d,&M);第5页N=pow(2,M);//计算序列总数for(i=0;iN;i++)//读取文件中的数据{fscanf(fp,%f%c%c%f,&A[i],&t1,&t2,&B[i]);if(iiff==-1)//根据FFT或IFFT修正BB[i]=B[i]*-1;if(t2!='j')//检错:检验读取格式是否有错{printf(输入格式错误\n);break;}if(t1=='+')//判断虚部的正负号B[i]=B[i];elseif(t1=='-')B[i]=-B[i];}/****************************************变换部分****************************************/fft(A,B,M);//FFT变换/**************************************数据输出部分**************************************/fp=fopen(fft_result.txt,w);//输出结果if(iiff==-1)fprintf(fp,IFFT变换的输出结果是:\n);elsefprintf(fp,FFT变换的输出结果是:\n);for(i=0;iN;i++){if(iiff==-1)//根据FFT或IFFT修正B{B[i]=B[i]*-1/N;A[i]=A[i]/N;}if(B[i]=0)//修正虚部的输出格式fprintf(fp,%f+j%f\n,A[i],B[i]);elseif(B[i]0)fprintf(fp,%f-j%f\n,A[i],-B[i]);elseif(B[i]==0)fprintf(fp,%f\n,A[i]);}fclose(fp);}四、程序运行结果检验1、对序列(){1,2,1,4}xn进行FFT变换(1)输入文件fft_input.txt:第6页21+j02+j0-1+j04+j0(2)控制台输入:请输入文件名:fft_input.txtFFT变换还是IFFT变换?(FFT:1,IFFT:-1):1(3)输出文件fft_result.txt:FFT变换的输出结果是:6.00000+j0.000002.00000+j2.00000-6.00000+j0.000002.00000+j-2.00000(4)运行结果分析:程序运行输出结果与计算结果相同,表示傅里叶正变换(FFT)成功。2、对序列(){6,22,6,22}Xkjj进行IFFT变换(1)输入文件ifft_input.txt:26+j02+j2-6+j02-j2(2)控制台输入:请输入文件名:ifft_input.txtFFT变换还是IFFT变换?(FFT:1,IFFT:-1):-1(3)输出文件fft_result.txt:IFFT变换的输出结果是:1.000000+j0.0000002.000000-j0.000000-1.000000+j0.0000004.000000+j0.000000(4)运行结果分析:程序运行输出结果与计算结果相同,表示傅里叶正变换(FFT)成功。第7页信号实验二IIR数字滤波器的设计一、实验目的1.掌握设计IIR数字滤波器的冲激响应不变法;2.掌握设计IIR数字滤波器的双线性变换法3.掌握IIR数字滤波器的实现方法。二、滤波器设计过程用双线性变换法设计一个IIR低通数字滤波器,数字滤波器的设计指标是ppδ=-1dB,0.3δ=-15dB,0.4ppwradwrad取采样时间1sTs,进行预畸变将上述数字滤波器的设计指标变换为模拟滤波器的设计指标,即pps2tan2tan0.1/δ=20log()=-1dB22tan2tan0.15/δ=20log()=-15dB2papsssasswradsHjTwradsHjT采用巴特沃思型逼近形式,因此,设计的模拟滤波器应满足20.121.51(/)101(/)10NpcNsc可得,模拟滤波器的系统函数a()Hs为2220.147995()(0.376480.52895)(1.028500.52895)(1.405010.52895)aHsssssss采用双线性变换法,得数字滤波器的系统函数123()()()()HzHzHzHz其中1211212212123120.8338(1)()11.314320.714890.8338(1)()11.054100.375340.8338(1)()10.945920.23422zHzzzzHzzzzHzzz可采用级联结构实现该滤波器。三、实验程序实验程序的源代码如下:#includemath.h#includestdio.h/*------------------------------------------------------------------------------------------子函数部分------------------------------------------------------------------------------------------*/voidIIRDF(floatA[],unsignedlongN)//A为待滤波序列,M为序列长度第8页{unsignedlongn;//赋初值x[0]为x(0),x[1]为x(-1),x[2]为x(-2),同理y1,y2,yfloatx[3]={0,0,0},y1[3]={0,0,0},y2[3]={0,0,0},y[3]={0,0,0};for(n=0;nN;n++){x[0]=A[n];//第一级y1[0]=1.31432*y1[1]-0.71489*y1[2]+0.08338*x[0]+0.16676*x[1]+0.08338*x[2];x[2]=x[1];x[1]=x[0];//第二级y2[0]=1.0541*y2[1]-0.37534*y2[2]+0.08338*y1[0]+0.16676*y1[1]+0.08338*y1[2];y1[2]=y1[1];y1[1]=y1[0];//第三级y[0]=0.94592*y[1]-0.23422*y[2]+0.08338*y2[0]+0.16676*y2[1]+0.08338*y2[2];y2[2]=y2[1];y2[1]=y2[0];y[2]=y[1];y[1]=y[0];A[n]=y[0];}}/*------------------------------------------------------------------------------------------主函数部分------------------------------------------------------------------------------------------*/voidmain(){intn,N;floatTs,T;floatx[3][100],x0[3][100];FILE*fp,*fp1,*fp2,*fp3;/***********************************数据输入部分***********************************/Ts=0.00125;