DSP报告.docx
《DSP报告.docx》由会员分享,可在线阅读,更多相关《DSP报告.docx(13页珍藏版)》请在冰豆网上搜索。
DSP报告
基于CCS和ICETEK5509实验箱
----FFT算法的C语言实现与验证
学院:
计算机学院
班级:
通信0801
姓名:
·····
学号:
3080601022
同组成员:
···
指导老师:
···
一、课程设计目的
1、熟悉FFT的基本原理及A/D转换的基本原理
2、针对理论课、实验课中无时间和不方便提及内容和需强调重点进行补充与完善;
3、以原理算法的实现与验证体会DSP技术的系统性,并加深基本原理的体会。
二、课程设计要求
1.设计一个以ICETEK5509为硬件主体,FFT为核心算法的频谱分析系统方案;
2.用C语言编写系统软件的核心部分,熟悉CCS调试环境的使用方法,在CCSIDE中仿真实现方案功能;
3.在实验箱上由硬件实现频谱分析。
三、课程设计内容
1、FFT算法C语言实现与验证
1)参考教材P371的14.3节完成CCS环境中的FFT工程的建立;
2)设计检测信号,验证FFT算法的正确性及FFT的部分性质;
3)运用FFT完成IFFT计算;
2、单路,多路模数转换(AD)
1)回顾CCS的基本操作流程,尤其是开发环境的使用;
2)参考实验指导和示例工程掌握5509芯片A/D的C语言基本控制流程;
3)仔细阅读工程的源程序,做好注释,为后期开发做好系统采集前端设计的准备;
3、系统集成,实现硬件频谱分析
1)整合前两个工程,实现连续信号的频谱分析工程的构建;
2)参考A/D转换示例和DSP系统功能自检示例完成硬件连接,并测试开发系统运行效果;
3)基于现有系统,对于实时频谱分析给出进一步开发设计和系统改良方案。
四、课程设计原理
1.(软仿真)先利用sin函数验证FFT的正确性
2.(硬仿真)将信号模拟信号经过AD采样后,转为离散的数字信号,将这些信号存储进缓冲区,然后读出缓冲区数据,经过变址运算后做蝶形运算,得到的数据进行IFFT运算,将运算后的图与开始的输入信号做对比。
原理流程图:
五、主要函数代码及流程分析:
main函数
#include"myapp.h"
#include"ICETEK-VC5509-EDU.h"
#include"scancode.h"
#include"FFT.h"
voidInitADC();
voidwait(unsignedintcycles);
voidEnableAPLL();
structcompxw[FFT_N];
floatm[FFT_N];
floatn[FFT_N];
unsignedintnADC0[FFT_N],nADC1[FFT_N];
//floatnADC0[256],nADC1[256];
floatre[FFT_N],im[FFT_N];
main()
{
inti;
unsignedintuWork;
EnableAPLL();
SDRAM_init();
InitADC();
PLL_Init(132);
while
(1)
{
for(i=0;i{
ADCCTL=0x8000;//启动AD转换,通道0
do
{
uWork=ADCDATA;//ADCDATA见ICETEK-VC5509-EDU.h
}while(uWork&0x8000);
nADC0[i]=uWork&0x0fff;//通道0信号采集
}
for(i=0;i{w[i].real=nADC0[i];//将输入信号的实部赋值送w[i]
w[i].imag=0;
}
FFT(w,FFT_N);//调用FFT对w做FFT
for(i=0;i<256;i++)
{m[i]=w[i].real;
n[i]=w[i].imag;
}
IFFT(w,FFT_N)//调用IFFT对w做IFFT
for(i=0;i<256;i++)
{re[i]=w[i].real;
im[i]=w[i].imag;
}
for(i=0;i{
ADCCTL=0x9000;//启动AD转换,通道1
do
{
uWork=ADCDATA;
}while(uWork&0x8000);
nADC1[i]=uWork&0x0fff;//通道1信号采集
}
asm("nop");//breakpoint
}
}
voidInitADC()
{
ADCCLKCTL=0x23;//4MHzADCLK
ADCCLKDIV=0x4f00;
}
voidwait(unsignedintcycles)
{
inti;
for(i=0;i}
voidEnableAPLL()
{
/*EnusreDPLLisrunning*/
*(ioportvolatileunsignedshort*)0x1f00=4;
wait(25);
*(ioportvolatileunsignedshort*)0x1f00=0;
//MULITPLY
*(ioportvolatileunsignedshort*)0x1f00=0x3000;
//COUNT
*(ioportvolatileunsignedshort*)0x1f00|=0x4F8;
wait(25);
//*(ioportvolatileunsignedshort*)0x1f00|=0x800
//MODE
*(ioportvolatileunsignedshort*)0x1f00|=2;
wait(30000);
//APLLSelect
*(ioportvolatileunsignedshort*)0x1e80=1;
//DELAY
wait(60000);
}
Main函数流程图:
FFT主程序:
#include
structcompx{floatreal;floatimag;}/*定义一个复数结构
structcompxs[257];/*FFT输入,输出均从s[1]开始
structcompxEE(structcompx,structcompx);
voidFFT(structcompx*,int)
structcompxEE(structcompxb1,structcompxb2)
{structcompxb3;
b3.real=b1.real*b2.real-b1.imag*b2.imag;
b3.imag=b1.real*b2.imag+b1.imag*b2.real;
return(b3);
}
/*输入xin的实部,虚部,输出:
xin(实部,虚部)N为FFT点数
voidFFT(structcompx*xin,N)
{intf,m,nv2,nm1,i,k,j=1,l;
intle,lei,ip;
floatpi,x,y;
structcompxv,w,t;
nv2=N/2;
f=N;
for(m=1;(f=f/2)!
=1;m++){;}/*求N为2的多少次幂放入m
nm1=N-1;
/*变变址运算,实现数据运算前的位倒序*/
for(i=1;i<=nm1;i++)
{if(ik=nv2;/*求j的下一个倒位序*/
while(k{j=j-k;k=k/2;}/*k/2,比较次高位,以此类推,逐个比较,直到某个位为0*/
j=j+k;}
/*FFT*/
for(l=1;l{le=pow(2,l);
lei=le/2;
pi=3.14159265;
v.real=1.0;v.imag=0.0;
w.real=cos(pi/lei);w.imag=-sin(pi/lei);
for(j=1;j<=lei;i++)//控制计算不同种蝶形结,即计算系数不同的蝶形结{for(i=j;i<=N;i=i+le){ip=i+lei;//控制计算同种蝶形结运算,即计算系数相同蝶形结
t=EE(xin[ip],v);
xin[ip].real=xin[i].real-t.real;
xin[ip].imag=xin[i].imag-t.imag;
xin[i].real=xin[i].real+t.real;
xin[i].imag=xin[i].imag+t.imag;}
v=EE(v,w);}
}
}
}
FFT流程图:
六、课程设计结果
1、输入sin信号
经fft变换后的频域实部虚部
2、输入三角波信号
经fft变换后的频域实部虚部
3.输入方波信号
经fft变换后的频域实部虚部
七、实验心得
通过一个半星期的DSP课程设计使我学到了好多课本上学不到的东西,增强了自己动手能力,并且复习了大一大二所学习的C语言能力。
对于FFT的算法的C语言实现,书上有部分语法的错误,比如:
第七行语句后面少一个分号,FFT函数中把L写成1等错误。
一开始对CCS开发环境不熟悉,在调试的时候,经常的会用到图形的输出,对于图片的属性设置很不熟悉,一开始感觉很不习惯,因为图太多加上对于程序总体把握的不准,经常搞出来不需要的图。
后来在同学的指导下才有所了解。
在使用硬件进行调试的时候,由于电脑和硬件的不稳定,经常出错,一开始不了解,出错了就只能通过重启来解决,浪费了大量时间。
后来才知道通过复位硬件也能解决。
由于时间有限,总体完成的不大满意,直到最后FFT算法还是有些问题,图形还是没做到实时性,不能使图形能实时的改变。
最后感谢周老师一个学期的悉心指导,本次课设使我们更加深入的了解DPS这门学科,为我们以后可能走上的研发调试工作提供了宝贵的经验。