DSP语音录放课程设计.docx
《DSP语音录放课程设计.docx》由会员分享,可在线阅读,更多相关《DSP语音录放课程设计.docx(14页珍藏版)》请在冰豆网上搜索。
DSP语音录放课程设计
青岛工学院
课程设计报告
课程设计名称:
语音采集和放送
学院:
信息工程学院
学生姓名:
郑肖肖
班级:
电子信息工程1班
学号:
201102305102
指导教师:
孙文汇
基于TMS320C5416DSP的语音信号的采集和放送
一、实践的目的和要求
1、实践目的
信息技术和超大规模集成电路工艺的不断发展,极大地推动了DSP的发展。
DSP技术的应用领域也越来越广,尤其在音频处理领域。
目前,在很多语音处理系统中都用到了语音录放模块,采集现场的声音并存储起来供以后回放。
语音处理系统的实时性、功耗、体积、以及对语音信号的保真度都是很影响系统性能的关键因素。
本设计采用的高速54xDSP芯片,最高频率能达到160MIPS,能够很好的解决系统的实时性;采用的数字编解码芯片TLV320AIC23(以下简称AIC23)具有16~32位采样精度,录音回放模式下仅23mW的功耗。
因此,该音频编解码芯片与54xDSP的结合是可移动数字音频录放系统、现场语音采集系统的理想解决方案。
在CCS环境下基于TMS320C5416芯片的语音采集压缩存储与回放。
通过这次课程设计,加深对CCS集成开发环境,熟悉DSP54X同步串口原理,了解音频编解码芯片TLV320AIC23原理,了解存储芯片NANDFLASH原理,掌握DSP54X中断原理以及DSP试验系统箱的使用。
锻炼逻辑思维能力、动手能力以及独立解决问题的能力,对以后更深入地学习和应用数字信号处理及相关知识作准备。
经过实验表明,本设计实现的基于定点DSP的语音录放系统具有如下优点:
1)音频数据占用资源少
2)声音保真度高
3)开发难度低
4)语音芯片与DSP接口电路简单
5)体积小
2、实践要求
(1)了解DSP开发工具及其安装过程
(2)熟悉DSP开发软件CCS使用
(3)熟悉工程文件的建立方法、汇编程序开发调试过程
(4)熟悉常用C5416系列指令的用法
(5)通过McBSP1设置AIC23工作模式,通过McBSP0控制AIC23编码和解码,语音信号可由MIC输入和LINEIN输入,采集的语音数据存储在NANDFLASH上,语音的回放方式可以为BYPASS和LOOP-BACK。
2、实践原理
1TMS320C5416芯片的基本原理
TMS320C5416数字信号处理器是TI公司为实现低功耗,高速实时信号处理而专门设计的16位定点数字信号处理器,采用改进的哈佛结构,具有高度的操作灵活性和运行速度,适用于远程通信等实时嵌入式应用的需要。
广泛应用于电子测试、电子设计、模拟仿真、通信工程中。
TMS320C5416具有的主要优点如下:
(1)围绕一组程序总线、三组数据总线和四组地址总线而建立的改进哈佛结构,提高了系统的多功能性和操作的灵活性。
(2)具有高度的并行性和专用硬件逻辑的CPU设计,提高了芯片的性能。
(3)具有完善的寻址方式和高度专业化指令系统,更适用于快速算法的实现和高级语言编程的优化。
(4)模块化结构设计,使派生器件得到了更快的发展。
(5)采用先进的IC制造工艺,降低了芯片的功耗,提高了芯片的性能。
(6)采用先进的静态设计技术,进一步降低了功耗,使芯片具有更强的应用能力。
TMS320C5416主要有中央处理器CPU,特殊功能寄存器,数据存储器RAM,程序存储器ROM,I/O接口功能,串行口,主机通信接口HPI,定时器,中断系统等10部分组成。
各部分功能如下:
(1)中央处理器(CPU)
它是DSP芯片的核心,它有以下特点:
(a)采用多总线结构,通过一组程序总线、三组数据总线和四组地址总线来实现。
(b)40位算术逻辑运算单元ALU,包括一个40位的桶形移位寄存器和两个独立的40位累加器。
(c)17×17位并行乘法器,与40位专用加法器相连,可用于进行非流水线的单周期乘法—累加运算。
(d)比较、选择、存储单元,可用于Viterbi译码器的加法-比较-选择运算。
(e)指数编码器,是一个支持单周期指令EXP的专用硬件。
可以在一个周期内计算40位累加器数值的指数。
(f)配有两个地址生成器,包括8个辅助寄存器和2个辅助寄存器运算单元。
(2)数据存储器RAM
TMS320C5416有两种片内数据存储器:
(a)双寻址RAM:
在一个指令周期内,可对其进行两次存取操作,一次读出和一次写入;
(b)双寻址RAM:
在一个指令周期内,只能进行一次存取操作。
(3)程序存储器ROM
T4MS320VC516的程序存储器可由ROM和RAM配置而成,程序空间可以定义在ROM上,也可以定义在ROM上。
当需要高速运行程序时,可以将片外ROM中的程序调入到片内RAM中,以提高程序运行速度。
降低对外部ROM的要求,增强系统整体抗干扰性能。
(4)I/O口
TMS320C5416芯片只有两个通用I/O引脚BIO和XF,BIO主要用来监测外部设备工作状态,而XF用来发信号给外部设备。
另外,芯片还配有主机接口HPI,同步串行口和64K字的I/O空间,HPI和串行口通过控制,用做通用I/O口使用。
而64K字I/O空间可通过外加缓冲器或锁存电路,配合外部I/O读写控制时序构成片外外设的控制电路。
(5)定时器
定时器是一个软件可编程计数器,用来产生定时中断。
定时器主要由定时寄存器TM,定时周期寄存器PRD,定时控制寄存器TCR及相应的逻辑控制电路组成。
其中寄存器TIM、PRD和TCR都是存储映象寄存器,它们在数据存储器中的地址分别为0024H、0025H和0026H。
TIM是一个减1寄存器。
PRD用来存放定时时间常数。
TCR中包含定时器的控制位和状态位。
(6)中断系统
TMS320C5416的中断系统具有硬件中断和软件中断。
硬件中断:
由外围设备引起的中断分为片外外设所引起的中断和片内外设所引起的中断。
软件中断:
有程序指令INTR、TRAP和RESET所引起的中断。
中断管理优先级为11—16个固定级,有4种工作方式。
(7)主机接口HPI
HPI是一个与主机通信的并行接口,主要用于DSP与其他总线或CPU进行通信,信息可通过TMS320C5416的片内存储器与主机进行数据交换。
不同型号的器件配置不同的HPI口,可分为8位标准HPI口、8位增强型HPI接口和16位增强型HPI接口。
(8)指令系统
支持单指令重复和块指令重复;支持存储器块传送指令;支持32位长操作数指令;具有支持2操作数或3操作数的读指令;具有能并行存储和并行加载的算术指令;支持条件存储指令及中断快速返回指令。
2语音编码芯片的选择
从适应语音信号频率、满足实时性、降低成本、简化设计的要求出发,本系统选择TLV320AIC23。
AIC23工作电压3.3伏特,能在数字和模拟电压下工作,与TMS320C5416的I/O电压相兼容,其控制接口和数字接口与DSP的MCBSP端口能够无缝连接。
AIC23的模数转换(ADCs)和数模转换(DACs)部件高度集成在芯片内部,采用了先进的Sigma-delta过采样技术,可以在8K到96K的频率范围内提供16bit、20bit、24bit和32bit的采样,ADC和DAC的输出信噪比分别可以达到90dB和100dB[1]。
3系统硬件设计
AIC23有独立的控制接口和数字接口。
控制口用于接收控制器的命令字,数据接口与DSP完成语音数据的交换。
AIC23的工作时钟由外接的一个11.2896M的晶振提供,同时该晶振也为DSP提供工作时钟。
DSP的工作时钟是5倍频后的时钟:
56.488M。
本系统用到了利用DSP的MCBSP0和MCBSP1,分别与AIC23的控制和数据接口相连。
DSP与AIC23的接口电路如图1
图2C5416与AIC23的接口图
(1)音频控制接口
MCBSP1接AIC23的控制接口。
AIC23提供SPI和I2C两种控制接口方式。
该器件的模式终端状态(MODE)决定了控制接口的形式。
本设计将MODE引脚接高,选择SPI方式。
AIC23的控制口主要是为了接收DSP的控制字,因此这里DSP的MCBSP1作为主器件。
AIC23有许多可编程特性,其内部有11个9位可编程控制寄存器,DSP通过MCBSP1来访问这些控制寄存器。
SDIN为串行数据输入端,它接收DSP串行数据,数据字长16位,其中高7位为地址信息,低9位为AIC23的命令字。
SCLK为控制端口串行数据时钟输入,DSP串口的采样率发生器对CPU时钟分频后得到串口的发送时钟BCLKX1=225.952KHz,产生的时钟通过SCLK引脚驱动AIC23。
(2)音频数据接口
DSP与AIC23的数据交换是通过串口0实现的。
其中MCBSP多通道缓冲串口数据的接收是通过三级缓冲完成的[2],即引脚DR上的数据先到达移位寄存器RSR,当收到一个满字之后数据被装载到数据接收寄存器RBR中,最后数据才被拷贝到接收数据寄存器DRR中。
DSP通过串口0接收AIC23采集的语音数字信号,并且在回放模式下,通过串口将语音信号传送给AIC23。
这时音频芯片为主器件,给DSP提供帧同步和时钟信号。
AIC23芯片与数字系统的接口有右判断模式、左判断模式、I2S模式和DSP模式四种数据格式。
数字音频接口由时钟信号BCLK、数据信号DIN和DOUT、同步信号LRCIN和LRCOUT组成。
由于DSP的MCBSP接口与该芯片的DSP模式相兼容,因此该音频模块采用了DSP模式。
现对DSP模式进行说明。
该音频处理模块采用的是DSP作为从设备,AIC23为主设备。
DSP模式下的数据格式为:
发送、接收帧长度为2个字,每个字长16位。
帧同步信号有效后跟着是两个数据字。
AIC23作为数据接口的主器件,为DSP提供发送接收时钟,以及帧同步信号,在帧同步信号的下降沿开始传送数据,左通道数据组成了首先传送的数据字,紧接着传送右通道的数据。
传送字长32位,其中左通道数据16位,右通道数据16位。
BCLK在主动方式下是输出,而在从动方式下是输入。
在LRCIN或LRCOUT的下降沿开始数据传输。
DSP为了接收正确的语音数据,应该将串口的数据格式配置为与AIC23相同。
帧同步脉冲高电平有效。
接收、发送时钟CLKR、帧同步信号由外部时钟驱动。
其中帧同步信号宽度是1个BCLK时钟宽度。
帧周期为32个BCLK时钟。
在CLKR的上升沿,发送或采样接收数据。
DSP模式下的数据传输时序入下:
(3)语音数据存储模块
考虑到存储器芯片的容量、系统供电、以及对语音信号的读取速率。
本系统采用了具有32MX8位存储空间的K9F5608Nandflash。
Nandflash以容量大价格低的优势被广泛应用在便携式设备中。
同时Nandflash存储器在写入时需要复杂的操作命令,这样确保了数据写入的正确性。
K9F5608有8位I/O端口,地址、命令字以及数据复用这8位I/O端口。
它采用复杂的操作顺序来区分地址、命令、数据信息。
DSP采集到的32位语音数据通过外部数据总线的低8位分4次,从左声道的高8位到右声道的低8位依次写入Nandflash。
(4)液晶屏显示模块
对于DSP来讲LCD是典型的慢速设备,如果仅仅靠设置DSP等待周期寄存器,在访问外部I/O时最多只能插入14个等待周期,这点延时对DSP来说是远远不够的。
因此,需要在DSP与LCD之间加入时序控制电路。
与Nandflash模块类似,液晶屏、Nandflash与DSP的接口电路由CPLD来完成,液晶屏占用DSP两个I/O地址,分别是命令和数据地址。
DSP对I/O空间的操作由地址线、数据线和三根信号线IOSTRB、R/W和IS来完成[4]。
CPLD根据DSP给出的读写信号以及地址信号,产生液晶屏的片选、读写信号、以及键盘的扫描信号。
4软件设计
系统的软件开发环境是TI公司的DSP集成开发环境CCS2.0。
CCS提供了软件开发、程序调试和系统仿真环境。
CCS不但能支持汇编语言,而且还支持C/C++语言进行软件开发。
CCS提供的C编译器能优化代码,提高C程序的运行效率。
系统有两种工作方式,一种是现场采集并播放,即系统采集现场的线路输入信号或麦克语音信号,并存储在NandFlash中,在采集的过程中,同时通过耳机播出。
另一种是播放录制的语音数据,即不采集现场语音信号,直接播放已经存储在NandFlash中的语音数据。
这两种工作方式可以在系统初始化工程时通过按键选择。
具体的程序代码段设计主要包括MCBSP口的配置、AIC23的初始化、NandFlash烧写、DSP上电自举,这四个部分。
其中现场采集、播放的流程图如下:
(1)MCBSP的配置
5416提供的MCBSP口是一种高速、双向、多通道带缓冲的串行接口。
它可以与其他C54xDSP器件、编码器或其他串行接口器件通信。
MCBSP的硬件部分是基于标准串行接口的[3]。
MCBSP的控制模块包括帧同步信号发生器、内部时钟发生器、以及它们的控制电路和多通道选择。
与MCBSP有关的控制寄存器是通过子地址寻址来访问的,它有28个子寄存器只占用一个DSP内存地址。
MCBSP的子地址寄存器(SPSA)用来指向这些使用同一个内存地址的寄存器中的某一个。
MCBSP子数据寄存器(SPSDx)用来访问选中的寄存器。
由于配置每个寄存器的代码段相同,首先指定子地址寄存器地址,接着给数据。
为了保证程序的简洁与可读性,这里采用调用函数的方法来替代这些重复代码,代码具体实现如下:
#defineMCBSP1_SET(add,data)
MCBSP1_SPSA=add,MCBSP1_SPSD=data//定义一个宏函数,第一个参数add为子地址寄存器的地址,data为子地址寄存器的值
MCBSP1_SET(SPCR1,0x1801)
//SPCR1=0x1801
MCBSP1_SET(SPCR2,0x03C1)
//SPCR2=0x03C1
(2)AIC23的初始化
AIC23具有8个可编程的内部寄存器,通过软件编程能随时控制AIC23的采样频率,高、低通滤波器的截止频率,模拟输入及输出的增益。
DSP通过串口1完成对AIC23的初始化工作。
程序中把对AIC23的初始化命令写在一个数组中,采用循环方式将这些命令通过串口发送出去。
codec[10]={0x1e00,0x0c00,0x0811,0x0a04,0x0e43,0x102c,0x1201,0x0117,0x05ff,0x07ff};
MCBSP1_DXR1=codec[i];
(3)DSP上电自举
当软硬件设计工作完成后,需要系统能够脱离PC机独立运行。
这就需要将调试好的.out烧写到外部Flash中,并要求目标系统上电后可自行启动并执行用户软件代码,这就需要用到DSP的自举引导(Bootloader)技术。
这里采用的是16位并行Flash引导方式。
使用Hex500.exe将.out文件转换成16进制的自举表文件,通过烧写器将这个自举表文件烧写到flash中。
然而,这种脱机烧写不能烧写贴片封装的芯片,系统的灵活性受到很大的限制。
本设计采用了一种新的一次装载程序并烧写的在线烧写方法。
用Hex500.exe生成好自举表文件后,另外跟据Flash的编程方法,编写烧写代码,并读取自举表文件。
在C程序源码中读取的自举表文件是ASCII值,因此需要在程序中加一段格式转换代码,将数据转换成二进制文件,并且去掉自举表的表头和表尾。
转换时采用一个4次循环,先读取4位16进制数的最高位,把这个ASCII值转换成二进制数字,将其左移4位,接着读取次高位。
循环4次便得到了可以直接烧写的数据。
系统脱机工时,通过外部并行总线,用DMA方式将这些代码从数据空间搬移到程序空间中。
三、实践步骤
1.实验准备:
⑴连接实验设备
⑵准备音频输入、输出设备。
①用PC机的媒体播放器选择一段音乐循环播放。
②用音频线连接PC机声卡的SpeakerOut到5416-A板的J5插座,即上图中“麦克风输入”。
③将耳机上音频输入插头插到5416-A板的J7插座,即上图中“立体声输出”。
④调节耳机上音量旋钮到适中位置。
2.设置CodeComposerStudio3.3在硬件仿真(Emulator)方式下运行
3.启动CodeComposerStudio3.3:
选择菜单Debug→ResetCPU。
4.打开工程文件:
工程目录为:
C:
\ICETEK\VC5416Ae\VC5416Ae\Lab0701-Echo\Echo.pjt。
5.编译、下载程序,选择菜单Debug->GoMain,使程序运行到main函数入口位置。
6.设置观察窗口:
打开源程序Echo.c,将变量bEcho、nCount和nTime加入观察窗口。
7.运行程序观察结果:
-按“F5”键运行,注意观察窗口中的bEcho=0,表示数字回声功能没有激活。
-这时从耳机中能听到麦克风中的输入语音放送。
-将观察窗口中bEcho的取值改成非0值。
-这时可从耳机中听到带数字回声的语音放送。
8.退出CCS
四、心得体会
通过这次的DSP课程设计,让我充分认识到了我的不足。
我虽然学习过C语言的编程,但一旦将它应用到实际的比较专业的问题上,我所学的知识就变得完全不够用了,为了这次课程设计我查询了大量的资料,无论是C语言方面的还是其他方面的都让我们花费了很多时间,查询到了需要的资料我们又对它们进行了整理,提取出我们需要的a律压缩和μ律压缩的算法和原理,并且努力去理解其中的知识,使其能为我们所用,尽管如此我们仍然没能成功的编出属于我们自己的程序,因此我们找到了一份编好的程序,用我们已经理解的知识去分析它,理解这份程序的原理,并根据我们的实际对它进行一些修改,从而我们才得出我们现在的程序。
虽然程序编写成功了但我们在调试上又遇到了很多的问题,比如在CCS环境下我们要如何观察波形,波形有代表什么等等,为此我们又不断的翻阅课件和资料,才最终解决了所有的问题,我的课程设计才算基本完成了。
整个课程设计过程中,我在不断的查阅资料和开动脑筋过程中,锻炼了我的资料采集能力,也锻炼了我的分析整理能力,为以后做毕业设计打下了基础;同样在实验过程中我遇到很多困难,而这些困难则锻炼了我的耐心和分析解决问题的能力;通过编程锻炼了我的编程能力,使我对C语言,汇编语言更加熟悉,让我能更好的运用它们;同时也锻炼了我们的团结协作能力,为将来走入社会能更好的工作打下了基础。
总之通过这次的实验,让我认识到了自己的不足,同时又通过这次的实验让我们学到了让我们受用一生的知识。
参考文献
[1]戴明桢等编著.TMS320C54XDSP结构原理及应用.北京:
航空航天大学出版社,第2版,2007;
[2]彭启琮编著.DSP技术的发展与应用.北京:
高等教育出版社,2002;
[3]胡广书编著.数字信号处理理论、算法与实现.北京:
清华大学出版社,2005;
[4]北京合众达电子技术有限公司编著.SEED-DTK系列实验手册.北京合众达电子技术有限公司出版,2007。
[5]邹彦主编.DSP原理及应用.电子工业出版社,2012.1
附录:
源程序代码
#include"scancode.h"
#include"myapp.h"
charConvertScanToChar(unsignedcharcScanCode);//将键盘扫描码转换为字符
#defineREGISTERCLKMD(*(unsignedint*)0x58)
#defineWAITSTATUS(*(unsignedint*)0x28)
#defineSOUNDBUFFERLENGTH0x0f000
unsignedintnSoundNumber,bPlayBack,bRecord,nCurrentSound,js,bls,bStop,bLongEnough;
#pragmaDATA_SECTION(uSound,".sound")
unsignedintuSound[SOUNDBUFFERLENGTH];
ioportunsignedintport0000;
ioportunsignedintport8000;
ioportunsignedintport8001;
ioportunsignedintport8002;
ioportunsignedintport8007;
voidmain(void)
{
inti,j;
unsignedintnScanCode,nScanCode1;
unsignedcharcKey;
port8000=0;port8000=0x80;port8000=0;
port8007=0;port8007=0x40;i=port8002;
REGISTERCLKMD=0;
WAITSTATUS=0x0ffff;
js=nSoundNumber=bPlayBack=bRecord=nCurrentSound=bls=bStop=0;
for(i=0;iinitCLK(CPU_SPEED_160M);
initMcBSP1();
initAIC23();
initMcBSP0();
initInterrupt();
initVal();
REGISTERCLKMD=0x1007;
for(i=0;i<2048;i++)nScanCode++;
DesableInterrupt();js=0;bStop=1;bLongEnough=0;
port0000=1;
for(;;)
{
if(bls)
if(bPlayBack==0)
{
DesableInterrupt();
bls=0;
js=0;
bStop=1;
}
if(js==0)
{
nScanCode1=port8001;
for(i=0;i<1024;i++);
nScanCode=port8001;
nScanCode&=0x0ff;
if(nScanCode!
=0&&nScanCode!
=0x0ff)
{
if(nScanCode==SCANCODE_Enter)break;
else
{
cKey=ConvertScanToChar(nScanCode);
switch(cKey)
{
case'0':
//录音
if(bRecord)
{
bRecord=0;