江苏大学 dsp课程设计

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

JIANGSU UNIVERSITY
本科生课程设计DSP课程设计实验报告
基于ICETEK5509实验箱和基2FFT
算法的频谱分析
学院名称:计算机科学与通信工程学院
专业班级:通信工程
学生姓名:
指导教师姓名:
指导教师职称:
年月
一、设计目的与意义
1、本课程设计与理论课、实验课一起构成《DSP芯片原理与应用》完整课程
体系;
2、针对理论课、实验课中无时间和不方便提及内容和需强调重点进行补充与
完善;
3、以原理算法的实现与验证体会DSP技术的系统性,并加深基本原理的体会。

二、设计要求
1、系统设计要求:
⑴.设计一个以ICETEK5509为硬件主体,FFT为核心算法的频谱分析系统
方案;
⑵.用C语言编写系统软件的核心部分,熟悉CCS调试环境的使用方法,
在CCS IDE中仿真实现方案功能;
⑶.在实验箱上由硬件实现频谱分析。

2、具体要求:
⑴.FFT算法C语言实现与验证
1) 参考教材14.3节FFT核心算法在CCS软件仿真环境中建立FFT工
程:添加main()函数,更改教材中个别语法错误,添加相应的库文
件,建立正确的FFT工程;
2) 设计检测信号,验证FFT算法的正确性及FFT的部分性质;
3) 运用FFT完成IFFT的计算。

⑵.单路、多路数模转换(A/D)
1) 回顾CCS的基本操作流程,尤其是开发环境的使用;
2) 参考实验指导和示例工程掌握5509芯片A/D的C语言基本控制流
程;
3) 仔细阅读工程的源程序,做好注释,为后期开发做好系统采集前端
设计的准备。

⑶.系统集成,实现硬件频谱分析
1) 整合前两个工程,实现连续信号的频谱分析工程的构建;
2) 参考A/D 转换示例和DSP 系统功能自检示例完成硬件连接,并测试 开发系统运行效果;
3) 基于现有系统,对于实时频谱分析给出进一步开发设计和系统改良 方案。

三、课程设计原理 1、DSP 应用系统构成:
注:一般的输入信号首先进行带限滤波和抽样,然后进行模数(A/D )转换,将信号变成数字比特流。

根据奈奎斯特抽样定理,对低通信号模拟,为保持信号的不丢失,抽样频率必须至少是输入带限信号的最高频率的2倍,工程上为带限信号最高频率的3-5倍。

2、快速离散傅里叶变换(FFT )的基本原理: 频谱分析系统
FFT 是一种快速有效地计算离散傅里叶变换(DFT )的方法。

它是根据离散傅
里叶变换的奇、偶、虚、实等特性,对离散傅里叶变换的算法进行改进获得的。

因为需要N 次复数乘法和N-1次复数加法,所以计算全部X(k)01k N ≤≤-(),共需要2N 次复数乘法和N(N-1)次复数加法。

实现一次复数乘法需要四次实数乘法和两次实数加法,一次复数加法需要两次实数加法,因此直接计算全部X(k)共需要42N 次实数乘法和2N(2N-1)次实数加法。

为减少运算量,提高运算速度,就必须改进算法。

FFT 算法就是不断地把长序列的DFT 分解成几个短序列的DFT ,并利用m
N W 的
周期性和对称性来减少DFT 的运算次数。

nk
N
W 具有以下固有特性: (1)nk
N W 的周期性:()(N nk n N k n k N N N W W W ++==)
(2)nk
N W 的对称性:()nk nk n n N k N N N W W W --=
=() (3)nk N W 的可约性:/,n n
N N n N Nn W W W W == 另外,/2(/2)1,N k N k
N N N W W W +=-=-。

利用nk
N W 的上述特性,将x(n)或X(k)序列按一定规律分解成短序列进行运算,
这样可以避免大量的重复运算,提高计算DFT 的运算速度。

算法形式有很多种,但基本上可以分为两大类,即按时间抽取(Decimation In Time ,DIT)FFT 算法和按频率抽取(Decimation In Frequency ,DIF)FFT 算法。

N=8的按时间抽取FFT
N=8的按频率抽取FFT
2.1实数序列的FFT :
反FFT 运算可以表示为:
1
1
x(n)=
(),0,1,2,,1N nk N
k X k W
n N N
--==⋅⋅⋅-∑ .2.8(4)
式中,X()k 是时域信号x()n 的傅里叶变换。

比较.1.2(4)和.2.8(4)可以看出,通过下列修改,我们可以用FFT 算法来实现反FFT: ⑴增加一个归一化因子1/N ;
⑵将nk N W 用其复共轭-nk
N W 代替。

由于第二点需要修改符号,因此FFT 程序还不能不加修改的来计算反FFT 。

因为
10
1x(n)=[()]N nk N k X k W N -**
=∑
1
=
{[()]}FFT X k N
** .2.9(4) 可见,求X()k 的反FFT 可以分为以下三个步骤:
⑴取X()k 的共轭,得X ()k *; ⑵求X ()k *的FFT,得Nx ()n *;
⑶取x ()n *的共轭,并除以N ,即得x()n 。

采用这种方法可以完全不用修改FFT 程序就可以计算反FFT 。

3、单路、多路模数转换实验原理(AD)
⑴ TMS320VC5509A 模数转换模块特性:
—带内置采样和保持的10位模数转换模块ADC,最小转换时间为500ns, 最大采样率为21.5KHz 。

—2个模拟输入通道(AIN0-AIN1)。

—采样和保持获取时间窗口有单独的预定标控制。

⑵ 模数转换工作过程:
—模数转换模块接到启动转换模块后,开始转换第一通道的数据。

—经过一个采样时间的延迟后,将采样结果放入转换结果寄存器保存。

—转换结束,设置标志。

—等待下一个启动信号。

⑶模数转换的程序控制:
模数转换相对于计算机来说是一个较为缓慢的过程。

一般采用中断方式启动转换或保存结果,这样在CPU忙于其它工作时可以少占用处理
时间。

设计转换程序应首先考虑处理过程如何与模数转换的时间相匹配,根据实际需要选择适当的触发转换手段,也要能及时地保存结果。

由于TMS320VC5509A DSP芯片内的A/D转换精度是10位,转换结果的低10位为所需数值,所以在保留时应注意将结果的高6位去除,取出
低10位有效数字。

⑷实验程序流程图:
实验程序流程图
四.实验程序和流程图:
1、FFT
⑴FFT程序:
#include <math.h>
struct compx { float real,imag;}; //定义一个复数结构
struct compx s[257]; //FFT输入和输出:均从s[1]开始存放struct compx EE(struct compx ,struct compx ); //定义复数相乘结构
void FFT(struct compx *, int ); //FFT函数预定义
#define pi 3.14159265
struct compx EE(struct compx b1,struct compx b2) //两个复数的相乘--b1*b2 {struct compx b3; //定义相乘的结果b3
b3.real=b1.real*b2.real-b1.imag*b2.imag;
b3.imag=b1.real*b2.imag+b1.imag*b2.real;
return(b3); } //返回相乘结果b3
/*输入:xin(实部,虚部), 输出:xin(实部,虚部), N:FFT点数*/
void FFT(struct compx *xin, int N)
{ int f,m,nv2,nm1,i,k,j=1,l;
struct compx v,w,t; //v为蝶形因子,w为中间变量nv2=N/2;
f=N;
for (m=1;(f=f/2)!=1;m++) {;} //计算蝶形运算的级数m=3,nm1=N-1;
/*变址运算*/
for (i=1;i<=nm1;i++) //实现位反转
{ if(i<j)
{ t=xin[j]; xin[j]=xin[i];xin[i]=t; }
k=nv2;
while(k<j) {j=j-k;k=k/2;}
j=j+k; }
/*fft*/
{int le,lei,ip;
for (l=1;l<=m;l++)
{le=pow(2,l);
lei=le/2;
v.real=1.0;v.imag =0.0; //第一级蝶形运算的运算因子
w.real =cos(pi/lei);w.imag =-sin(pi/lei); //用于改变蝶形运算因子中间变量for(j=1;j<=lei;j++) // 改变第二,三蝶形运算的运算因子{for(i=j;i<=N;i=i+le) //循环N/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);
}}}
return;
}
/*****************main programe********************/
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
float result[257];
float input[257];
struct compx s[257];
int Num=256 ;
const float pp=3.14159 ;
main()
{
int i=1 ;
for(;i<257;i++)
{
//s[i].real=sin(pi*i/128);
s[i].real=cos(2*pp*i/256);
s[i].imag=0 ;
input[i]=sin(2*pp*i/256);
}
FFT(s,Num);
for(i=1;i<257;i++)
{
result[i]=sqrt(pow(s[i].real,2)+pow(s[i].imag,2));
}

3、AD
⑴AD程序
#include "myapp.h"
#include "ICETEK-VC5509-EDU.h"
#include "scancode.h"
#include "fft.h"
#include "math.h"
struct compx s0[257],s1[257];
float input0[256],input1[256],output0[256],output1[256];
#define pi 3.14159265
void InitADC();
void wait( unsigned int cycles );
void EnableAPLL( );
unsigned int nADC0[256],nADC1[256];
main()
{ int i;
unsigned int uWork;
EnableAPLL();
SDRAM_init();
InitADC();
PLL_Init(132);
while ( 1 )
{ for ( i=0;i<256;i++ )
{ ADCCTL=0x8000; // 启动AD转换,通道0
do{uWork=ADCDATA; } //ADCDATA见ICETEK-VC5509-EDU.h
while ( uWork&0x8000 );
nADC0[i]=uWork&0x0fff; //0xfff→0x3ff 取后十位,前两位一直为0
s0[i+1].real=nADC0[i]; //实部为nADC0中的值
input0[i]= s0[i+1].real;
s0[i+1].imag=0; //虚部为0
}
for ( i=0;i<256;i++ )
{ ADCCTL=0x9000; // 启动AD转换,通道1
do{uWork=ADCDATA;} //ADCDATA见ICETEK-VC5509-EDU.h
while ( uWork&0x8000 );
nADC1[i]=uWork&0x0fff;//0xfff→0x3ff 取后十位,前两位一直为0
s1[i+1].real=nADC1[i]; //实部为nADC1中的值
input1[i]= s1[i+1].real;
s1[i+1].imag=0;//虚部为0
}
FFT(s0,256); //调用FFT函数对s0进行FFT变换
FFT(s1,256); //调用FFT函数对s1进行FFT变换
for(i=0;i<256;i++)
{ output0[i]=sqrt(pow(s0[i+1].real,2)+pow(s0[i+1].imag,2)); //取模
output1[i]=sqrt(pow(s1[i+1].real,2)+pow(s1[i+1].imag,2));}
asm( " nop"); // break point
}
}
void InitADC()
{
ADCCLKCTL=0x23; // 4MHz ADCLK 4*(35+1)=144MHz
ADCCLKDIV=0x4f00;
}
void wait( unsigned int cycles )
{ int i;
for ( i = 0 ; i < cycles ; i++ ){ }}
void EnableAPLL( )
{ /* Enusre DPLL is running */
*( ioport volatile unsigned short* )0x1f00 = 4;
wait( 25 );
*( ioport volatile unsigned short* )0x1f00 = 0;
// MULITPLY
*( ioport volatile unsigned short* )0x1f00 = 0x3000;
// COUNT
*( ioport volatile unsigned short* )0x1f00 |= 0x4F8;
wait( 25 );
//*( ioport volatile unsigned short* )0x1f00 |= 0x800 // MODE
*( ioport volatile unsigned short* )0x1f00 |= 2;
wait( 30000 );
// APLL Select
*( ioport volatile unsigned short* )0x1e80 = 1;
// DELAY
wait( 60000 );
}
⑵AD流程图
图5-2 AD流程图
五、实验步骤及结果分析
实验步骤及结果分析
1、FFT验证的步骤和分析:
⑴实验步骤:
参考教材中的FFT核心算法在CCS软件仿真中建立FFT工程:
首先更改FFT算法中的个别语法错误,初步理解程序,其次编写main()函数使系统能够找到程序入口地址,由于正余弦信号的频谱为脉冲信号,因此这里采用正余弦及其线性组合作为检测信号,编写检测信号程序时,应注意将采样点放入结构体数组s[257]中。

然后添加rts55.lib库文件到工程中,编译、下载,用view graph Tim e/Frequency…观察波形,设置观察窗口为:
⑵实验结果截图:
检测信号为input[i]=sin(2*pp*(i-1)/256)
检测信号input[i]=cos(2*pp*(i-1/)256)
检测信号为直流信号Input[i]=1
检测信号input[i]=sin(10*2*pp*(i-1)/256)
input[i]=0.5+sin(10*2*pp*i/256)+cos(50*2*pp*i/256)
⑶实验结果分析:
1) 信号中有直流分量,有正弦信号和余弦信号,但在时域波形中得
不出信号的组成如何;
2)在0频时有直流分量;
3)正余弦信号频谱实部大小相等关于中间值(129,0)对称,虚部大
小相等方向相反,关于中间值(129,0)对称,因此验证了FFT算
法的正确性;
4)换个角度思考,可以利用此算法来验证奈奎斯特抽样定理,正余
弦时域中任意线性组合不影响频谱分布,以及验证FFT的栅栏效
应,只能看到整数倍频的点等。

2、IFFT验证的步骤和分析:
⑴实验结果截图:
1) 输入信号为cos(2*pi*m/256)时
cos(2*pi*m/256)输入信号和IFFT后时域图
2) 输入信号为sin(2*pi*m/256)时
sin(2*pi*m/256)输入信号和IFFT后时域图
3) 输入信号为1+sin(2*pi*m/256)+cos(2*pi*m/256)时
1+sin(2*pi*m/256)+cos(2*pi*m/256)输入信号和IFFT后时域图
3、两通道模数转换(A/D)在开发环境中的调试
⑴通道波形的产生
根据实验指导书中的操作步骤调试出两通道相同的正弦波,使图像在CCS界面中动态变化,调节实验板上的频率、波形控制按钮,图形界面输出相应的波形,图6-3-1为0通道在10KHZ—100KHZ、1通道在10—100HZ 事的正弦波:
4.两个工程整合后:
六、课程设计心得
本次DSP课程设计针对理论课、实验课中无时间和不方便提及内容和需强调重点进行补充与完善,以原理算法的实现与验证体会DSP技术的系统性,并加深了我对基本原理的体会。

在这几天中,我学到了如下几点:
⑴通过对FFT算法进行分析研究,从基础深入研究和学习,掌握FFT
算法的关键;
⑵通过对DSP芯片工作原理以及开发环境的回顾,在DSP芯片上实现对信
号的实时频谱分析;
⑶这次课程设计,虽然不能做到完全理解掌握,但依然让我加深了对各门专
业课之间的联系;
⑷通过与同组成员的互相沟通,不仅使各自的知识得到了扩充,而且从中得
到了很多的启示,增强了团队合作能力;。

相关文档
最新文档