文档视界 最新最全的文档下载
当前位置:文档视界 › 数字信号处理实验指导书

数字信号处理实验指导书

数字信号处理实验指导书
数字信号处理实验指导书

实验一 离散傅立叶变换

一、 实验目的

1. 在理论学习的基础上,通过本实验,加深对离散傅立叶变换(DFT )的理解。

2. 以正弦信号为例,学习和掌握利用离散傅立叶变换(DFT )分析信号频谱的方法。

3. 了解应用DFT 进行信号频谱分析过程中可能出现的问题,以便在实际中正确应用DFT 。

4. 学习和熟悉在计算机上作图显示和研究信号的离散频谱

二、实验原理与方法

在各种信号序列中,有限长序列的数字信号处理占有很重要地位,对有限长序列,我们可以使用离散傅立叶变换(DFT ), 这一变换不但可以很好地反映序列的频谱特性,而且易于用快速算法在计算机上实现,当序列x (n )的长度为N 时,它的DFT 定义为:

X (k )= N j N N n kn N e W W n x π210,)(--==∑ 反变换为:

x (n )=101N X k W N

kn k N ()-=-∑ 有限长序列的DFT 是其Z 变换在单位圆上的等距采样,或者说是序列傅立叶变换的等距采样,因此可以用于序列的谱分析。

DFT 要求被分析序列的长度为有限长,对无限长和很长的序列则需要截取。截取的结果使得信号的频谱分析出现频率泄漏。本实验分析的周期性信号,对周期信号,当截取的序列长度是信号周期的整数倍的时候,DFT 分析的频率离散点恰好采在周期信号的谐波分量和其它零值频率点上,能正确反映信号的频谱。当截取的序列长度不为信号周期的整数倍时,DFT 分析的结果就会有频率泄漏的反映。

三、实验内容

1. 设计说明

编制程序用DFT 分析正弦信号的频谱。具体包括以下几部分

(1)编程产生正弦抽样输入信号

x(t) = sin(Ωt) = sin(2πf t)

x(n) = x(nT) = sin(2πf n T)

正弦信号的频率f 、取样点数N 和取样间隔T 通过人机对话的方式由键盘

输入,以便调整。

(2)编程实现DFT 的运算

DFT 的计算公式为

∑∑∑-=-=-=--==10101

0)2sin()()2cos()()()(2N n N n N n nk j nk N n x j nk N n x e

n x k X N πππ )()(k jX k X i r +=

(3)计算DFT 的幅度

22)()(|)(|k X k X k X i r +=

(4)作图画出DFT 的幅度谱线。

2.实验步骤

将编制的程序输入计算机,调试运行正确后,进行以下实验。

(1)分别在下列几种情况下,输入正弦信号的频率f 、采样点数N 和采样周期T ,观察和研究DFT 的结果,并记录谱线的大体形状。

(a ) f = 50 Hz ,N = 32,T = 0.000625 s

(b ) f = 50 Hz ,N = 32,T = 0.005 s

(c ) f = 50 Hz ,N = 32,T = 0.004 s

(d ) f = 150 Hz ,N = 32,T = 0.000625 s

(2)修改程序,将输入信号改变成50 Hz 和150 Hz 两个正弦信号分量的迭加,并令50 Hz 分量的幅度为2,150 Hz 分量的幅度为1。即

x(n) = 2 sin(2π50 n T) + sin(2π150 n T)

取N = 32,分别在T = 0.000625 s 、T = 0.0025 s 和T = 0.002 s 情况下

进行DFT分析,观察和记录结果。

(3)有余力的同学还可以将输入信号改成50Hz的周期性方波,再对其进行DFT 分析。

四、C语言参考程序

/* 用DFT分析正弦信号频谱的C语言程序 */

#include

#include

#include

#include

#define PI 3.1415926

float x[1024],y[1024], w[1024];

void draw(int);

void axis(int,int);

main()

{

int N,f,n,k;

float T,r,i,c;

/* 键盘输入f、N、T */

printf("The frequency of the Sine wave f=");

scanf("%d",&f);

printf("The number of samples N=");

scanf("%d",&N);

printf("The sampling period T=");

scanf("%f",&T);

c=2*PI/N;

/* 产生正弦抽样信号 */

for(n=0;n

x[n]=sin(2*PI*f*n*T);

}

/* 计算DFT */

for(k=0;k

r=i=0.0;

for(n=0;n

r=r+x[n]*cos(c*n*k);

i=i+x[n]*sin(c*n*k);

}

y[k]=r;

w[k]=i;

}

/* 计算DFT的幅度 */

for(k=0;k

w[k]=sqrt(y[k]*y[k]+w[k]*w[k]);

}

/* 画频谱图 */

draw(N);

getch();

closegraph();

}

void draw(int N) /* 作图 */

{

int k,driver,mode,step,x,y;

driver=VGA;

mode=VGAHI;

step=512/N;

x=64;

y=400;

registerbgidriver(driver);

initgraph(&driver,&mode,"c:\\tc");

/* 绘制坐标及刻度 */

axis(x,y);

outtextxy((x+step+546),y+8,"k");

outtextxy((x+step-8),y-290,"X(k)");

outtextxy((x+step-8),y-234,"32");

outtextxy((x+step-8),y-121,"16");

outtextxy((x+step-19),y+8,

"0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1"); /* 绘制频谱图 */

for(k=0;k

line(x,y,x,(y-floor(w[k]*7)));

x+=step;

}

}

void axis(int x,int y) /* 绘制横轴与纵轴 */

{

line(10,y,630,y);

line(610,(y-4),630,y);

line(610,(y+4),630,y);

line(x,(y+20),x,(y-280));

line((x-4),(y-260),64,120);

line((x+4),(y-260),64,120);

}

五、实验报告要求

(1)给出几种情况下DFT分析的结果,绘制相应的谱线。(2)对每种情况的结果进行分析,从理论上加以说明。(3)通过本实验,谈谈你对DFT的进一步认识。

实验二快速傅立叶变换

一、实验目的

1.学习和掌握快速傅立叶变换(FFT)的实现过程和编程技术

2.运用FFT分析正弦信号的频谱

3.测试FFT的运算时间,比较FFT与DFT的运算速度,获得对 FFT“快速”

的感性认识。

4.锻炼和提高数字信号处理的程序设计和调试能力。

二、实验原理与方法

FFT并不是与DFT不同的另一种变换,而是为了减少DFT运算次数的一种快速算法。它是对DFT变换式进行一次次分解,使其成为若干小点数的组合,从而减少运算量。常用的FFT是以2为基数的,其长度N=2M。它的效率高,程序简单,使用非常方便,当要变换的序列长度不等于2的整数次方时,为了使用以2为基数的FFT,可以用末尾补零的方法,使其长度延长至2的整数次方。

本实验运用时间抽取基2 FFT,其原理、信号流图和运算过程可参阅课堂笔记、教材和其它教科书。FFT的实现要比DFT复杂,通常采用三个嵌套循环来实现。最外面的循环是分级循环,N=2M点的FFT分为M级计算。中间一层是分组循环,一级内蝶形系数W k相同的蝶形构成一组。最内层为蝶形计算的循环,一组内不同输入数据的蝶形逐个计算。编程时要注意各级蝶形组之间的间隔、组内蝶形之间间隔、以及系数W k变化。有不少书中有FFT程序可供参考,但要注意理解和弄懂,不可一味照搬,要尽量自己去编。

三、实验内容

1.设计说明

编制时间抽取基2 FFT程序计算前面DFT程序分析过的正弦信号,与DFT 计算的结果进行比较,以验证所编程序的正确性。

FFT为复数运算,若用实数运算来实现,需要设置两个数组来存放输入输出数据。其中一个用于存放数据的实部,另一个存放数据的虚部。正弦输入信号为实数,则令其虚部为零。同样,碟形运算也要化成实数来进行,分别算出实部和虚部。当然也可以直接用复数数组和语句实现。

程序设计的难点和重点在于要合理安排和正确设置碟形运算的分级循环、

k的变化以及各循环变量的级内分组循环和组内分碟形循环。要注意乘法系数W

N

变化和调整。

程序中,在进行FFT计算之前,先要将输入数据排列成二进制倒序的形式,这可通过将有关数据相互换位来实现。

正弦抽样信号的产生和输出频谱图的绘制与前面的DFT程序相同。

2.实验步骤

(1)将编制的程序输入计算机,调试、运行正确。即输入实验一中的1~2组数

据,看FFT输出谱线的结果是否与前面DFT的结果一致。

(2)在不同的FFT长度下(可分别令N=64,128,256,512,1024),运行FFT 程序,观察、比较和记录运行时间。

由于现在计算机的运算速度很快,计算一次FFT的时间很短(在ms数量级),不便观察和记录。可在程序中添置循环语句,让其重复计算FFT许多次(可重复100次、1000次或更多,视情况而定),使总的运算时间达到数秒或数十秒钟,从而可以通过人工来观察和记录。

此时注意,为了防止FFT多次循环计算,使输入输出数据越来越大而发生溢出,可令输入数据全部为零。这样,FFT的运算量保持不变,但输入输出始终为零,不会因多次循环而发生溢出。

在观测FFT的运算时间时,作图部分的语句不要运行(一方面,它不应该计入FFT或DFT的运算时间。另一方面,当N较大时,原有程序中的作图语句会出错),可将其注释掉。

测量FFT运行时间的一个更好、更精确的方法是在程序中调用读取计算机时钟的函数。TURBO C中提供多种读取计算机时间的方法和函数,一种比较简单的方法是用

相关文档