DSP期末考试实验报告Word格式.docx
《DSP期末考试实验报告Word格式.docx》由会员分享,可在线阅读,更多相关《DSP期末考试实验报告Word格式.docx(16页珍藏版)》请在冰豆网上搜索。
(一)设计前了解和准备:
(1)此次实验主要用到了三个模块,第一个是AIC23的立体声语音解码芯片,第二个是MCBSP0的多通道缓冲串口,第三个是I2C总线模块。
另外还用到了DSP的FIR滤波实现。
(2)三个模块的基本介绍和FIR基础知识:
AIC23芯片:
AIC23是可编程芯片,内部有11个16位寄存器,编程设置这些寄存器可得到所需的采样频率、输入输出增益和传输数据格式等。
该控制接口有SPI和I2C两种工作模式,由芯片上的MODE引脚进行选择:
MODE=0为I2C模式,MODE=1为SPI模式。
AIC23的I2C接口地址由引脚的状态决定,=0时地址为0011010,=1时地址为0011011。
(注意:
在该开发板上我们已经直接将MODE接口接地,即低电平0,此时则只
运行于I2C模式。
)
MCBSP模块:
MCBSP为多通道缓冲串口,用于实现DSP芯片与AIC23芯片之间的数据传输,在实验中我们用到了MCBSP0的模块进行数据接收和发送。
I2C模块:
I2C总线定义:
I2C(Inter-IntegratedCircuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备
I2C总线特点:
I2C总线最主要的优点是其简单性和有效性。
由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本,I2C要求从器件有一个地址。
FIR滤波:
FIR:
有限脉冲响应滤波器。
特点:
线性相位,非递归结构。
既具有严格的线性相位(就是不同频率分量的信号经过fir滤波器后他们的时间差不变)。
图像处理以及数据传输,都要求信道具有线性相位特性。
FIR滤波器的单位抽样响应是有限长的,因而滤波器性能稳定。
(3)程序需要配置的模块:
初始化DSP的时钟和寄存器。
MCBSP寄存器配置。
I2C寄存器配置。
AIC23寄存器配置。
实现程序代码,包括FIR滤波实现。
初始化配置:
DSP通过I2C总线将配置命令发送到AIC23,配置完成后AIC23开始工作。
(4)大致实验原理和步骤:
第一步:
通过麦克风利用芯片AIC23进行带噪声的语音信号采集,由于AIC本身自带A/D转化,采集得到的数据传输保存于MCBSP数据接收寄存器DDR。
第二步:
DSP对MCBSP中的数据进行FIR滤波,并送给MCBSP中的数据发送寄存器DXR。
第三步:
DXR中数据回传给AIC23,并利用它带的D/A转换进行输出,从而能听到滤波后的信号。
(二)实验流程图设计:
设计流程图如下:
(三)三大模块初始化代码:
(1)AIC23的初始化代码(附注解):
//AIC23的11个控制寄存器各基地址定义
#defineAIC23_LT_LINE_CTL0x00//0
#defineAIC23_RT_LINE_CTL0x02//1
#defineAIC23_LT_HP_CTL0x04//2
#defineAIC23_RT_HP_CTL0x06//3
#defineAIC23_ANALOG_AUDIO_CTL0x08//4
#defineAIC23_DIGITAL_AUDIO_CTL0x0A//5
#defineAIC23_POWER_DOWN_CTL0x0C//6
#defineAIC23_DIGITAL_IF_FORMAT0x0E//7
#defineAIC23_SAMPLE_RATE_CTL0x10//8
#defineAIC23_DIG_IF_ACTIVATE0x12//9
#defineAIC23_RESET_REG0x1E//F–让寄存器复位
//部分控制寄存器各个位的初值设置
//数字音频控制接口寄存器各位定义
#defineDIGIF_FMT_MS0x40
#defineDIGIF_FMT_LRSWAP0x20
#defineDIGIF_FMT_LRP0x10
#defineDIGIF_FMT_IWL0x0c
#defineDIGIF_FMT_FOR0x03
#defineDIGIF_FMT_IWL_160x00
#defineDIGIF_FMT_IWL_200x04
#defineDIGIF_FMT_IWL_240x08
#defineDIGIF_FMT_IWL_320xc0
#defineDIGIF_FMT_FOR_MSBRIGHT0x00
#defineDIGIF_FMT_FOR_MSLEFT0x01
#defineDIGIF_FMT_FOR_I2S0x02
#defineDIGIF_FMT_FOR_DSP0x03
//电源控制寄存器各位定义
#definePOWER_DEV0x80
#definePOWER_CLK0x40
#definePOWER_OSC0x20
#definePOWER_OUT0x10
#definePOWER_DAC0x08
#definePOWER_ADC0x04
#definePOWER_MIC0x02
#definePOWER_LINE0x01
//采样率控制寄存器各位定义
#defineSRC_CLKOUT0x80
#defineSRC_CLKIN0x40
#defineSRC_SR0x3c
#defineSRC_BOSR0x02
#defineSRC_MO0x01
#defineSRC_SR_440x20
#defineSRC_SR_320x18
//模拟音频通道控制寄存器各位定义
#defineANAPCTL_STA0xc0
#defineANAPCTL_STE0x20
#defineANAPCTL_DAC0x10
#defineANAPCTL_BYP0x08
#defineANAPCTL_INSEL0x04
#defineANAPCTL_MICM0x02
#defineANAPCTL_MICB0x01
//数字音频通道控制寄存器各位定义
#defineDIGPCTL_DACM0x08
#defineDIGPCTL_DEEMP0x06
#defineDIGPCTL_ADCHP0x01
#defineDIGPCTL_DEEMP_DIS0x00
#defineDIGPCTL_DEEMP_320x02
#defineDIGPCTL_DEEMP_440x04
#defineDIGPCRL_DEEMP_480x06
#defineDIGIFACT_ACT0x01//数字接口激活寄存器初始化
#defineLT_HP_CTL_LZC0x80//耳机左通路音频控制寄存器
#defineRT_HP_CTL_RZC0x80//耳机右通路音频控制寄存器
voidAIC23_Init()//音频芯片AIC23初始化模块
{
I2C_Init();
//调用I2C初始化程序用来打开AIC23
//初始化AIC23并打开各个模块
AIC23_Write(AIC23_RESET_REG,0);
//AIC23寄存器复位
AIC23_Write(AIC23_POWER_DOWN_CTL,0);
/*节电模式设置,所有部分都为工作状态*/
AIC23_Write(AIC23_ANALOG_AUDIO_CTL,ANAPCTL_DAC|ANAPCTL_INSEL);
//模拟音频通道控制,打开DAC,ADC输入选择方式为麦克风输入方式
AIC23_Write(AIC23_DIGITAL_AUDIO_CTL,0);
//数字音频通道控制
//line输入的音频方式调节
AIC23_Write(AIC23_LT_LINE_CTL,0x000);
//左通路音频方式调节
AIC23_Write(AIC23_RT_LINE_CTL,0x000);
//右通路音频方式调节
AIC23_Write(AIC23_DIGITAL_IF_FORMAT,DIGIF_FMT_MS|
DIGIF_FMT_IWL_16|DIGIF_FMT_FOR_DSP);
/*选定AIC23为主模式,
数据长为16bit,DSP格式*/
AIC23_Write(AIC23_SAMPLE_RATE_CTL,SRC_SR_44|SRC_BOSR|SRC_MO);
//选定USB模式采样率为44.1KHZ,
//打开耳机通路调节
AIC23_Write(AIC23_LT_HP_CTL,0x07f);
//耳机左通路控制调节音量增益为+6db
AIC23_Write(AIC23_RT_HP_CTL,0x07f);
//耳机右通路控制调节音量增益为+6db
AIC23_Write(AIC23_DIG_IF_ACTIVATE,DIGIFACT_ACT);
//数字接口激活
McBSP0_InitSlave();
//设置McBSP0用来控制发送来的数据
}
//AIC23控制口写入,利用I2C激活AIC23
voidAIC23_Write(unsignedshortregaddr,unsignedshortdata)
unsignedcharbuf[2];
buf[0]=regaddr;
buf[1]=data;
I2C_Write(I2C_AIC23,2,buf);
//用I2C激活AIC23
(2)MCBSP0的初始化代码(附注解):
voidMcBSP0_InitSlave()//MCBSP初始化模块
PC55XX_MCSPpMCBSP0=(PC55XX_MCSP)C55XX_MSP0_ADDR;
/*使用库函
PC55XX_MCSP*/
//初始化MCBSP0的SPCR1和SPCR2这两个控制寄存器
Write(pMCBSP0->
spcr1,0);
spcr2,0);
//设置接收和传输的大小,并设置接收和传输时不需要延迟
xcr1,XWDLEN1_32);
/*设置输出控制寄存器xcr1来传输字节长度*/
xcr2,XPHASE_SINGLE|XDATDLY_0);
/*设置输出控制寄存器
cxcr1在传输数据时,不需要延迟一个时钟输出*/
rcr1,RWDLEN1_32);
/*设置输入控制寄存器rcr1的读入字节长度*/
rcr2,RPHASE_SINGLE|RDATDLY_0);
/*设置输入控制寄存器rcr1在接收数据时,不需要延迟一个时钟接收*/
/*设置PCR时钟信号控制寄存器,确定时钟信号的极性,当CLKXP为
0的时候为正极性,时钟以上升沿开始;
反之,时钟以下降沿开始*/
pcr,PCR_CLKXP);
//对发送和接收进行复位
SetMask(pMCBSP0->
spcr2,SPCR2_XRST);
//复位SPCR2中的XRST寄存器
spcr1,SPCR1_RRST);
//复位SPCR1中RRST寄存器
(3)I2C的初始化代码(附注解):
I2C_Init()//I2C的初始化模块
PC55XX_I2CpI2C=(PC55XX_I2C)C55XX_I2C_ADDR;
/*利用到库文件中的PC55XX_I2C*/
ClearMask(pI2C->
icmdr,ICMDR_IRS);
/*重置I2C寄存器ICMDR,发送一个信号激活I2C总线*/
pI2C->
icpsc=dspclk.pllmult;
/*配置I2C总线的时钟信号,AIC23使用的是晶振输入,所以I2C时钟寄存器ICPSC直接用时钟信号dspclk.pllmult*/
//配置I2C信号的时钟信号(SCL)频率
Write(pI2C->
icclkl,10);
icclkh,10);
WriteMask(pI2C->
icoar,ICOAR_OADDR,ICOAR_MASK_7);
//设置I2C主从地址。
SetMask(pI2C->
icmdr,ICMDR_IRS|ICMDR_MST);
/*第二次对ICMDR赋值,表示I2C寄存器配置完成,I2C总线准备工作;
*/
I2C_Disable()//I2C关闭模块
//让I2C控制寄存器重启(如果没重启寄存器的情况下时钟改变了)
//I2C的写模块
voidI2C_Write(unsignedshortintdevice,intcount,unsignedchar*bytedata)
//调用库函数PC55XX_I2C
intI;
//设置I2C的控制寄存器用来写大小为count的数据
iccnt,count);
/*设置需要通过I2C来传输的数据大小,大小为count*/
icsar,device,ICSAR_MASK_7);
/*设置DSP想要读写的从地址*/
//激活ICMDR模式寄存器中的相应位,从而定义控制方式
icmdr,
ICMDR_STT|ICMDR_STP|ICMDR_TRX,
ICMDR_STT|ICMDR_STP|ICMDR_TRX);
//STT代表的开始位,STP代表的结束位,TRX代表的传输模式
//传输数据
for(i=0;
i<
count;
i++)
icdxr,bytedata[i]);
/*DSP通过ICDXR这个寄存器发送数据bytedata[i]*/
while(!
(pI2C->
icstr&
ICSTR_ICXRDY));
/*检测DSP发送寄存器ICSTR是否发送完毕*/
}
//I2C的读模块
voidI2C_Read(unsignedshortintdevice,intcount,unsignedchar*bytedata)
//使用库函数PC55XX_I2C
inti;
//设置I2C的控制寄存器用来读大小为count的数据
/*设置需要通过I2C来传输的数据大小,大小为count*/
ICMDR_STT|ICMDR_STP,//这里的ICMDR_TRX没写即代表为默认1,读模式
//接收count大小的数据
count;
i++)
{
ICSTR_ICRRDY));
/*检测DSP接收寄存器ICRRX是否接收完毕*/
bytedata[i]=pI2C->
icdrr;
//拷贝数据到bytedata[i]数组进行保存。
(四)主函数和关键程序代码:
(1)main()函数代码(附注释):
voidmain()
SDRAM_init();
//初始化EMIF外部扩展接口
EnableAPLL();
//打开时钟锁相环
PLL_Init(40);
//初始化时钟
AIC23_Init();
//调用AIC23初始化模块
PLL_Init(120);
for(;
;
AIC23_Mixer();
//调用关键实现程序
(2)关键实现函数AIC23_Mixer()代码(附注释):
#defineAUTIODATALEFT0x0d000
#defineAUTIODATARIGHT0x17000
int*pAudioLeft,*pAudioRight;
voidAIC23_Mixer()
intleft,right;
//定义左右声道变量
int*pl,*pr,nAudioCount;
pAudioLeft=pl=(int*)AUTIODATALEFT;
pAudioRight=pr=(int*)AUTIODATARIGHT;
nAudioCount=0;
for(i=0;
i<
NX;
i++)x[i]=0;
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的最后一个单元为当前输出
dxr1,left);
//将原来数据送左声道输出
dxr2,r[NX-1]);
//将滤波后的数据送右声道输出
nAudioCount++;
pl++;
pr++;
//循环使用缓冲区
if(nAudioCount>
=1024)
nAudioCount=0;
//断点位置
pl=pAudioLeft;
pr=pAudioRight;
NX-1;
i++)//重新调整输入序列(供fir2使用)
x[i]=x[i+1];
注意:
其中这些定义中还包含了很多头文件以及系统库函数的引用,这些大部分为CCS软件提供,具体的设置略,以上仅为核心模块初始化以及主程序实现部分代码。
四、实验运行结果
实验运行结果:
在设置断点处设置断点,下载进实验板后点一直运行,麦克风输入声音,由于原
来数据保存于AUTIODATALEFT,滤波后数据保存于AUTIODATARIGHT,所以可以在CCS
软件中打开图形观察窗口监视动态变化,开两个窗口,观察基地址分别对应
AUTIODATALEFT(0x0d000),AUTIODATARIGHT(0x17000),取一个输入点停止运行
截得各个部分的频域图和时域图分别如下:
图1带噪声声波时域图
图2滤波后声波时域图
图3带噪声声波频域图
图4滤波后声波频域图
五、实验心得
虽然本科是学习过这门课程但是由于一些原因学的很粗糙,这学期通过学习DSP这门课程,让我加深了对DSP的了解,让我进一步熟悉了CCS开发环境以及设计运行调试过程,认识到AIC23语音芯片和I2C协议以及MCBSP模块的各个工作原理以及三者之间的关系,学会对模块的初始化怎么定义和编写的流程。
使我对DSP产生了浓厚的兴趣,激发了我学习DSP的积极性,从这次实验结果上来说,清晰的结果使我对书本上的知识应用到了实验中,很满足。
该实验通过FIR滤波器滤波后把噪声滤除掉了,从时域图来看,原来的带有毛刺的音频波形滤波后变得平滑,从频域图来看,噪声所在的频域段基本上被滤除掉。
实验的成功离不开老师、师兄、师姐的耐心指导!
在这里谢谢老师、师兄、师姐的教导!