课程设计报告
课程设计名称: DSP原理与应用
系 :
学生姓名:
班 级: 通信
学 号:
成 绩:
指导教师:
开课时间: 学年 学期
基于TMS320VC5509 DSP的FIR滤波器设计
一、实践的目的和要求
1、实践的目的
(1)了解TMS320055x DSP汇编语言的特点,掌握TMS320C55x DSP常用的开发工具,掌握集成开发环境CCS的使用及利用CCS进行程序开发的一般过程。
(2)熟悉FIR滤波器工作原理及编程。
(3)掌握汇编语言程序的编写方法,汇编器和链接器的用法,利用汇编指令实现高速数字信号处理器。
(4)学习使用CCS图形观察窗口观察和分析语音波形及其频谱。
通过该课程的学习为今后从事使用DSP技术在通讯、控制等相关领域的应用、研究和开发打下良好的基础,为进入社会增加一种工作技能。
2、实践的要求
设计要求:已知信号的采样频率为8000hz,设计一个29阶的低通滤波器,滤波器的通带截止频率为2800hz,阻带截止频率为3100hz。
(1)学生首先自己参照指导书完《FIR算法实验》,认真阅读实验中的源程序,深刻理解FIR滤波的原理及具体实现方法,包括含噪信号的生成,滤波后信号的输出重点理解FIR滤波器的实现(循环寻址的实现)。
(2)在理解原理的基础上,设计自己的滤波器。
①设计一定参数的滤波器
用MATLAB设计滤波器,使用fir2函数设计滤波器,注意,在函数中,其截止频率均用归一化频率表示。
②得到滤波器的系数后,按照循环寻址的原理,参照给出的实验程序,编写具体的滤波器实现程序。
③调试程序,测试平台的性能。观察相应得含噪信号波形及去噪后的信号波形,滤波器的波形。经反复调试,使滤波器达到预计的结果。
二、实践原理:
1、DSP芯片
数字滤波是语音处理、图像处理、模式识别、频谱分析等应用中的基本处理算法。用DSP芯片实现数字滤波除了具有稳定性好、精确度高、不受环境影响等优点外,还具有灵活性好等特点。如图2-1为c5509引脚图。
2-1 VC5509引脚图
2、设计:
过渡带宽度=阻带边缘频宽-通带边缘频率
采样频率:
f1=通带边缘频率+(过渡带宽度)/2
理想低通滤波器脉冲响应:
h1[n]=sin(nΩ1)/n/π
根据要求,选择布莱克曼窗,窗函数长度为:
N=5.98fs/过渡带宽度
选择N=30
w[n]=0.42+0.5cos(2πn/30)+0.8cos(4πn/24)
滤波器脉冲响应为:
h[n]=h1[n]w[n]|n|<=12
h[n]=0|n|>12
根据上面计算,各式算出h[n],然后将脉冲响应值移位为因果序列。
完成的滤波器的差分方程为:
y[n]=-0.001x[n-2]-0.002x[n-3]-0.002x[n-4]+0.01x[n-5]-0.009x[n-6]-0.018x[n-7]-0.049x[n-8]-0.02x[n-9]+0.11x[n-10]+0.28x[n-11]+0.64x[n-12]+0.28x[n-13]-0.11x[n-14]-0.02x[n-15]+0.049x[n-16]-0.018x[n-17]-0.009x[n-18]+0.01[n-19]-0.002x[n-20]-0.002x[n-21]+0.001x[n-22]
3、 程序流程图
三、实践步骤
1、设计一定参数的滤波器
编写滤波器程序,首先要算出各个所需要的系数,然后编译程序,完成滤波的功能。用MATLAB设计滤波器,使用fir2函数设计滤波器,注意,在函数中,其截止频率均用归一化频率表示。
已知信号的采样频率为8000hz,设计一个29阶的低通滤波器,滤波器的通带截止频率为2800hz,阻带截止频率为3100hz。在函数中,其截止频率均用归一化频率表示。
归一化频率的计算方法:f=实际频率/(采样频率/2),则将截止频率归一化后的截止频率值为0.7、0.775。
程序代码: f=[0 0.7 0.775 1];
m=[1 1 0 0];
b=fir2(28,f,m)
结果: b= 0.0010 -0.0015 0.0011 0.0013 -0.0059 0.0092 -0.0047 -0.0107
0.0306 -0.0372 0.0101 0.0578 -0.1501 0.2307 0.7373 0.2307
-0.1501 0.0578 0.0101 -0.0372 0.0306 -0.0107 -0.0047 0.0092
-0.0059 0.0013 0.0011 -0.0015 0.0010
2.滤波器的设计程序
include "myapp.h"
#include "ICETEK-VC5509-EDU.h"
#include "scancode.h"
#include <math.h>
#define FIRNUMBER 29
#define SIGNAL1F 2800
#define SIGNAL2F 3100
#define SAMPLEF 8000
#define PI 3.1415926
float InputWave();
float FIR();
float fHn[FIRNUMBER]={
b= 0.0010 -0.0015 0.0011 0.0013 -0.0059 0.0092 -0.0047 -0.0107
0.0306 -0.0372 0.0101 0.0578 -0.1501 0.2307 0.7373 0.2307
-0.1501 0.0578 0.0101 -0.0372 0.0306 -0.0107 -0.0047 0.0092
-0.0059 0.0013 0.0011 -0.0015 0.0010
};
float fXn[FIRNUMBER]={ 0.0 };
float fInput,fOutput;
float fSignal1,fSignal2;
float fStepSignal1,fStepSignal2;
float f2PI;
int i;
float fIn[256],fOut[256];
int nIn,nOut;
main()
{
nIn=0; nOut=0;
f2PI=2*PI;
fSignal1=0.0;
fSignal2=PI*0.1;
fStepSignal1=2*PI/30;
fStepSignal2=2*PI*1.4;
while ( 1 )
{
fInput=InputWave();
fIn[nIn]=fInput;
nIn++; nIn%=256;
fOutput=FIR();
fOut[nOut]=fOutput;
nOut++; /* break point */
if ( nOut>=256 )
{
nOut=0;
}
}
}
float InputWave()
{
for ( i=FIRNUMBER-1;i>0;i-- )
fXn[i]=fXn[i-1];
fXn[0]=sin((double)fSignal1)+cos((double)fSignal2)/6.0;
fSignal1+=fStepSignal1;
if ( fSignal1>=f2PI ) fSignal1-=f2PI;
fSignal2+=fStepSignal2;
if ( fSignal2>=f2PI ) fSignal2-=f2PI;
return(fXn[0]);
}
float FIR()
{
float fSum;
fSum=0;
for ( i=0;i<FIRNUMBER;i++ )
{
fSum+=(fXn[i]*fHn[i]);
}
return(fSum);
}
5.调试程序,测试平台的性能
语音信号的FIR滤波
#include "5509.h"
#include "util.h"
#include "audio.h"
// AIC23 Control Register addresses
#define AIC23_LT_LINE_CTL 0x00 // 0
#define AIC23_RT_LINE_CTL 0x02 // 1
#define AIC23_LT_HP_CTL 0x04 // 2
#define AIC23_RT_HP_CTL 0x06 // 3
#define AIC23_ANALOG_AUDIO_CTL 0x08 // 4
#define AIC23_DIGITAL_AUDIO_CTL 0x0A // 5
#define AIC23_POWER_DOWN_CTL 0x0C // 6
#define AIC23_DIGITAL_IF_FORMAT 0x0E // 7
#define AIC23_SAMPLE_RATE_CTL 0x10 // 8
#define AIC23_DIG_IF_ACTIVATE 0x12 // 9
#define AIC23_RESET_REG 0x1E // F - Writing 0 to this reg triggers reset
// AIC23 Control Register settings
#define lt_ch_vol_ctrl 0x0017 /* 0 */
#define rt_ch_vol_ctrl 0x0017 /* 1 */
#define lt_ch_headph_ctrl 0x0079 /* 2 */
#define rt_ch_headph_ctrl 0x0079 /* 3 */
#define alog_au_path_ctrl 0x0000 /* 4 */
#define digi_au_path_ctrl 0x0000 /* 5 */
#define pow_mgt_ctrl_ctrl 0x0002 /* 6 */
#define digi_au_intf_ctrl 0x000D /* 7 */
#define au_FS_TIM_ctrl 0x0000 /* 8 MCLK=12MHz, Sample Rate setting */
#define digi_intf1_ctrl 0x0001 /* 9 */
#define digi_intf2_ctrl 0x00FF /* 10 */
#define DIGIF_FMT_MS 0x40
#define DIGIF_FMT_LRSWAP 0x20
#define DIGIF_FMT_LRP 0x10
#define DIGIF_FMT_IWL 0x0c
#define DIGIF_FMT_FOR 0x03
#define DIGIF_FMT_IWL_16 0x00
#define DIGIF_FMT_IWL_20 0x04
#define DIGIF_FMT_IWL_24 0x08
#define DIGIF_FMT_IWL_32 0xc0
#define DIGIF_FMT_FOR_MSBRIGHT 0x00
#define DIGIF_FMT_FOR_MSLEFT 0x01
#define DIGIF_FMT_FOR_I2S 0x02
#define DIGIF_FMT_FOR_DSP 0x03
#define POWER_DEV 0x80
#define POWER_CLK 0x40
#define POWER_OSC 0x20
#define POWER_OUT 0x10
#define POWER_DAC 0x08
#define POWER_ADC 0x04
#define POWER_MIC 0x02
#define POWER_LINE 0x01
#define SRC_CLKOUT 0x80
#define SRC_CLKIN 0x40
#define SRC_SR 0x3c
#define SRC_BOSR 0x02
#define SRC_MO 0x01
#define SRC_SR_44 0x20
#define SRC_SR_32 0x18
#define SRC_SR_8 0x0c
#define ANAPCTL_STA 0xc0
#define ANAPCTL_STE 0x20
#define ANAPCTL_DAC 0x10
#define ANAPCTL_BYP 0x08
#define ANAPCTL_INSEL 0x04
#define ANAPCTL_MICM 0x02
#define ANAPCTL_MICB 0x01
#define DIGPCTL_DACM 0x08
#define DIGPCTL_DEEMP 0x06
#define DIGPCTL_ADCHP 0x01
#define DIGPCTL_DEEMP_DIS 0x00
#define DIGPCTL_DEEMP_32 0x02
#define DIGPCTL_DEEMP_44 0x04
#define DIGPCRL_DEEMP_48 0x06
#define DIGIFACT_ACT 0x01
#define LT_HP_CTL_LZC 0x80
#define RT_HP_CTL_RZC 0x80
void AIC23_Write(unsigned short regaddr, unsigned short data)
{
unsigned char buf[2];
buf[0] = regaddr;
buf[1] = data;
I2C_Write(I2C_AIC23, 2, buf);
}
void McBSP0_InitSlave()
{
PC55XX_MCSP pMCBSP0 = (PC55XX_MCSP)C55XX_MSP0_ADDR;
// Put the MCBSP in reset
Write(pMCBSP0 -> spcr1, 0);
Write(pMCBSP0 -> spcr2, 0);
// Config frame parameters (32 bit, single phase, no delay)
Write(pMCBSP0 -> xcr1, XWDLEN1_32);
Write(pMCBSP0 -> xcr2, XPHASE_SINGLE | XDATDLY_0);
Write(pMCBSP0 -> rcr1, RWDLEN1_32);
Write(pMCBSP0 -> rcr2, RPHASE_SINGLE | RDATDLY_0);
// Disable int frame generation and enable slave w/ext frame signals on FSX
// Frame sync is active high, data clocked on rising edge of clkx
Write(pMCBSP0 -> pcr, PCR_CLKXP);
// Bring transmitter and receiver out of reset
SetMask(pMCBSP0 -> spcr2, SPCR2_XRST);
SetMask(pMCBSP0 -> spcr1, SPCR1_RRST);
}
void AIC23_Init()
{
I2C_Init();
// Reset the AIC23 and turn on all power
AIC23_Write(AIC23_RESET_REG, 0);
AIC23_Write(AIC23_POWER_DOWN_CTL, 0);
AIC23_Write(AIC23_ANALOG_AUDIO_CTL, ANAPCTL_DAC | ANAPCTL_INSEL); // 使用麦克风音源
AIC23_Write(AIC23_DIGITAL_AUDIO_CTL, 0);
// Turn on volume for line inputs
AIC23_Write(AIC23_LT_LINE_CTL,0x000);
AIC23_Write(AIC23_RT_LINE_CTL,0x000);
// Configure the AIC23 for master mode, 44.1KHz stereo, 16 bit samples
// Use 12MHz USB clock
AIC23_Write(AIC23_DIGITAL_IF_FORMAT, DIGIF_FMT_MS | DIGIF_FMT_IWL_16 | DIGIF_FMT_FOR_DSP);
AIC23_Write(AIC23_SAMPLE_RATE_CTL, SRC_SR_44 | SRC_BOSR | SRC_MO);
// Turn on headphone volume and digital interface
AIC23_Write(AIC23_LT_HP_CTL, 0x07f); // 0x79 for speakers
AIC23_Write(AIC23_RT_HP_CTL, 0x07f);
AIC23_Write(AIC23_DIG_IF_ACTIVATE, DIGIFACT_ACT);
// Set McBSP0 to be transmit slave
McBSP0_InitSlave();
}
void AIC23_Disable()
{
PC55XX_MCSP pMCBSP0 = (PC55XX_MCSP)C55XX_MSP0_ADDR;
I2C_Disable();
// Put the MCBSP in reset
Write(pMCBSP0 -> spcr1, 0);
Write(pMCBSP0 -> spcr2, 0);
}
#define AUTIODATALEFT 0x0d000
#define AUTIODATARIGHT 0x17000
int *pAudioLeft,*pAudioRight;
int www=0;
void AIC23_Mixer()
{
PC55XX_MCSP pMCBSP0 = (PC55XX_MCSP)C55XX_MSP0_ADDR;
int left, right;
int *pl,*pr,nAudioCount;
int i;
pAudioLeft=pl=(int *)AUTIODATALEFT;
pAudioRight=pr=(int *)AUTIODATARIGHT;
nAudioCount=0;
for ( i=0;i<NX;i++) x[i]=0;
for ( i=0;i<NH+2;i++) db[i]=0;
while(1)
{
while (!ReadMask(pMCBSP0 -> spcr2, SPCR2_XRDY)); // 等待数据传输完成
(*pl)=left = Read(pMCBSP0 -> ddr1); // 读入左声道数据
right = Read(pMCBSP0 -> ddr2); // 读入右声道数据
x[NX-1]=left/16; // 防止滤波时数据溢出
fir2(x, h, r, db, NX, NH); // 调用滤波程序计算当前输出
(*pr)=r[NX-1]; // 数组r的最后一个单元为当前输出
Write(pMCBSP0 -> dxr1, left); // 将原始数据送左声道输出
//Write(pMCBSP0 -> dxr1, r[NX-1]); // 将原始数据送左声道输出
Write(pMCBSP0 -> dxr2, r[NX-1]); // 将经过滤波后的数据送右声道输出
nAudioCount++; pl++; pr++; // 循环使用缓冲区
if ( nAudioCount>=1024 )
{
nAudioCount=0; // break point
pl=pAudioLeft;
pr=pAudioRight;
}
for ( i=0;i<NX-1;i++ ) // 重新调整输入序列(供fir2使用)
{
x[i]=x[i+1];
}
}
}
实验结果
四、心得体会
这次课程设计实现了一个简单的FIR滤波器的设计。通过这一个星期的课程设计,我学到了很多的东西,不仅巩固了我以前所学过的知识, 还让我学到很多在书本上所没有学到过的知识。 同时通过这次课程设计,我了解了FIR滤波器的原理,熟练掌握了MATLAB的操作,不仅是我学到了知识,更锻炼了我的动手能力。也进一步认识了CCStudio软件的使用,了解了各种窗函数对滤波器特性的影响。
在这次课程设计的过程中,我遇到不少的问题,比如刚开始,计算机上的CCS软件无法与试验箱正常相连,通过对其他同学的帮助,解决了问题;其次在输入命令的时候也遇到了些问题,经常会输错,不过经过慢慢的调试,最后得出正确的结果。这才使我明白了理论与实际相结合是很重要的。
总的来说,这次的课程设计使我对DSP课程有了全面的认识,对CCS和MATLAB的知识又有了深刻的理解,更让我感受到只有在充分理解课本知识的前提下,才能更好的应用工具。因此,本次课程设计我受益匪浅。
这是本学期的第二个课程设计,现在深切体会到课程设计在大学生的学习过程中是多么的重要,它使我们在实践中了巩固了所学的知识、锻炼了自己的动手能力同时又拓展了知识,它让我学到了很多在课堂上根本就学不到的知识,开阔了视野,增长了见识,也为以后的学习工作打下了坚实的基础。
五、参考文献
1、瑞泰公司.ICETEK-VC5509A开发实验平台系列使用说明书[M].2007
2、邹彦.DSP原理与应用[M].北京:电子工业出版社.2006
3、张雄伟.DSP芯片的原理与开发利用[M].北京:电子工业出版社.2007
4、丁玉美 高西全.数字信号处理(第二版)[M].西安: 西安电子科技大学出版社.2000.
5、程佩青.数字信号处理教程[M].北京:清华大学出版社,1999年.
6、孙宗瀛 谢鸿林.TMS320C5xDSP原理设计与应用[M].北京:清华大学出版社.20##年
7、自编教材. DSP原理实验及课程设计指导书[M].2013