DSP课程设计报告_自动化0804_姚笑菲

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

DSP课程设计实验报告语音噪声滤波
院(系):电子信息工程学院
班级:自动化0804
姓名:姚笑菲
学号:08212116
指导教师:杨恒
目录
一、实验背景............................................................. 错误!未定义书签。

二、设计要求 (3)
三、设计思路 (3)
四、算法原理 (4)
1、直接存储器访问DMA (4)
2、A/D和D/A转换器 (6)
3、FIR滤波器算法 (6)
4、LMS算法 (7)
5、利用DSP产生回波 (8)
6、利用自适应滤波实现回波对消 .................... 错误!未定义书签。

五、用C语言实现LMS算法 ................................. 错误!未定义书签。

六、用MATLAB设计FIR滤波器.......................... 错误!未定义书签。

七、程序设计 (17)
1、主程序(firlab.c) (17)
2、中断服务程序(dma2isr.c) (22)
3、链接命令文件(5402a.cmd) (24)
4、中断向量表(c5402vec.asm) (26)
八、程序调试 (30)
九、结果分析 (31)
十、感想 (40)
一、实验背景
我们的日常生活中离不开语音通信,如接打电话、收听音乐等。

语音通信的过程主要分为三个部分,即发送部分——将音频信号转化为电信号,经发送端设备变换为适合传输的形式发送出去;传输部分——通过传输信道将电信号进行传输;接收部分——经接收端设备恢复出原来的语音信号,经耳机或者喇叭转换为接收者可以听到的声音信号。

但是由于环境的原因,我们采集到语音信号经常含有不同程度的噪声。

与语音通信系统的三个部分相对应,语音通信系统中的噪声一般也来自三个方面:一是信号发送端空间环境中的音频噪声信号经麦克风变换为电信号之后,与有用信号其同传递到接收端;二是信号接收端空间环境中的音频噪声对信号接收者的影响;三是信号处理设备产生的电噪声及传输信道中的电噪声。

当语音信号受到背景噪声干扰而使语音通信质量变得不可接受时,要对语音信号中的噪声进行滤除,也就是本次实验要完成的语音噪声滤波。

二、设计要求
1、基本部分:
(1)对DMA进行初始化;
(2)对A/D、D/A进行初始化;
(3)编写DMA中断服务程序和滤波算法程序,实现语音信号的实时滤波;
2、发挥部分:
(1)使用DSP产生带回波的语音信号;
(2)利用自适应滤波实现语音信号的回波对消。

(3)比较采用不同窗和阶数时滤波器的滤波效果;
(4)测试所设计滤波器的幅频特性和相频特性,并与MATLAB下的设计结果进行比较。

三、设计思路
首先利用DSP的DMA方式对外部含噪声的语音信号进行实时采集,语音信号先经过A/D转换为数字信号,利用MCBSP的接收寄存器接收数据。

编写滤波算法程序,或调用DSPLIB中的滤波函数,对信号进行滤波。

滤波后的数据利
用DMA 方式送到D/A 转换器转换为模拟信号。

设计流程框图如下:
加有噪声色语音信号由DSK 板的MIC 端口输入,经A/D 转换器转换为数字信号后到达DSP 的DMA 通道2,DSP 接收到信号后调用中断服务程序进行滤波,可选择滤波模式进行不同种类的滤波,滤波后的信号在CCS 上显示,或通过DMA 通道3将信号输出到D/A 转换器,转换为模拟信号后从SPEAKER 端口输出。

四、算法原理
1、直接存储器访问DMA
直接存储器访问(Direct Memory Access )是C54x DSP 非常重要的片上外设,DMA 控制器可以在不影响CPU 的情况下完成数据的传输,因此数据传输速度快,在要求信号实时采集和处理的系统中常采用DMA 方式进行信号采集和传输。

C5402有6个可独立编程的DMA 通道,每个DMA 通道受各自的5个16位寄存器控制:源地址寄存器DMSRC 、目的地址寄存器DMDST 、单元计数寄存器DMCTR 、同步事件和计数寄存器DMSFC 、发送模式控制寄存器DMMCR 。

目的地址寄存
主程序 中断服务程序
器DMDST规定DMA要传送数据目的地址和首地址。

单元计数寄存器DMCTR规定DMA传送数据的个数为DMCTR寄存器的值加1。

同步事件和帧计数寄存器DMSFC规定DMA传送数据的同步事件类型和传送一块数据所含帧信号的个数。

发送模式控制寄存器DMMCR规定DMA通道的传输模式,当DMA工作在自动初始化模式时,CPU在一个DMA事件完成后自动装载下一个DMA初始化设置并继续进行数据传送。

DINM位和IMOD位设置DMA中断产生方式。

CTMOD位设置发送计数模式控制,CTMOD位为0时,DMA工作在多帧模式,CTMOD位为1时,DMA工作在自动缓冲ABU模式。

SIND位和DIND位用来设置源地址和目的地址的自动调整方式。

此外,DMA的6个通道还受通道优先级和使能控制寄存器DMPREC控制。

本实验利用DMA通道2与MCBSP1通道结合来读取A/D转换器的数据,利用DMA通道3与MCBSP1通道结合来将处理后的数据发送至D/A转换器。

选择MCBSP1通道的接收寄存器DRR11(41H)为DMA传送数据的首地址,并选择DMA源地址工作在不调整方式,选择MCBSP1接收事件为DMA同步事件,以实现DMA和MCBSP的结合。

A/D转换器的数据按MCBSP1的设置被传送到DSP内部接收寄存器DRR11中,再由DMA通道2将DRR11中的数据读到指定数据存储区INP-BUFFER中完成数据采集。

DMA在传送外部来的数据时不会影响CPU的正常运行,当DMA通道2采集完一组数据后产生一个DMA中断事件中断CPU,来通知CPU对其进行相应的处理,此时DMA通道2可以按照设定继续采集下一组数据,实现了数据采集与CPU处理的并行操作。

当一组数据处理完成后,将数据存放在数据存储区OUT-BUFFER中,选择OUT-BUFFER为DMA通道3的首地址,并选择源工作地址工作在不调整方式。

选择MCBSP1通道的发送寄存器DXR11(43H)为DMA通道3传送数据的目的地址,并选择DMA源地址工作在不调整方式,选择MCBSP1接收事件为DMA同步事件,以实现DMA和MCBSP的结合。

在CCS集成开发环境中,与DMA相关的头文件有regs54xx.h和dma54xx.h。

在这两个头文件中,定义了DMA的寄存器资源、使用方法和DMA寄存器的地址和基本访问方式,以及寄存器的各个比特域和访问方法,因此需要进行C源程序的开始处包含这两个头文件。

输入信号经A/D转换后,利用DMA通道2
进行传输进入DSP处理,而滤波后的信号输出利用了DMA通道3进行传输进入D/A转换器等输出,因此需要对DMA通道2和通道3进行初始化配置。

详细的DMA初始化程序请见后面的程序清单。

2、A/D和D/A转换器
A/D模数转换器是将输入电压信号转换为输出的数字信号。

由于数字信号本身不具有实际意义,仅仅表示一个相对大小,所以任何一个模数转换器都需要一个参考模拟量作为转换的标准,而输出的数字量则表示输入信号相对于参考信号的大小。

A/D转换器能够将接收的语音信号(模拟信号)转化为数字信号,供CPU 进行处理。

D/A转换器是将数字信号转换为模拟信号的电路。

实现原理就是将输入的二进制代码按其权值的大小转换成相应的模拟量,然后将所有的模拟量相加,使其与数字量成正比。

D/A转换器能够将数字信号转换为语音信号送SPEAKER端口输出。

要使用A/D和D/A转换器,必须首先对A/D和D/A转换器进行初始化设置,即设置A/D转换器的工作模式(15+1bit模式,16bit模式)、输入增益(0dB,6dB,12dB)以及抽样频率(8000Hz,16000Hz)等。

3、FIR滤波器算法
数字滤波器原理一般具有如下差分方程:
y(n)=∑x(n-k)+ ∑y(n-k) (1)
式中x(n)为输人序列,y(n)为输出序列,和为滤波器系数,,N是滤波器阶数。

当所有的均为零时,则有
y(n)= ∑x(n-k) (2)
(2)式是FIR滤波器的差分方程,其一般形式为
y(n)= ∑h(k)x(n-k) (3)
对(3)式进行z变换,整理后可得FIR滤波器的传递函数:
H(z)= ∑h(k)(4)
FIR(Finite Impulse Response)滤波器,即有限长单位冲激响应滤波器,是指系统的单位脉冲响应h[k]仅在有限范围内有非零值的滤波器。

FIR数字滤波器的设计方法主要有窗函数法和频率抽样设计法,其中窗函数法是基本而有效的设计方法。

下面为FIR滤波器的算法实现方法。

FIR滤波为有限冲击响应滤波,其滤波结构是一个分节的延时线,每节的输出加权累加,得到滤波器的输出。

由前面的分析知,FIR滤波器数学上可表示为:
y(n)= ∑h(k)x(n-k) (5)
式(5)中x[n]为最近(t=nT)的输人信号,x[n-k]是延时了k个取样周期的输人信号,h[k]是第k个延时的加权值(即滤波器系数),可由MATLAB设计出来,y[n]是时刻t=nT时滤波器的输出信号,N是滤波器的阶数也称滤波器的抽头数,为实整数,且须满足N*t<1/,其中为采样频率。

因为该滤波器的冲激响应在N个周期后变为0也就是每次乘加运算都要用到之前N个数。

滤波器系数可通过MATLAB设计得到。

4、LMS算法
LMS(least-mean-square)算法,即最小均方算法,是由Widrow和Hof在1960年创建的,直到现在它还是应用最广泛的自适应滤波算法。

LMS算法是随机梯度算法族中的一员。

该算法在随机输入维纳滤波器递推计算中使用确定性梯度。

LMS算法的一个显著特点就是它的简单性。

此外,它不需要计算有关的相关函数,也不需要矩阵求逆运算。

事实上,正是因为LMS算法的简单性,使得它成为其他自适应滤波算法的参照标准。

这两个过程一起工作组成一个反馈环,如下图所示。

首先有一个横向滤波器(围绕它构造LMS算法),该部件的作用在于完成滤波过程。

其次,有一个对横向滤波器抽头权值进行自适应控制过程的算法。

横向滤波器各部分的细节如下图所示。

抽头输入u(k),u(k-1),……,u(k-M+1),其中M+1是延迟单元的个数,这些输入张成一个多维空间。

相应的(k), (k), ...,(k)为抽头权向量h(k)的元素。

通过LMS算法计算这个向量所得的值表示一个估计,当迭代次数趋于无穷时,该估计的期望值可能接近维纳最优解,在滤波过程中,期望响应d(k)与抽头输入向量z(k)一道参与处理。

在这种情况下,给定一个输入,横向滤波器产生一个输入,横向滤波器产生一个输出y(k)作为期望响应d(k)的估计。

因此,我们可把估计误差e(k)定义为期望响应与实际滤波器输出之差,估计误差e(k)与抽头输入向量z(k)都被加到自适应部分,因此围绕抽头权值的反馈环是闭环的。

5、利用DSP产生回波
在打电话的过程中,常常能听见自己说话的声音在话筒里重复,实际上就是自己的声音泄露到了接收系统中。

在一些特定的系统中出现这种现象将会对信
号的正常收发产生不利影响。

因此,回声在上述系统中会严重影响了通话的清晰度,多点回声甚至会引起通讯网之间声音的振荡。

可通过设置时间的延迟,将过去的信号衰减加到现在的信号上,以产生回波。

这次实验我们的回声信号定义为语音信号的延迟再进行适当的衰减。

即将麦
克输入的语音信号叠加上述麦克输入语音信号的延时衰减后的信号,用此混合信
号模拟真实的回波信号。

因此回声通道的传输函数为:
()M
=⨯
H z s z-
其中S为衰减,M为延迟点数。

听到的回波是混合信号,此时不仅能听到自己的声音,也能听到几个衰减后叠加的回声,该回声为近端输入的延迟和衰减。

回波产生程序如下:
while (!MCBSP_RRDY(HANDSET_CODEC)) {}; //codec句柄如未准备好
则等待
dk = *(volatile u16*)DRR1_ADDR(HANDSET_CODEC); //从ADC读数
bf[i]=dk; //放入缓冲区
if(i==10000)
i=0;
*(volatile u16*)DXR1_ADDR(HANDSET_CODEC) = dk+bf[i+1]/2; //延迟
+衰减
6、利用自适应滤波实现回波对消
声学回声消除的功能原理框图如下图所示:
其基本原理可概括为,自适应地合成回声,并从有回声干扰地信号中减去
该合成回声。

一般回声消除算法通过自适应滤波来完成,其基本原理如下图所示:
其中,远端信号x (k)通过回声信道h 产生回声y(k),近端信号d(k)是由回声y(k)和近端声音信号(可包含噪声信号)得到。

通过使用M 抽头的FIR 自适应滤波器^
h 来模拟回声信道h ,可以使所得y(k)通近回声信号,进而达到回声消除的目的由此可见,回声消除的关键是自适应地调整^
h 使其通近h ,可通过现有的各种自适应滤波算法实现。

这个实验采用的LMS 算法,即最小均方误差算法设计的自适应滤波器进行未知系统识别,以将回声信号滤除。

该自适应滤波器是FIR 横向滤波器,可以根据输出自动修改滤波器的权系数,从而逼近未知系统回声通道。

算法的实现基于TMS320C5402DSP 芯片和CCS 系统的C 语言。

远端的信号通过回声通道产生回声信号d(n),该信号一般为远端信号的衰减和延迟。

远端信号通过自适应滤波器产生回声预测信号y(n)。

在k 时刻,它们之差为剩余回声信号: k k k
e d y =-
用它来控制LMS 自适应滤波器的系数ω(n) (1)()2()
k n n e in n μ+=+⨯⨯ωω 其中μ为自适应步长因子,一般取0<μ<1,可视为常数,k 时刻滤波器的输出
为: 10y(n)=()()
N i w n in n i -=*-∑
以上三个方程是LMS 最小均方误差算法的核心方程,也是C 语言编程的依据。

LMS 的算法流程图如下:
五、用C 语言实现LMS 算法
由C 语言实现LMS 算法的C 语言程序如下所示:
double lms (double w[],double x[],double dk,double ek) //移植到CCS 中的lms 算法
{
s16 i;
double uek,yk; yk=0;
for(i=0;i<N;++i) { yk=yk+w[i]*x[i];
in (n )
1
()()
N i w n in n i -=*-∑k k k
e d y =-(1)()2()k n n e in n μ+=+⨯⨯ω
}
ek=dk-yk;
uek=2*mu*ek;
for(i=0;i<N;i++)
{
w[i]=w[i]+uek*x[i];
}
return(ek);
}
然而算法的效率与滤波器的长度有关,因此应当适当减小滤波器的长度;同时也应该适当的提高FIR滤波器的阶数。

同时替换原有的LMS算法的C语言实现程序,更换为CCS的diplib库中的函数short dlms(PARAM)取代自定的lms()函数,同时用dsplib库里的函数short fir(PARAM)产生回声通道的输出信号(也就是用预定阶数的FIR滤波器模拟回声通道),该输出信号作为自适应滤波器的理想输出信号,对之进行逼近进而得到预定结果。

Dsplib库中的dlsm函数和fir函数的子程序:
Dlsm.h的程序如下,路径:C:\ti\c5400\dsplib\EXAMPLES\DLMS
//*************************************************************** **************
// Filename: dlms_t.c
// Version: 0.01
// Description: test for dlms routine
//*************************************************************** **************
#include <math.h>
#include <tms320.h>
#include <dsplib.h>
#include "test.h"
short i;
short eflagr= PASS;
short eflagh= PASS;
void main(void)
{
/* clear */
for (i=0;i<NH;i++) h[i] =0; // clear coeff buffer (optional)
for (i=0;i<NX;i++) r[i] =0; // clear output buffer (optional)
for (i=0; i<NH; i++) dbuffer[i] = 0; // clear delay buffer (a must)
/* compute */
dlms(x,h,r,&dp,des,STEP, NH, NX);
/* test */
eflagr = test(r, rtest, NX, MAXERROR); // for r
eflagh = test(h, htest, NH, MAXERROR); // for h
if (eflagr != PASS)
{
exit(-1);
}
if (eflagh != PASS)
{
exit(-1);
}
return;
}
FIR.h的程序如下,路径:C:\ti\c5400\dsplib\EXAMPLES\FIR
//*************************************************************** **************
// Filename: fir_t.c
// Version: 0.01
// Description: test for fir routine
//*************************************************************** **************
#include <math.h>
#include <tms320.h>
#include <dsplib.h>
#include "test.h"
short i;
short eflag1= PASS;
short eflag2= PASS;
DATA *dbptr = &db[0];
void main(void)
{
/* 1. Test for single-buffer */
/* clear */
for (i=0; i<NX; i++) r[i] = 0; // clear output buffer (optional)
for (i=0; i<NH; i++) db[i] = 0; // clear delay buffer (a must)
/* compute */
fir(x, h, r, &dbptr, NH, NX);
/* test */
eflag1 = test (r, rtest, NX, MAXERROR);
/* 2. Tests for dual-buffer */
/* clear */
for (i=0; i<NX; i++) r[i] = 0; // clear output buffer (optional)
for (i=0; i<NH; i++) db[i] = 0; // clear delay buffer (a must)
dbptr = &db[0];
/* compute */
if (NX>=4)
{
fir(x, h, r, &dbptr, NH, NX/4);
fir(&x[NX/4], h, &r[NX/4], &dbptr, NH, NX/4);
fir(&x[2*NX/4], h, &r[2*NX/4], &dbptr, NH, NX/4);
fir(&x[3*NX/4], h, &r[3*NX/4], &dbptr, NH, NX/4);
}
/* test */
eflag2 = test (r, rtest, NX, MAXERROR);
if (eflag1 != PASS)
{
exit(-1);
}
if (eflag2 != PASS)
{
exit(-2);
}
return;
}
这两个函数是用C5000汇编语言编写的,具有很高的执行效率,使用这个函数可以大大提高运算速度,以解决用C语言编写的程序效率不能满足要求的问题。

下面以dlsm.h为例,其使用方法如下:
short oflag = dlms (DATA *x, DATA *h, DATA *r, DATA **d, DATA *des, DATA step, ushort nh, ushort nx)
其C子函数定义的各个变量的意义如下表所示:
注意:h和d的存储地址要求起点必须位于Kbit边界处,即起始地址值的最低有效位必须是0,必须在CMD文件中开辟对齐1K边界的空间,并且只能在头文件中进行段的配置。

否则编译无法通过。

同理,FIR.h的使用方法如下:
oflag = short fir (DATA *x, DATA *h, DATA *r, DATA **dbuffer, ushort nh,
ushort nx)
oflag 溢出错误标志,为1时在计算过程中发生了数据溢出;为0时无数据溢出。

x 输入信号数组
h FIR滤波器的系数矢量,也是要逼近的对象
r 输出数组
d 延迟缓冲区,用来存放上一时刻的输出数据
nx 向量x中的个数
nh 系数的个数
注意:h、d的地址要求同dlms()函数中的h、d参数。

DATA 为tms320.h中定义的short整型。

为了降低计算量,输入缓冲数组长度应该尽量小,取长度为LENGTH_IN=5。

采用数据压入方式,将最新的声音采样值存入数组x[0],然后将存储的数据从低位压入高位。

其实现程序update(DATA x[],DATA dk)如下:
void update(DA TA x[],DA TA dk) //dk为当前采样值
{
s16 j,k;
for(j=1;j<LENGTH_IN;++j)
{
k=LENGTH_IN-j;
x[k]=x[k-1]; //从低位压向高位
}
x[0]=dk; // 当前采样值存入最低位
}
六、用MATLAB设计FIR滤波器
用MATLAB设计FIR流程如下:
打开MATLAB,在命令窗中输入fdatool,打开滤波器设计与分析工具。

更改滤波器的各个参数值,因为语音信号的频率成分主要分布在300Hz到
3400Hz,所以我们只要设计300Hz到3400Hz的带通FIR滤波器就可以实现对语音信号中掺杂的噪声的滤除。

在FDA中选择带通FIR滤波器,阶数选择15,抽样频率选择16kHz,阻带截频分别为0.25 kHz和3.45 kHz,通带截频分别为0.3 kHz和3.4 kHz。

点击“Desgin filter” 完成滤波器设计,滤波器的波形如下图所示。

然后将设计好的结果导出为fir.h文件。

下面就是导出的fir.h文件。

/*
* Filter Design and Analysis Tool - Generated Filter Coefficients - C Source
* Generated by MATLAB - Signal Processing Toolbox
*/
/* General type conversion for MATLAB generated C-code */
#include "tmwtypes.h"
/*
* Expected path to tmwtypes.h
* C:\MATLAB6p5\extern\include\tmwtypes.h
*/
const int BL = 16;
const real64_T B[16] = {-1737, -22, 494, -1762, -4117, -2011, 5080, 11684, 11684, 5080, -2011, -4117, -1762, 494, -22, -1737};
七、程序设计
实验中用到的源程序有以下几个:
1.主程序(firlab.c)
/*****************************************************************************/ /* */
/* */
/* */
/* */ /*****************************************************************************/
#include <type.h>
#include <board.h>
#include <codec.h>
#include <dsplib.h>
#include <firlab.h>
#include <string.h>
#include <math.h>
void delay(s16 period);
extern void DMAC2ISR();
#define SS 16
/*****************************************************************************/ /* 全局变量*/
/*****************************************************************************/ HANDLE hHandset;
unsigned int dmsefc,dmmcr,dmctr,src_addr,dst_addr;
unsigned int dmpre,dmsrcp,dmdstp,dmidx0,dmidx1,dmfri0,dmfri1,dmgsa,dmgda,dmgcr,dmgfr; /*存放输入数据*/
#pragma DATA_SECTION(inp_buffer,"audio_buffer");
int inp_buffer[0x200];
/*存放输出数据*/
#pragma DATA_SECTION(out_buffer,"outt_buffer");
int out_buffer[0x200];
int out1_buffer[0x200];
/*存放滤波器系数*/
#pragma DATA_SECTION(coeffs,"coefficients");
/*低通滤波器*/
DA TA coeffs[16]={ 0, -113, 419, -878, 1031, 0, -3731, 19656, 19656,
-3731, 0, 1031, -878, 419, -113, 0};
/*高通滤波器*//*这里COEFF的数据类型曾经是int*/
/*带通滤波器*/
/*带阻滤波器*/
/*全通滤波器*/
/*存放延迟数据*/
#pragma DATA_SECTION(delaybuff,"delayb");
int delaybuff[16]={0};
int frame=0;
int flag=0;
int temp;
int currbuff=0;
int choose=1;
int *delayptr1= &(delaybuff[0]);
interrupt void DMAC2ISR();
DA TA y[SS];
double p,q,temp1;
u16 f[SS/2+1];
int iii,mm;
/*****************************************************************************/ /* MAIN */ /*****************************************************************************/
void main()
{
s16 cnt=2;
BSCR=0x8806;
XPC=0;
PMST=0xA0;
brd_set_cpu_freq(100);
TIMER_HALT(0);
brd_set_wait_states(7,7,9);
TIMER_RESET(0);
IMR=0;
/************************计算滤波器的
FFT******************************************/
cbrev(coeffs,y,SS/2);
rfft(y,SS,0);
/********求信号的幅度谱*************************/
f[0]=abs(y[0]);
f[SS/2]=abs(y[1]);
mm=1;
for(iii=2;iii<SS;iii=iii+2)
{
p=y[iii];
q=y[iii+1];
temp1=sqrt(p*p+q*q);//取幅度谱
f[mm]=temp1;
mm++;
}
/****************************************************************************** /
/*****************************************************************************/
if(brd_init_bios())
return;
while (cnt--)
{
brd_led_toggle(BRD_LED0);
delay(1000);
brd_led_toggle(BRD_LED1);
delay(1000);
brd_led_toggle(BRD_LED2);
delay(1000);
}
hHandset=codec_open(HANDSET_CODEC);
/*设置codec参数*/
codec_dac_mode(hHandset,CODEC_DAC_15BIT);
codec_adc_mode(hHandset,CODEC_ADC_15BIT);
codec_ain_gain(hHandset,CODEC_AIN_6dB);
codec_aout_gain(hHandset,CODEC_AOUT_MINUS_6dB);
codec_sample_rate(hHandset,SR_16000);
INTR_CLR_FLAG(DMAC2);
dma_reset_all();
/*初始化DMA2通道*/
dmsefc=((DSYNC_REVT1<<12));
dmmcr=((AUTOINIT_ENABLE<<15)|(DINM_ENABLE<<14)|(IMOD_HALFBLOCK<<1 3)|(CTMOD_DEC<<12)|
(INDEXMODE_NOMOD<<8)|(SPACE_DATA<<6)|(INDEXMODE_INC<<2)|(SPACE_DA TA));
dmmcr=0xe045;
dmctr= 0xFF;
src_addr=DRR1_ADDR(HANDSET_CODEC);
dst_addr=(unsigned int)&inp_buffer;
dma_init(DMA_CH2,dmsefc,dmmcr,dmctr,SPACE_DATA,src_addr,SPACE_DATA,dst_addr );
DMA_FRAMECOUNT(DMA_CH2,1);
dmgsa=src_addr;
dmgda=dst_addr;
dmgcr=0xFF;
dmgfr=1;
dmpre=((HIGH_PRIORITY<<10)|(INTSEL_01<<6));
dmsrcp=SPACE_DA TA;
dmdstp=SPACE_DA TA;
dmidx0=0;
dmidx1=0;
dmfri0=0;
dmfri1=0;
dma_global_init(dmpre,dmsrcp,dmdstp,dmidx0,dmidx1,dmfri0,dmfri1,dmgsa,dmgda,dmgcr, dmgfr);
DMA_ENABLE(DMA_CH2);
temp=*(volatile u16*)DRR1_ADDR(HANDSET_CODEC);
INTR_ENABLE(DMAC2);
INTR_GLOBAL_ENABLE;
for(;;);
}
void delay(s16 period)
{ int i,j;
for(i=0;i<period;i++)
{ for (j=0;j<period;j++);
}
}
2.中断服务程序(dma2isr.c)
#include<codec.h>
#include<firlab.h>
#include<stdio.h>
#include<stdlib.h>
extern void delay(s16 period);
extern unsigned int channel;
extern unsigned int dmsefc;
extern unsigned int dmmcr;
extern unsigned int dmctr;
extern unsigned int src_page;
extern unsigned int src_addr;
extern unsigned int dst_page;
extern unsigned int dst_addr;
extern int inp_buffer[0x200];
extern int out_buffer[0x200];
extern int coeffs[16];
extern int delaybuff[16];
extern int frame;
extern int flag;
extern int currbuff;
extern int *delayptr1;
extern int L=0;
extern int choose;
extern int out1_buffer[0x200];
void init_dma3(void)
{ while(DMPREC&0x0008){};
dmsefc=((DSYNC_REVT1<<12));
dmmcr=0x4141;
dmctr=0xFF;
src_addr=(unsigned int)&out_buffer+((unsigned int)frame*0x100);
dst_addr=DXR1_ADDR(HANDSET_CODEC);
dma_init(DMA_CH3,dmsefc,dmmcr,dmctr,SPACE_DATA,src_addr,SPACE_DATA,dst_addr );
DMA_FRAMECOUNT(DMA_CH3,0);
DMA_ENABLE(DMA_CH3);
}
interrupt void DMAC2ISR(void)
{
int *p_inp,*p_out;
int *p_out1;
if(choose==1)
{
p_inp=inp_buffer+frame*0x100;
p_out1=out1_buffer+frame*0x100;
p_out=out_buffer+frame*0x100;
fir(p_inp,coeffs,p_out1,&delayptr1,16,256);
dlms(p_inp,coeffs,p_out,&delayptr1,p_out1,327,16,256);
init_dma3();
frame^=1;
}
if (choose==0)
{
p_inp=inp_buffer+frame*0x100;
p_out=out_buffer+frame*0x100;
fir(p_inp,coeffs,p_out,&delayptr1,16,256);
init_dma3();
frame^=1;
}
}
3.链接命令文件(5402a.cmd)
MEMORY
{
PAGE 0:
VEC1: origin = 0080h, length = 0078h /* Internal Program RAM */
PRAM: origin = 2000h, length = 2000h /* Internal Program RAM */
VEC2: origin = 0xff80, length = 0x78
PAGE 1:
SCRATCH: origin = 0060h, length = 0020h /* Scratch Pad Data RAM */
DMARAM: origin = 0100h, length = 0400h /* DMA buffer */
STACK: origin = 0600h, length = 0400h
/* Stack Memory Space */
EXRAM: origin = 1100h, length = 0e00h /* External Data RAM */
}
/*****************************************************************************/ /* DSP Memory Allocation */ /*****************************************************************************/
SECTIONS
{
.cinit > PRAM PAGE 0
.text > PRAM PAGE 0
.vectors > VEC2 PAGE 0
.vecs > VEC1 PAGE 0
.stack > STACK PAGE 1
.trap > SCRATCH PAGE 1
.bss > EXRAM PAGE 1
.cio > EXRAM PAGE 1
.fifo > EXRAM PAGE 1
.sintab > EXRAM PAGE 1
audio_buffer > DMARAM PAGE 1
outt_buffer > DMARAM PAGE 1
.const > EXRAM PAGE 1
coefficients > EXRAM ,align (512)
delayb > EXRAM ,align (512)
}
4.中断向量表(c5402vec.asm)
*************************************************************************
* (C) Copyright Texas Instruments, Inc. 2000 *
*************************************************************************
* *
* MODULE NAME: C5402VEC.ASM * * *
* AUTHOR: C5000 Applications *
* *
* DESCRIPTION: TMS320VC5402 Interrupt Vector initialization table *
* *
* NOTE: If DSP/BIOS used you will have to initialize interrupt *
* vector table using the BIOS configuration tool *
* *
* *
* DA TE: 02/00 *
* *
*************************************************************************
.title "54xDSKPLUS Vector Table Initialization"
.ref _c_int00, _DMAC2ISR
.sect ".vecs"
RESET: BD _c_int00 ; RESET vector
NOP
NMI: BD NMI ; ~NMI
NOP
NOP
********************************************************************** * S/W Interrupts
********************************************************************** SINT17 BD SINT17
NOP
NOP
SINT18 BD SINT18
NOP
NOP
SINT19 BD SINT19
NOP
NOP
SINT20 BD SINT20
NOP
NOP
SINT21 BD SINT21
NOP
NOP
SINT22 BD SINT22
NOP
NOP
SINT23 BD SINT23
NOP
NOP
SINT24 BD SINT24
NOP
SINT25 BD SINT25
NOP
NOP
SINT26 BD SINT26
NOP
NOP
SINT27 BD SINT27
NOP
NOP
SINT28 BD SINT28
NOP
NOP
SINT29 BD SINT29
NOP
NOP
SINT30 BD SINT30
NOP
NOP
************************************************************************** * Rest of the Interrupts
**************************************************************************
INT0: BD INT0
NOP
NOP
INT1: BD INT1
NOP
INT2: BD INT2
NOP
NOP
TINT0: BD TINT0
NOP
NOP
BRINT0: BD BRINT0
NOP
NOP
BXINT0: BD BXINT0
NOP
NOP
DMAC0: BD DMAC0
NOP
NOP
TINT1: BD TINT1
NOP
NOP
INT3: BD INT3
NOP
NOP
HPINT: BD HPINT
NOP
NOP
DMAC2: BD _DMAC2ISR
NOP
NOP
DMAC3: BD DMAC3
NOP
NOP
DMAC4: BD DMAC4
NOP
NOP
DMAC5: BD DMAC5
NOP
NOP
八、程序调试
首先打开Setup CCS 2(’C5000),在Import Configuration对话框中先单击“Clear”按钮,选择正确的项目,单击“Import”按钮,然后单击“Save and Quit”按钮,保存设置并退出。

打开CCS界面,新建任务fir,并将源程序文件firlab.c、dma2isr.c和c5402vec.asm以及链接命令文件5402a.cmd添加到任务下,再将用到的头文件board.h、codec.h、firlab.h、type.h添加到该工程下,最后添加库文件54xdsp.lib、drv5402.lib、dsk5402.lib、rts.lib。

然后进行编译和链接,如下图所示:
编译无错误后,将生成firlab.out文件,这就是将要下载到DSK板上的文件。

将DSK板与计算机连接好,接通电源,在CCS中选择File中的Load Program,将firlab.out文件载入DSK板。

接好耳机和话筒,对着话筒讲话就可以从耳机中听到去噪后输出的语音信号。

九、结果分析
1、语音自适应滤波效果
(1)语音信号输入与输出的信号频域对比图
(2)语音信号输入与输出的信号时域对比图
(3)语音信号输入与输出的信号频域对比图
(4)语音信号输入与输出的信号频域对比图
结论:
由时域图可看出,经过自适应滤波后,输出信号的波形明显比输入信号平滑。

由频域波形可看出,高频的噪音在先经过带通滤波器后都先被滤掉了,输出信号只有语音频率带有幅值;
2、不同低通滤波器的对比
(1)FIR16阶hann窗
MATLAB设计结果:
h[k]参数
0, -41, 298, -761, 967, 0, -3696, 19616, 19616, -3696, 0, 967,
-761, 98, -41, 0
CCS中幅频特性:
(2) FIR32阶hann窗
MATLAB设计结果:
h[k]参数
0, -7, 18, 0, -83, 223, -341, 306, 0, -590, 1299, -1777, 1540, 0, -3993, 19789, 19789, -3993, 0, 1540, -1777, 1299, -590, 0, 306, -341, 223, -83, 0, 18, -7, 0
CCS中幅频特性
(3)FIR64阶hann窗
MATLAB设计结果:
h[k]参数
0, 1, -3, 5, 0, -14, 34, -47, 39, 0, -65 ,132, -161, 121, 0, -172, 328, -385, 278, 0,-376, 709, -827, 599, 0, -848, 1671, -2095, 1699, 0, -4064, 19828, 19828, -4064, 0, 1699, -2095, 1671, -848, 0, 599, -827, 709, -376, 0, 278, -385, 328, -172, 0, 121, -161, 132, -65, 0, 39, -47, 34, -14, 0, 5, -3, 1, 0
CCS中幅频特性:
(4)FIR 16阶blackman窗
MATLAB设计结果:
h[k]参数
0, -16, 139, -443, 690, 0, -3471, 19484, 19484, -3471, 0, 690, -443, 139, -16, 0
CCS中幅频特性
(5)FIR32阶blackman窗
MATLAB设计结果:
h[k]参数
0, -3, 7, 0, -38, 114, -194, 193, 0, -448, 1066, -1556, 1421, 0, -3935, 19756, 19756, -3935, 0, 1421, -1556, 1066, -448, 0, 193, -194, 114, -38, 0,7, -3, 0
CCS中幅频特性
(6)FIR16阶hamming窗
MATLAB设计结果:
h[k]参数
0, -113, 419, -878, 1031, 0, -3731, 19656, 19656, -3731, 0, 1031, -878, 419, -113, 0
CCS中幅频特性
(7)FIR32阶hamming窗
MATLAB设计结果:
h[k]参数
51, -61, 53, 0, -119, 280, -397, 339, 0, -617, 1338, -1809, 1555, 0, -3996, 19766, 19766, -3996, 0, 1555, -1809, 1338, -617, 0, 339, -397, 280, -119, 0, 53, -61, 51
CCS中幅频特性
(8)FIR 64阶hamming窗带通滤波器
MATLAB设计结果:
h[k]参数
-22, 46, 1, 35, -26, -85, 31, -38, 154, 69, -135, -5, -326, 196, 261, 58, 307, -798, -127, 0, 170, 1421, -734, -189, -1161, -1218, 2895, 69, 2772, -2419, -10979, 9792, 9792, -10979, -2419, 2772, 69, 2895, -1218, -1161, -189, -734, 1421, 170, 0, -127, -798, 307, 58, 261, 196, -326, -5, -135, 69, 154, -38, 31, -85, -26, 35, 1, 46, -22
CCS中幅频特性
(9)滤波器的相频特性(FIR 16位blackman窗)
MATLAB设计结果:
设计相频特性
CCS中相频特性
结论:
通过对各种窗函数的研究可以发现:
在窗函数类型相同时,阶数越高,通带与阻带越平坦,通带与阻带的过渡带越窄。

但是该实验的DSK板资源有限,当阶数过高时,超过64,效果反而大打折扣。

在阶数相同,窗函数不同时,滤波器特性会有不同的效果。

从blackman窗到hamming窗和hann窗,阻带衰减变小,通带平坦度下降,主瓣长度变窄,但过渡带变窄。

对于相位响应,当阶数上升时,对于FIR滤波器,一直是比较理想的线性响应。

在实际CCS环境中观察时,会出现卷绕现象,即在周期处发生相位的跳变,这是由于计算机处理产生主值不连续造成的。

对于幅度相应,实际CCS中得出的结果比起MATLAB仿真,阻带波动变小。

其他特性变化不明显。

十、感想
经过整整十天的努力,本次小学期的任务终于完成了,这次实验我花费了很
多的时间和精力,经过无数次的调试和修改,终于得到了最后的成果。

首先感觉这次实验的难度很大。

在整个学期没有深入接触信号处理的情况
下,要在几天之内重拾数字信号处理的知识,并编写程序实在是感觉很困难。


经过老师三次的课堂讲解之后,我只是基本上学会了CCS的操作,对DSP处理
的程序根本不知其所以然。

开始做这次实验的时候一点头绪都没有,感觉无从下手。

于是我决定从老师上课用的例题程序开始,一点点的研读程序,分析它的功能。

虽然之前学过C语言,但是把C语言用在这么专业的场合还是第一次,适
应这种思路就花费了不少时间。

有一点思路之后,我开始接触与题目相关的程序。

当然自己写程序有点超乎我的能力之外,所以程序思路大体上都是参考的资料。

但当我开始运行程序的时候才发现存在很多问题,比如在加载很多程序的时候,
没有考虑好它们和我们的程序的对应性;编译无错但.out文件始终无法生成;头
文件路径不对,堆栈空间未设置,变量未定义或者重复定义等等的各种问题。


些问题有时会导致编译时报错,有时不报错但会影响程序运行的结果。

后来通过
查阅书籍、与同学讨论、向老师请教等方式,经过多次的修改,终于可以拿出能
够正常运行并得到正确结果的程序。

这次实验将理论上学习的DSP知识真正应用到了实践中,虽然掌握了理论
的相关知识,但在与实践相联系的过程中还是遇到了不少问题。

我总是根据自己
掌握的理论知识想当然的去编写和调试程序,因此也出现了不少错误。

虽然这学
期已经解除过用软件语音驱动硬件工作,比如微机接口和单片机,但这次实验相
比起来更复杂,修改程序时更难以下手。

我学的是自动化专业,也许以后不会有很多机会接触这样的信号处理的任
务,但是这次实验将给我以后完成其他实验时提供思路。

事在人为,无论多复杂,
无论有没有思路,只要努力去思考,就肯定会有解决问题的办法。

十一、参考文献
【1】高海林钱满义DSP技术及其应用北京交通大学出版社,2005
【2】谭浩强C程序设计(第二版)清华大学出版社,2003
【3】冬雷DSP原理及开放技术北京:清华大学出版社北京交通大学出版社2007.7
文档从互联网中收集,已重新修正排版,word格式支持编辑,如有帮助欢迎下载支持。

【4】王树恩宋彦一种快速的回声消除算法及DSP实现合肥:中国科学技术大学电子工程与信息科学系2007.6
【5】亓淑敏梁文家张美娟基于DSP的自适应噪声消除系统西安:长安大学信息工程学院2008.6
【6】Thomas F.Quatieri 著,赵胜浑等译.离散时间语音处理—原理与应用.电子工
业出版社,2004
【7】TMS320C54x DSP CPU and Peripherals. Texas Instrument Inc,2001.
【8】TMS320C54x DSP Applications and Guide. Texas Instrument Inc.2001.
41word格式支持编辑,如有帮助欢迎下载支持。

相关文档
最新文档