DSP课程设计报告(256点FFT的实现).doc_第1页
DSP课程设计报告(256点FFT的实现).doc_第2页
DSP课程设计报告(256点FFT的实现).doc_第3页
DSP课程设计报告(256点FFT的实现).doc_第4页
DSP课程设计报告(256点FFT的实现).doc_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

DSP课程设计报告设计题目: 256点FFT 院 系: 计算机科学学院 专 业: 自动化 年 级: 2008级 姓 名: 学 号: 指导教师: 2011年 11 月 28日256点FFT的实现一、 设计目的1、 加深对DFT算法原理和基本性质的理解;2、 熟悉FFT的算法原理和FFT子程序的算法流程和应用;3、 学习用FFT对连续信号和时域信号进行频谱分析的方法;4、 学习DSP中FFT的设计和编程思想;5、 学习使用CCS的波形观察器观察波形和频谱情况;二、 设计内容给定256 采样点,求频谱,统计运行时间并在PC 上显示。三、 设计原理快速傅里叶变换(FFT)是一种高效实现离散傅里叶变换(DFT)的快速算法,是数字信号处理中最为重要的工具之一,它在声学,语音,电信和信号处理等领域有着广泛的应用。快速傅里叶变换FFT旋转因子WN 有如下的特性。对称性: WNk+N/2=-WNk 周期性:WNn(N-k)=WNk(N-n)=WN-nk利用这些特性,既可以使DFT中有些项合并,减少了乘法积项,又可以将长序列的DFT分解成几个短序列的DFT。FFT就是利用了旋转因子的对称性和周期性来减少运算量的。FFT的算法是将长序列的DFT分解成短序列的DFT。例如:N为偶数时,先将N点的DFT分解为两个N/2点的DFT,使复数乘法减少一半:再将每个N/2点的DFT分解成N/4点的DFT,使复数乘又减少一半,继续进行分解可以大大减少计算量。最小变换的点数称为基数,对于基数为2的FFT算法,它的最小变换是2点DFT。一般而言,FFT算法分为按时间抽取的FFT(DIT)和按频率抽取的(DIF FFT)两大类。IF FFT算法是在时域内将每一级输入序列依次按奇偶分成个短序列进行计算。而DIF FFT算法是在频域内将每一级输入序列依次奇偶分成个短序列进行计算。两者的区别是旋转因子出现的位置不同,得算法是一样的。在DIF FFT算法中,旋转因子出现在输入端,而在DIF FFT算法中它出现在输入端。假定序列x(n)的点数N是2的幂,按照DIF FFT算法可将其分为偶序列和奇序列。偶序列:x(2r)=x1(r)奇序列:x(2r+1)=x2(r)其中:r=0,1,2,N/2-1 则x(n)的DFT表示为 式中,x1(k)和x2(k)分别为x1(r)和x2(r)的N/2的DFT。 由于对称性,WNk+N/2=-WNk。因此,N点DFT可分为两部分:前半部分:x(k)=x1(k)+WkNx2(k) (4)后半部分: x(N/2+k)=x1(k)-WkNx2(k) k=0,1,N/2-1 (5)从式(4)和式(5)可以看出,只要求出0N/2-1区间x1(k)和x2(k)的值,就可求出0N-1区间x(k)的N点值。以同样的方式进行抽取,可以求得N/4点的DFT,重复抽取过程,就可以使N点的DFT用上组2点的 DFT来计算,这样就可以大减少运算量。基2 DIF FFT的蝶形运算如图(a)所示。设蝶形输入为X1(K)和X2(K),输出为x(k)和x(N/2+K),则有 x(k)=x1(k)+WkNx2(k) (6) x(N/2+k)=x1(k)-WkNx2(k) (7)在基数为2的FFT中,设N=2M,共有M级运算,每级有N/2个2点FFT蝶形运算,因此,N点FFT总共有MN/2个蝶形运算。 图(a) 基2 DIF FFT的蝶形运算例如:基数为2的FFT,当N=8时,共需要3级,12个基2 DIT FFT的蝶形运算。其信号流程如图(b)所示。x(0) x(0) WN0x(4) x(1) -1 WN0x(2) x(2) -1 WN0 WN2x(6) x(3) -1 -1 WN0x(1) x(4) -1 WN0 WN1x(5) x(5) -1 -1 WN0 WN2x(3) x(6) -1 -1 WN0 WN2 WN3x(7) x(7) -1 -1 -1 图(b) 8点基2 DIF FFT蝶形运算从图(b)可以看出,输入是经过比特反转的倒位序列,称为位码倒置,其排列顺序为x(0),x(4),x(2),x(6),x(1),x(5),x(3),x(7),输出是按自然顺序排列,其顺序为x(0),x(1),x(2),x(3),x(4),x(5),x(6),x(7)。四、 设计步骤1、 启动CSS。2、 加载工程项目。3、 编译。4、 加载.out文件5、 打开串口调试。6、 运行。7、 输入Texas点手工发送。8、 观察s的频谱。si.real=sin(2*3.141592653589793*i/FFT_N); /实部为正弦波FFT_N点采样,赋值为1si.imag=0; /虚部为0正弦波形图,由于定义了虚部,0的下方有波形。9、 调整,只显示实部。10、调整显示大小,显示更好。五、 程序主要代码1、main( )函数#include DSP28_Device.h#include FFT.h#define send(A) SciaRegs.SCITXBUF= (A);#define WaitForReady while(SciaRegs.SCICTL2.bit.TXEMPTY=0)interrupt void sci_rx_isr(void);interrupt void sci_tx_isr(void);interrupt void timer0_isr(void);void TakeTheBit(Uint32 in);Uint8 strcmp(char *a,char *b);void printf(char *a);void menu(void);char jilu26=0,0,0,0,0,0;unsigned char message20;Uint8 index=0,flag=0;Uint32 Timer0InterruptCount=0;void main(void) /-系统初始化(PLL,锁相环,外设时钟等等)-/ InitSysCtrl();/-gpio初始化-/ InitGpio(); /- 禁止CPU中断,清除所有中断标志位-/ DINT; IER = 0x0000; IFR = 0x0000;/-初始化PIE控制寄存器-/ InitPieCtrl();/-初始化中断向量表-/ InitPieVectTable();/=中断向量配置=/ EALLOW; PieVectTable.RXAINT = & sci_rx_isr;/sci 接受中断入口 PieVectTable.TXAINT = & sci_tx_isr;/sci 发送中断入口 PieVectTable.TINT0 = & timer0_isr;/定时器0中断入口 EDIS;/-分界-/ /-初始化串口(根据需要)-/ InitSci();/=初始化事件管理器=/ InitEv();/=初始化定时器0=/ InitCpuTimers(); / For this example, only initialize the Cpu Timers/ Configure CPU-Timer 0 to interrupt every second:/ 100MHz CPU Freq, 1 second Period (in uSeconds) ConfigCpuTimer(&CpuTimer0, 150, 10); /10us产生一次中断/=用户自定义的初始化 =/=显示菜单=/ menu();/=开启中断=/ PieCtrl.PIEIER1.bit.INTx7 =1 ; /CPU定时器0中断开 PieCtrl.PIEIER9.bit.INTx1 =1 ;/SCI 接受中断开启/ PieCtrl.PIEIER9.bit.INTx2 =1 ;/SCI 发送中断开启 IER |=M_INT1; IER |=M_INT9;/关掉 sci中断 EINT; ERTM;/=运行程序=/ while(1) /=FFT测试程序=/ if(flag=1) CreatVirtualData(); /创建虚拟的256个采样点 StartCpuTimer0();/启动定时器开始计时 TestFFT();/开始FFT变换 StopCpuTimer0();/停止计时 TakeTheBit(Timer0InterruptCount*10); printf(jilu2);/显示变换时间 printf(us); flag=0; /等待中断 ;/=/函数原型:void menu(void)/函数功能:在PC上显示本设计界面(需要根据具体调试更改)/输入参数:无/输出参数:无/=void menu(void)printf(DSP 课程设计之256点FFTrn);printf(运行时间rn);interrupt void timer0_isr(void) Timer0InterruptCount+;/计数值 每10us PieCtrl.PIEACK.all=PIEACK_GROUP1; /确认pie中断/=/串口接收中断服务程序/=interrupt void sci_tx_isr(void)SciaRegs.SCITXBUF=messageindex+;/自动发送数据PieCtrl.PIEACK.all=0x0100;/确认中断/=/串口发送中断服务程序/=interrupt void sci_rx_isr(void)int i;char buffer16;for (i=0;i4)flag=1;/接受PC端发送的命令/=相应的操作就在这添加就okSciaRegs.SCIFFRX.bit.RXFIFORESET=0;SciaRegs.SCIFFRX.bit.RXFIFORESET=1;SciaRegs.SCIFFRX.bit.RXFFINTCLR=1;/=/函数原型:void printf(char *a)/函数功能:/输入参数:/输出参数:/=void printf(char *a)Uint8 i;for(i=0;ai!=0;i+)WaitForReady;/等待上个字节发送完成SciaRegs.SCITXBUF=ai;/发送当前字节/=/函数原型:void TakeTheBit(Uint32 in)/函数功能:整形数据转化为字符型数据/输入参数:转换完成的整形数据/输出参数:字符串的首地址/=void TakeTheBit(Uint32 in)jilu20=in/10000+48;/取万位jilu21=in%10000/1000+48;/取千位jilu22=in%1000/100+48;/取百位jilu23=in%100/10+48;/取十位jilu24=in%10+48;/取个位/=/函数原型:Uint8 strcmp(char *a,char *b)/函数功能:字符串比较函数/输入参数:/输出参数:/=Uint8 strcmp(char *a,char *b)Uint8 i,jilu=0;for(i=0;(ai!=0)&(bi!=0);i+)if(ai=bi) jilu+;return jilu;2、主程序简要说明:此程序包是通用的快速傅里叶变换C语言函数,移植性强,以下部分不依赖硬件。此程序包采用联合体的形式表示一个复数,输入为自然顺序的复数(输入实数是可令复数虚部为0),输出为经过FFT变换的自然顺序的复数.此程序包可在初始化时调用create_sin_tab()函数创建正弦函数表,以后的可采用查表法计算耗时较多的sin和cos运算,加快可计算速度。#include math.h#define FFT_N 256 /定义福利叶变换的点数#define PI 3.1415926535897932384626433832795028841971 /定义圆周率值struct compx float real,imag; /定义一个复数结构struct compx sFFT_N; /FFT输入和输出:从S0开始存放,根据大小自己定义float SIN_TABFFT_N/4+1; /定义正弦表的存放空间/*函数原型:struct compx EE(struct compx b1,struct compx b2) 函数功能:对两个复数进行乘法运算输入参数:两个以联合体定义的复数a,b输出参数:a和b的乘积,以联合体的形式输出*/struct compx EE(struct compx a,struct compx b) struct compx c; c.real=a.real*b.real-a.imag*b.imag; c.imag=a.real*b.imag+a.imag*b.real; return(c);/*函数原型:void create_sin_tab(float *sin_t)函数功能:创建一个正弦采样表,采样点数与福利叶变换点数相同输入参数:*sin_t存放正弦表的数组指针输出参数:无*/void create_sin_tab(float *sin_t) int i; for(i=0;i=0&nFFT_N/4&n=FFT_N/2&n=3*FFT_N/4&n2*PI) pi2-=2*PI; a=sin_tab(pi2); return a;/*函数原型:void FFT(struct compx *xin,int N)函数功能:对输入的复数组进行快速傅里叶变换(FFT)输入参数:*xin复数结构体组的首地址指针,struct型输出参数:无*/void FFT(struct compx *xin) int f,m,nv2,nm1,i,k,l,j=0; struct compx u,w,t; nv2=FFT_N/2; /变址运算,即把自然顺序变成倒位序,采用雷德算法 nm1=FFT_N-1; for(i=0;inm1;i+) if(ij) /如果ij,即进行变址 t=xinj; xinj=xini; xini=t; k=nv2; /求j的下一个倒位序 while(k=j) /如果k=j,表示j的最高位为1 j=j-k; /把最高位变成0 k=k/2; /k/2,比较次高位,依次类推,逐个比较,直到某个位为0 j=j+k; /把0改为1 int le,lei,ip; /FFT运算核,使用蝶形运算完成FFT运算 f=FFT_N; for(l=1;(f=f/2)!=1;l+) /计算l的值,即计算蝶形级数 ; for(m=1;m=l;m+) / 控制蝶形结级数 /m表示第m级蝶形,l为蝶形级总数l=log(2)N le=2(m-1); /le蝶形结距离,即第m级蝶形的蝶形结相距le点 lei=le/2; /同一蝶形结中参加运算的两点的距离 u.real=1.0; /u为蝶形结运算系数,初始值为1 u.imag=0.0; /w.real=cos(PI/lei); /不适用查表法计算sin值和cos值 / w.imag=-sin(PI/lei); w.real=cos_tab(PI/lei); /w为系数商,即当前系数与前一个系数的商 w.imag=-sin_tab(PI/lei); for(j=0;j=lei-1;j+) /控制计算不同种蝶形结,即计算系数不同的蝶形结 for(i=j;i=FFT_N-1;i=i+le) /控制同一蝶形结运算,即计算系数相同蝶形结 ip=i+lei; /i,ip分别表示参加蝶形运算的两个节点 t=EE(xinip,u); /蝶形运算,详见公式 xinip.real=xini.real-t.real; xinip.imag=xini.imag-t.imag; xini.real=xini.real+t.real; xini.imag=xini.imag+t.imag; u=EE(u,w); /改变系数,进行下一个蝶形运算 /*函数原型:void Tes

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论