资源描述:
《基于SPCE061A的语音播放系统设计【毕业论文】》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库。
本科毕业设计(20届)基于SPCE061A的语音播放系统设计摘要 随着信息技术的快速发展,人们在寻求一种更为直接的人机信息互换方式,其中语音播放就是最直接最有效的方式之一。语音播放就是让仪器能够用语音的方式告知目前的动作。在传统的语音播放系统应用当中,大部分被应用于音乐的播放。但随着信息的快速发展,人们对于信息获取及时性、方便性的要求也越来越高,因此在很多的公共交通服务系统以及防盗报警系统中就被广泛得应用,也因此语音播放系统越来越受到设计者的广泛采用。开发带有语音功能的产品通常是单片机加专用语音芯片来完成,这样既增加成本,又延长了开发时间。而具有强大语音功能和编程方便的凌阳系统单片机就克服这些问题。此次课题设计的语音播放系统就是基于凌阳SPCE061A单片机而开发的。利用SPCE061A开发板以及unSP开发工具,通过单片机C语言编程,实现对预先存储的语音信号,通过开发板上的微型喇叭进行播放。语音播放的模式有两种,一个是自动模式,还有一个是手动模式,我分别在这两种模式下,将语音播放出来,同时在加上按键,通过按键来调出语音资源。同时还清楚语音播放系统的发展动向,对其在各个领域的应用有极其重要的意义,而且具有十分重要的应用价值和良好的市场前景。关键词:语音播放;应用;SPCE061A AbstractWiththerapiddevelopmentofinformationtechnology,peoplearelookingforamoredirectwayofhuman-computerexchangeofinformation,includingaudioplaybackisthemostdirectoneofthemosteffectiveway.Voiceplaybackistolettheinstrumentcantellthewaywithvoice-currentaction.Intheapplicationoftraditionalvoiceplaybacksystem,themajoritybeingusedinmusicplayback.Butwiththerapiddevelopmentofinformation,peopleaccesstoinformationinatimelymanner,conveniencerequirementsaregettinghigherandhigher,soalotofpublictransportservicesinthesystemandburglaralarmsystemshavebeenwidelyapplied,andthereforemorevoiceplaybacksystemandmorewidelyusedbydesigners.Withavoice-enabledproductdevelopmentisusuallydedicatedvoicechipmicrocontrolleraddedtocomplete,thenitwillincreasecosts,andextendthedevelopmenttime.TheprogramhaspowerfulfunctionsandconvenientvoiceSunplussystemmicrocontrollertoovercometheseproblems.ThesubjectofthevoicebroadcastsystemdesignisbasedonSunplusSPCE061ASCMdeveloped.SPCE061AdevelopmentboardandunSPusingdevelopmenttools,throughthemicrocontrollerCprogramminglanguage,toachievethepre-storedvoicesignals,throughthedevelopmentofon-boardmicro-speakersforplayback.Voicebroadcastsystemisalsoclearthatthedevelopmenttrendofitsapplicationinvariousfieldsareofgreatimportance,butalsohasimportantapplicationvalueandgoodmarketprospects.Keywards:VoicePlay;Applications;SPCE061A 目录1引言12SPCE061A单片机简介22.1SPCE061A单片机22.2SPCE061A结构32.3SPCE061A的DAC音频输出42.3.1DAC音频输出通道结构42.3.2DAC音频输出特性42.4中断系统42.4.1中断类型和中断方式52.4.2中断向量和中断源52.5定时器62.5.1定时器A/B62.5.2看门清狗定时器63硬件应用73.1初识61板73.1.161板硬件框图及功能73.1.261板各功能区接口和跳线83.2键盘93.2.1键盘功能93.2.2键盘结构94程序设计104.1音频概述104.2音频压缩算法104.3播放系统设计114.4SACM_A2000自动语音播放124.4.1自动播放语音方式和流程图124.4.2SACM_A2000算法自动播放API函数134.5SACM_A2000手动播放语音144.5.1手动播放语音方式和流程图144.5.2SACM_A2000算法手动播放API函数174.6中断服务程序184.6.1中断程序设计流程184.7键盘程序194.7.1键盘程序设计流程195制作和调试226总结23致谢24参考文献25 附录1总程序代码27附录2硬件实物图片35 -35-1引言随着信息技术快速的发展,语音播放系统不仅仅应用于音乐的播放,而且在其他领域也都有着广泛的应用,尤其是在智能化电子设备上。传统的电子设备只是简单将所测量到的数据,用数码管显示出来,而在仪器设计中加入了语音系统,则可以将数据更加直接,形象地表现出来。例如将语音播放系统应用于电阻测量仪中,在传统的电阻测量仪的基础上,加入了语音播放系统,这样一来,电阻测量仪测量的数据,不仅仅可以用肉眼看到,而且可以直接听到电阻的大小,将电阻测量仪推向了智能化的水平。这种设计理念将会成为一种潮流,会被更多的设计者所采纳,融入到设计中,将各种设备变的更加智能化。因此语音系统所涉及的领域将更加得广泛。基于单片机的语音处理系统也是目前应用的比较广泛的。由于单片机的操作简单,设计方便,容量大的特点,因此适合语音系统的设计。相比较各种单片机的特点来说,用凌阳单片机来设计语音系统是最适合的。SPCE061A是台湾凌阳公司生产的性价比很高的一款十六位单片机,使用它可以非常方便的实现语音系统的设计[1]。凌阳SPCE061A单片机自带双通道DAC音频输出DAC1和DAC2,DACl、DAC2转换输出的模拟量电流信号分别通过AUDl和AUD2管脚输出,DAC输出为电流型输出,经LM386音频放大,即可驱动喇叭放音,在DACl、DAC2后面接一个简单的音频放大电路和喇叭,就实现语音播放功能[2]。此次课题旨在利用SPCE061A开发板以及unSP开发工具,通过单片机C语言编程,实现对预先存储的语音信号,通过开发板上的微型喇叭进行播放。同时还要清楚语音播放系统的发展动向,对其在各个领域的应用有极其重要的意义,而且具有十分重要的应用价值和良好的市场前景。 -35-2SPCE061A单片机简介2.1SPCE061A单片机SPCE061A是台湾凌阳科技公司推出的一款16位SOC的单片机,广泛应用于嵌入式系统和控制系统当中,特别是在语音处理上,优势尤其明显。它采用高性能的unSP内核,具有丰富的硬件资源,并集成了ICE电路接口,可以直接利用该接口对芯片进行下载、仿真、调试等操作。在unSP集成开发环境下,可采用汇编语言和标准C语言开发各种应用程序,同时也可以实现C语言和汇编语言的互相调用。SPCE061A是继μ’nSP™系列产品SPCE500A等之后,凌阳科技推出一款16位结构的微控制器。与SPCE500A不同的是,在存储器资源方面考虑到,用户对较少资源的需求以及便于程序调试等功能,SPCE061A里只内嵌32K字的闪存(FLASH)。较高的处理速度使μ’nSP™能够很容易地、快速地处理复杂的数字信号。因此,与SPCE500A相比,以μ’nSP™为核心的SPCE061A微控制器是适用于数字语音识别应用领域产品的一种最经济的选择。SPCE061A的语音处理功能是由凌阳科技自行开发的,具有音频编码和解码以及语音压缩算法。各种算法对应的程序模块都存放在语音算法SCAM-LIB中,使用时只需调用相应的模块就可以方便地实现语音合成、语音播放、录音、识别等功能。因此SPCE061A是一款适合语音系统设计的开发工具[3]。μ’nSP™内核是一个通用的核结构。除这以外的其它模块。均为可选结构,也就说这种结构可大可小或可有可无。通过这种通用结构再加可选结构的积木式的构成,便可形成各种不同系列的生产品,以适应不同的应用场合。这样做无疑会使每一种生产品具有更强的功能和更低的成本。 -35-2.2SPCE061A结构图2-1SPCE061A的结构如上图2-1所示的SPCE061A的结构。凌阳SPCE061A内部以unSP16位微控制器为核心,集成了ICE(在线仿真)、Flash存储器(闪存)、SART(静态内存)、通用I/O端口、定时器/计数器、中断控制、CPU时钟、锁相环(PLL)振荡器、双通道10位DAC(数字/模拟转换器)等模块。SPCE061A单片机的技术特性如下:1、工作电压范围:(CPU)VDD为3.0一3.6V,(I/O)VDDH为VDD-5.5V2、系统工作频率范围:0.32一49.152MHZ3、数据存储器:2K字SRAM4、程序存储器:32K字FlashROM5、模/数转换器:7通道10位ADC和单通道10位声音ADC6、数/模转换器:2个10位DAC输出通道 -35-7、具有红外通信功能:可对红外信号进行接收或发送14个中断源来自系统时钟,定时器/计数器,时间基准发生器,外部时钟源输入,触键唤醒以及通用异步串行接口等8、掉电方式下的系统运行可将功耗降至5V电源电压下的2uA9、具有运行在睡眠方式下的看门狗维护功能[4]2.3SPCE061A的DAC音频输出2.3.1DAC音频输出通道结构SPCE061A为音频输出提供DAC1和DAC2两个通道,分别由AUD1和AUD2这两个引脚输出。DAC的输出范围为0x0000-0xFFFF。DAC1和DAC2的输出数据应分别写入P_DAC1(写)(0x7017)和P_DAC2(写)(0x7016)单元[5]。DAC1和DAC2均为10位D/A转换单元。在DAC方式下,该单元均为10位的缓冲寄存器DAR2/DAR1。P_DAC1(写)/P_DAC2(写):通过此两单元直接写入10位数据到10位寄存器DAR1/DAR2,锁存相应DAC的输入数据。P_DAC1(读)/P_DAC2(读):从DAR1/DAR2内读出10位数据。2.3.2DAC音频输出特性DAC数模转换器,用作SPCE061A的音频输出设备。通常DAC的最大输出电流与Vdd成正比,DAC的最大输出电流范围是“正常电流值*(1+10%)”。在得知DAC的最大输出电流后,模拟电压输出范围将由DAC负载决定。由于DAC本身的物理特性,最大输出电压将比Vdd低0.3—0.4V[6]。2.4中断系统中断是为处理外界异步事件而设置的。中断技术将计算机的发展和应用推到了一个新的领域。因此中断功能的强弱已经成为衡量计算机性能的重要指标之一。SPCE061A的中断系统功能较强,提供14个中断源,具有2个中断优先级,可实现两级中断嵌套。用户可通过关中断指令来屏蔽所用的中断请求;通过开中断指令来允许CPU接受中断申请。 -35-2.4.1中断类型和中断方式SPCE061A的中断分为软件中断、异常中断和事件中断三种类型。1异常中断异常中断用于监测非常重要的事件,这类事件一旦发生,CPU必须立即处理。目前SPCE061A定义的异常中断只有RESET一种。2软件中断软件中断是由软件指令产生的中断,软件中断的中断向量地址为FFF5H。3事件中断事件中断一般发生在芯片内部或输入引脚引入的某个事件中。这种中断允许/禁止由独立使能控制和相应IRQ或FIQ总能控制。SPCE061A的事件中断采用快速中断请求(FIQ中断)和中断请求(IRQ中断)两种方式。2.4.2中断向量和中断源SPCE061A中断系统共有9个中断向量,即FIQ、IRQ0—IRQ6和UARTIRQ,这9个中断向量可安置14个中断源。其中3个中断源安置在IRQ0-IRQ2或FIQ,另外10个中断源安置在IRQ3-IRQ6中。还有1个专门用于UART串行端口的中断源,必须安置在UARTIRQ向量中。中断源可分为5种:1、定时器溢出中断:由SPCE061A内部定时器中断源产生,属于内部中断。SPCE061A内部有2个16位定时器/计数器(TimerA和TimerB)。TimerA和TimerB在定时脉冲的作用下从预置数开始加计数,当计数累计到“0XFFFF”时,可以自动向CPU提出溢出中断请求,表示TimerA或TimerB定时时间已到。2、外部中断:SPCE061A有EXT1和EXT2两个外部中断。其信号输入分别与B端口IOB2和IOB3共享引脚。 -35-3、串行口中断:由SPCE061A内部串行口中断源产生,属于内部中断。串行口中断分为两种中断:串行口发送中断和串行口接收中断,并且这两个中断共一个中断向量。4、触键唤醒中断:在系统处于睡眠状态时,IOA端口低8位的触键信号可唤醒系统,将系统恢复为工作状态。5、时基信号中断:时基信号发生器的输入信号来自32768Hz实时时钟,输出信号有通过选频逻辑TMB1、TMB2信号和直接从时基计数器溢出而来的各种实时基信号。2.5定时器2.5.1定时器A/B定时器中断包括定时器A中断和定时器B中断。定时器A、B中断源不但在FIQ中断方式中有,而且在IRQ1、IRQ2中断方式中也有。TimerA的时钟源是由两个时钟源CLKA和CLKB经过一个逻辑与门相与而成的,TimerB的时钟源只有CLKA。2.5.2看门清狗定时器看门狗(WatchDog)用于监视系统是否正常工作。当系统正常运行时,每隔一定的周期就必须清除WatchDog计数器。如果在限定的时间内,WatchDog计数器没有被清除,CPU就会认为系统已经无法正常工作,将会强行进行系统复位。SPCE061A的WatchDog的清除时间周期为0.75s。要清除WatchDog,只需要将“xxxxxxxxxxxxxx01B”写入P_WatchDog_Clear(写)(0x7012)单元即可。 -35-3硬件应用3.1初识61板"61板“是SPCE061AEMUBOARD的简称,是以台湾凌阳科技16位单片机SPCE061A为核心的精简开发-仿真-实验板,也可以说是16位单片机SPCE061A的开发系统。“61板”包括电源电路、程序下载电路、音频电路(含MIC输入部分和DAC音频输出部分)、SPCE061A单片机最小系统电路、复位电路、按键、输入输出口引脚插针等。凌阳科技提供的集成开发环境IDE,安装在Windows系统的计算机中,并支持凌阳16位单片机汇编语言、C语言开发,也支持C语言和汇编语言的结合开发。利用61板和安装在计算机中的集成开发环境IDE,可以建立凌阳16位单片机SPCE061A的软、硬开发环境,轻松实现源程序的编辑、编译、链接功能,下载到芯片就可以仿真运行。3.1.161板硬件框图及功能61板共分为7个功能区,分别是电源区、程序下载区、音频区、SPCE061A与周围区、键控区、复位区和端口区。(1)电源区:为整个单片机开发系统提供电源,只要将3节5号电池放入系统配套的电池盒,就可以满足供电需求。(2)程序下载区:通过该区域的接口,将程序下载到单片机SPCE061A中;同时,在进行在线调试时也把一些硬件信息上传到计算机的开发环境中。(3)音频区:61板具有强大的语音处理功能,这里有一个传声器,用于进行语音输入,还有一个扬声器接口,可以外接一个扬声器,进行语音输出。(4)SPCE061A与周围区:这是整块板的中心区,所有控制信息都是从这里输出去的,用于确定某些周边器件是否协助单片机SPCE061A正常工作。 -35-(5)键控区:一共有三个按键,分别是KEY1、KEY2和KEY3。采用按键,可以做一些简单的按键实验。(6)复位区:由几个简单的电子元器件组成。当按下该按键后,单片机就会重新开始工作;或者说单片机里的程序就会从第一条开始重新运行。(7)端口区:用于对扩展的外部硬件电路进行控制,或者获取外部硬件的一些状态,以便单片机SPCE061A进行处理。3.1.261板各功能区接口和跳线在61板有功能区外,还有许多接口和跳线。(1)电源区接口J10和跳线J5J10是61板电源接口,通过该接口,可以外接5V的直流稳压电源;J5是端口电压选择跳线,61板的内核SPCE061A电压要求为3.3V;而IO端口的电压可以选择3.3V,也可以选择5V。所以,在板子上共存两种工作电压:3.3V和5V,这两种电平通过跳线J5,按照实际情况来选择。(2)下载区接口J11、J4和跳线S5J11是一个5针的EZ_PROBE接口。61板配套下载线一端5针接口连接到61板的J11口,另一端连接计算机的25针并行口。J4是一个5针的PROBE接口,其中在线调试器PROBE又分为Printer_PROBE和USB_PROBE。S5是61板程序下载方式选择跳线,61板可以选择EZ_PROBE(配套下载线)和PROBE(在线调试器)两种方式下的程序和仿真调试,主要是靠接口S5来进行选择的。(3)音频区接口X1、J3、J13和跳线J2X1是驻极体传声器,与单片机SPCE061A的单通道10为声音ADC引脚连接。录音时,语音就是从这里输入的。J3是2个插针的语音输出接口,可以外接扬声器,从单片机SPCE061A的DAC输出的语音信号经语音集成放大器SPY0030放大后,然后输出到扬声器中。J13是单片机SPCE061A音频DAC2输出插针,如果需要,可以外扩音频电路。 -35-J2是D/A输出选择接口。(4)SPCE061A与周围区J1J1为A/D输入电压选择接口,有2个插针分别以“VREF”和“VRT”为标识。3.2键盘3.2.1键盘功能采用区内的按键,可以做一些简单的按键实验,例如在做语音处理实验中,采用按键可分别进行录音、暂停和播放;在做语音万年历实验中,按键可以用来设定初始时间和控制播放当前时间等操作。本次设计中采用按键来调用语音资源。设置了两个按键,KEY1和KEY2,分别用于调用语音资源1和语音资源2。即当按下KEY1按键,系统将自动调取出语音资源1来进行解码。KEY2的作用跟KEY1相同。3.2.2键盘结构键盘电路与单片机的IO口连接,单片机应能识别是否有按键按下,按下的是哪个按键,并且把该按键代表的信息翻译成单片机能识别的编码[7]单片机可以采用的键盘有全编码键盘和非编码键盘两种。全编码键盘是由硬件电路自动提供与被按键对应的编码,它还有去抖动和多键、蹿键保护电路。非编码键盘只提供按键电路,其他如按键的识别和按键编码都是由软件来完成的。它具有结构简单、使用灵活、经济实用等特点。一般系统设计都采用非编码键盘。单片机键盘接口电路(含键盘控制程序)能够完成的任务:1、能识别有无按键按下;2、有按键按下后,在没有硬件去抖动的时候,要有软件程序来消除按键抖动的影响。3、正确的获取按键取值,并根据按键值作相应的处理。 -35-4程序设计4.1音频概述音频是个专业术语,人类能够听到的所有声音都称之为音频,音频的频率在20Hz-20kHz这范围之间。具体可分为波形声音、语音和音乐三种形式。波形声音就是自然界中所有的声音,是声音数字化的基础。语音是对讲话声音的一次抽象,是语言的载体,是人类社会特有的信息系统之一。音乐是被形象化的声音,比语音更加规范。音频信号数字化是指将模拟的(连续的)声音波形进行数字化(离散化),变成数字音频,以便于计算机处理。数字化主要包括信号采样和量化两方面内容。数字音频的质量取决于采样频率和量化位数。4.2音频压缩算法语音压缩可分无损压缩和有损压缩。无损压缩是指使用压缩后的数据进行重构,重构后的数据与原来的数据完全相同。无损压缩一般指磁盘文件,压缩比低,为2:1-4:1。有损压缩是指使用压缩后的数据进行重构,重构后的数据跟原来的不一样,但不影响人们对原来数据的正确理解。有损压缩则是指音/视频文件,压缩比高达100:1。凌阳音频压缩算法根据不同的压缩比可分为波形编码(SACM-A2000)、混合编码(SACM-S480)、参数编码(SACM-S240)。1、波形编码(SACM-A2000)压缩比为8:1、8:1.25、8:1.5,特点:高质量、高码率、适于高保真语音/音乐。2、参数编码(SACM-S240)压缩比为80:1.5,特点:压缩比大,计算量大,廉价但音质不高。3、混合编码(SACM-S480) -35-压缩比为80:3.80:4.5,特点:综合参数和混合的特点。按音质排序:A2000>S480>S240[8]。4.3播放系统设计语音播放就是语音录制的逆过程,就是把经过压缩编码的语音数据还原成声音的过程。如图4-1为语音播放过程图。图4-1语音播放过程图语音资源的获取:通过计算机自带的录音机录制一段语音,并以*.WAV的格式保存。并通过凌阳科技提供的一个语音压缩工具,将*.WAV格式的语音文件压缩成凌阳的A2000或是S480的语音资源。语音播放过程:1、数据提取顺次从压缩格式的语音资源中取出一组数据,放到解压缩队列里,等待解压。2、数据解码执行解码程序,把压缩数据还原成数字量的语言信号,送到输出队列,等待输出。3、转换为模拟信号在定时中断的控制下,将数字量转换成模拟信号量。4、转换成声音模拟信号再经过滤波、放大等处理,最好通过扬声器转换成声音[9]。 -35-4.4SACM_A2000自动语音播放4.4.1自动播放语音方式和流程图SACM-A2000压缩算法压缩率比较小,并且具有高质量、高码率的特点,适于高保真语音/音乐,所以本次设计采用压缩算法就是SACM-A2000。SACM-A2000音频算法提供了两种播放模式:自动播放和手动播放。采用自动播放模式,只要在初始化设置为自动方式。一般的播放过程包括取数据、填充语音队列(解压缩队列)、解压缩、输出播放4个阶段。而选择自动播放时,取数据、填充语音队列及解压缩只需调用SACM_A2000_ServiceLoop()一个函数就可以完成[10]。自动播放流程图4-2如下:图4-2自动播放流程图如下为自动播放函数:voidPlaySnd_Auto(unsignedintuiSndIndex,unsignedintuiDAC_Channel){//初始化语音播放,自动方式SACM_A2000_Initial(1);//播放语音SACM_A2000_Play(uiSndIndex,3,3); -35-//判断当前是否在播放?返回最低,为1则表示当前播放while(SACM_A2000_Status()&0x0001)//取语音压缩码并解压缩填充队伍{SACM_A2000_ServiceLoop();*P_Watchdog_Clear=0x0001;}//停止SACM_A2000_Stop();4.4.2SACM_A2000算法自动播放API函数(1)初始化函数【格式】C:intSACM_A2000_Initial(intInit_Index)ASM:R1=[Init_Index]CallF_SACM_A2000_Initial【功能】SACM_A2000语音播放之前的初始化。【参数】Init_Index=0,表示手动方式;Init_Index=1,表示自动方式。(2)播放函数【格式】C:voidSACM_A2000_Play(intSpeech_Index,intChannel,intRamp_Set)ASM:R1=[Speech_Index]R2=[Channel]R3=[Ramp_Set]CallSACM_A2000_Play【功能】播放资源中SACM_A2000语音或乐曲【参数】Speech_Index:表示语音索引号。Channel:1、通过DAC1通道播放2、通过DAC2通道播放3、通过DAC1和DAC2双通道播放Ramp_Set:0、禁止音量增/减调节1、仅允许音量增调节2、仅允许音量减调节3、允许音量增/减调节 -35-(3)获取模块状态函数【格式】C:unsignedintSACM_A2000_Status()(void)ASM:CallF_SACM_A2000_Status【功能】获取SACM_A2000语音播放状态(4)获取语音资料,填入译码队列函数【格式】C:voidSACM_A2000_ServiceLoop(void)ASM:CallF_SACM_A2000_ServiceLoop【功能】从资源中获取SACM_A2000语音资料,并将其填入译码队列中(5)停止播放函数【格式】C:voidSACM_A2000_Stop(void)ASM:CallF_SACM_A2000_Stop【功能】停止播放SACM_A2000语音或乐曲(6)中断服务函数【格式】ASM:Call_F_FIQ_Service_SACM_A2000【功能】用作SACM_A2000语音背景程序的中断服务子程序。4.5SACM_A2000手动播放语音4.5.1手动播放语音方式和流程图相比较自动播放方式,手动播放要稍微复杂一些,自动播放时,取数据、填充语音队列及解码压缩只要调用SACM_A2000_ServiceLoop()一个函数就可以完成[11]。而手动播放则不同,取数据、将数据送入解码队列、解压缩后送入播放队列这三个操作,分别用三个函数来实现。取数据需要调用的函数是Ret=SP_GetResource(Addr);填充队列要调用函数是SACM_A2000_FillQueue(Ret);解压缩和输出队列调用的函数是SACM_A2000_Decoder()[12]。SACM_A2000手动播放函数流程图4-3如下: -35-开始获取播放语音的起始地址和结束地址初始化为手动播放方式初始化语音队列初始化译码器语音队列是否已满从存储器上获取语音资料源填充语音队列指向下一个地址是否还在播放状态停止播放返回解码播放清门看狗4-3手动方式的流程图YNYN -35-如下为手动播放函数://获取要播放的语音的首地址ulAddr=*(&RES_Table+(uiSndIndex<<1));//获取要播放的语音的结束地址ulEndAddr=*(&RES_Table+(uiSndIndex<<1)+1);//播放的初始化,手动方式SACM_A2000_Initial(0);//初始化播放队列SACM_A2000_InitQueue();//初始化解码器SACM_A2000_InitDecoder(uiDAC_Channel);while(1){//播放队列是否为空while(SACM_A2000_TestQueue()!=1){//地址超出。则退出队列填充操作if(ulAddr>=ulEndAddr){break;}//从存储器中获取语音资源uiRet=SP_GetResource(ulAddr);//填充队伍SACM_A2000_FillQueue(uiRet);ulAddr++;}//当前还处到播放状态,则进行解码if(SACM_A2000_Status()&0x0001){SACM_A2000_Decoder();}else{//否则,停止播放SACM_A2000_Stop();//退出播放循环break;}*P_Watchdog_Clear=1;}} -35-4.5.2SACM_A2000算法手动播放API函数1、初始化解码队列函数【格式】C:SACM_A2000_InitQueue_InitQueue(void)ASM:CallF_SACM_A2000_InitQueue【功能】开始对SACM_A2000语音播放队列以手动方式进行初始2、译码初始化【格式】C:SACM_A2000_InitDecoder(intChannel)ASM:CallF_SACM_A2000_Decoder【功能】开始对SACM_A2000语音播放队列以手动方式进行译码【参数】Channel=1,2,3分别表示使用DAC1、DAC2通道以及DAC1和DAC2双通道[13]。3、测试语音队列状态函数【格式】C:unsignedintSACM_A2000_TestQueue(void)ASM:CallF_SACM_A2000_TestQueue[返回值]=R1【返回值】R1=0、1、2分别表示语音队列不空不满,语音队列满及语音队列空4、填充语音队列函数【格式】C:voidSACM_A2000_FillQueue(unsignedintencoded-data)ASM:CallF_SACM_A2000_FillQueue=【功能】将从用户存储区里获取SACM_A2000语音编码资料,然后将其填入语音队列中等待译码处理。【参数】encoded-data为语音编码资料5、译码函数【格式】C:voidSACM_A2000_Decoder(void)ASM:CallF_SACM_A2000_Decoder【功能】从语音队列里获取的SACM_A2000语音资料,并进行译码,然后通过中断服务子程序将其送入DAC通道播放。 -35-4.6中断服务程序4.6.1中断程序设计流程在TMA_FIQ中断源上,调用F_FIQ_Service_SACM_A2000函数完成解码播放语音[14],中断子程序流程图4-4如下:寄存器组入栈保护是否FIQ_TMA中断是否FIQ_TMB中断清中断标志寄存器出栈中断返回调用F_FIQ_Service_SACM_A2000函数清中断标志清中断标志YNNNN图4-4中断子程序流程图1、判断是否是定时器A的FIQ中断r1=C_FIQ_TMA;testr1,[P_INT_Ctrl];jnzL_FIQ_TimerA;2、判断是否是定时器B的FIQ中断r1=C_FIQ_TMB;testr1,[P_INT_Ctrl]; -35-jnzL_FIQ_TimerB;3、进入PWM中断L_FIQ_PWM:r1=C_FIQ_PWM;//清除PWM中断标志[P_INT_Clear]=r1;//出栈恢复popr1,r5from[sp];reti;4、定时器A的FIQ中断L_FIQ_TimerA://清中断标志位[P_INT_Clear]=r1;//调用A2000的音频中断服务程序callF_FIQ_Service_SACM_A2000;popr1,r5from[sp];reti;5、定时器B的FIQ中断L_FIQ_TimerB:[P_INT_Clear]=r1;popr1,r5from[sp];reti;4.7键盘程序4.7.1键盘程序设计流程调用键盘程序用来调用语音资料,设定两个按键,分别是KEY1和KEY2,KEY1用于调用语音资料1,KEY2用于调用语音资料2[15]。如下为调用函数:while(1) -35-{KeyCode=GetKey();switch(KeyCode){//调用播放程序,播放第1段语音,采用DAC1播放case1:PlaySnd_Auto(0,1);break;//调用播放程序,播放第2段语音,采用DAC1播放case2:PlaySnd_Auto(1,1);break;default:break;}开始初始化IO口调用键盘程序键值键值是否为0把键值送到IOA的低8位清门看狗YN图4-5按键流程图 -35-如上图4-5为按键的流程图。1、初始化IOA的相应端口为上拉输入*P_IOA_Dir&=~KEY_ALL;*P_IOA_Attrib&=~KEY_ALL;*P_IOA_Buffer|=KEY_ALL;2、等待有键按下,即有端口变为1while(!((*P_IOA_Data)^KEY_ALL)){*P_Watchdog_Clear=1;//清看门狗}while(KeyValue==0){KeyValue=(*P_IOA_Data)^KEY_ALL;*P_Watchdog_Clear=1;}3、等待按键抬起KeyValue=(*P_IOA_Data)^KEY_ALL;while(((*P_IOA_Data)^KEY_ALL)){*P_Watchdog_Clear=1;}returnKeyValue;} -35-5制作和调试1、制作(1)新建一个工程,在工程中建main.c文件和isr.asm文件,在两个文件中并编写主程序和中断程序。(2)复制头文件,将头文件a2000.h和a2000.inc复制到工程文件中。(3)复制支持文件,将hardware.inc、hardware.h和hardware.asm复制到工程文件中。并将hardware.asm文件添加到工程中。(4)复制语音资源文件,将之前制作好的语音资料复制到工程文件中。并添加到工程中(5)链接sacmv26e.lib库到工程中(6)在resource.asm文件中定义语音资源表和语音播放顺序。2、调试完成了上述制作过程后,执行编译。如果没有出现错误,就可以把程序下载到61板。通过外接一个扬声器,就可以把语音播放出来。按键按下KEY1,则播放第一段语音;按键按下KEY2,则播放第二段语音。通过实际测试,该设计已经可以完成原先制定的要求,成功播放语音。 -35-6总结本设计方案按照任务书的要求设计制作了一个语音播放系统,通过程序的编写和硬件的结合,达到了预期目标。这次设计是基于凌阳SPCE061A单片机而开发的。利用SPCE061A开发板以及unSP开发工具,通过单片机C语言和汇编语言两种语音的编写,实现对预先存储的语音信号,通过开发板上的微型喇叭进行播放。一开始做这个设计的时候,对于这方面的知识不是很清楚,但通过参考书籍和老师的指导下,弄清楚了其中的原理。并成功完成的语音播放系统的设计。随着信息技术的发展,电子设备趋向于智能化,在很多的电子设备中都加入了语音播放这个系统,将数据结果从原先的数码管显示出来,到现在可以用听觉听到,这样既方便了实验操作,又将设备推向更加的智能化。但由于时间有限,本设计仅仅只做了一个播放系统,并没有加入到其他设备中,这个有待在以后的学习中不断进步。 -35-致谢本次毕业设计能够顺利完成,首先要感谢我的指导老师方朝曦老师。即使平时工作繁忙,也会定期的召集我们,给我们作指导。对我们碰到的问题,都会认真仔细的指导我们,帮助我们解决问题。我还要感谢跟我一起做毕业设计的同学们,在这几个月的工作中,让我体会到团队的力量,只有同学之间的相互帮助,相互共享,我们才能在短时间内,高质量的完成任务。同时我也很感谢曾经教导过我的老师们,没有他们给我灌输的知识,我不可能有良好的基础,更不能顺利地完成设计。最后我还要感谢答辩组,你们严格认真的态度,使我能够更加认真的对待本次毕业设计,如果能顺利的通过,这将对我将来的学习起到很大的鼓励作用。在将来的工作生活中,我一定会秉持这种认真的态度,不断努力提高自我,完善自我。 -35-参考文献[1]张玉均,杨晓邦.基于SPCE061A的步进电机控制及语音播报设计[J].中国科技信息2007,(16):57-58.[2]谭永红,雷跃.基于单片机的气敏传感器测试系统[J].中国科技信息 ,2007,(6):107-109.[3]李志强,刘平,邓智慧,付勇山.基于GPS的自动语音报站系统设计[J].通信技术,2010,43(2):85-87.[4]郭迅.语音处理技术在单片机上的应用研究与实现[D].电子科技大学,2003.[5]曾鹏,林躜,朱晓燕.16位单片机的语音信号处理技术的研究[J].湖北工学院学报,2003,18(2):37-38.[6]万海峰,王慧,叶义成.基于SPCE061A语音识别技术的智能交通灯设计[J].自动化技术与应用,2009,28(11):110-112.[7]葛林,邸彩芸,艾建军.基于凌阳单片机的语音播报智能化燃气灶设计[J].中国高新技术企业,2010,(5):5-6.[8]邹飞,黄华,祝诗平.基于单片机的语音播报智能化电阻测试仪设计[J].电子测量技术,2007,30(4):127-128.[9]吴贻伟,谢汝峰.基于凌阳61单片机的智能电子密码锁[J].科技资讯,2010,(8):39-41.[10]吴书学.基于凌阳单片机的矿山铁路信号设备语音提示系统[D].江苏徐州:中国煤炭学会,2006,8.[11]张栋,徐继文,张革新,朴健浩,陈兴文.具有语音播报功能的温湿度测量仪设计[J].大连民族学院学报,2007,9(3):94-95.[12]文环明,张艳.基于SPCE061A的电子语音播报称重[J].电脑开发与应用,2007,20(12):37-39.[13]高新,张智杰,李莹.语音功能的数字转速表[J],信息技术,2007,31(11):121-123.[14]NavrajChohan,“VoiceStreamingoveraSensorNetwork,”[EB/OL],[2010-10-15],http://cs.ucsb.edu/~nchohan/vosn/vosn.pdf.[15]JavasEAPIs&Documentation[EB/OL][2007·01-08].http://java.8un.com -35-/j2se/1.3/docs/api/. -35-附录1总程序代码1、自动播放程序#include"a2000.h"#include"spce061a.h"#defineP_Watchdog_Clear(volatileunsignedint*)0x7012#defineKEY_ALL0xff00unsignedGetKey(void);intKeyCode;voidPlaySnd_Auto(unsignedintuiSndIndex,unsignedintuiDAC_Channel);//声明播报函数intmain(void){voidKey_Init(void);voidKey_Scan(void);while(1){KeyCode=GetKey();switch(KeyCode){//调用播放程序,播放第0段语音,采用DAC1播放case1:PlaySnd_Auto(0,1);break;//调用播放程序,播放第1段语音,采用DAC1播放case2:PlaySnd_Auto(1,1);break;default:break; -35-}*P_Watchdog_Clear=0x0001;}}voidPlaySnd_Auto(unsignedintuiSndIndex,unsignedintuiDAC_Channel){//初始化语音播放,自动方式SACM_A2000_Initial(1);//播放语音SACM_A2000_Play(uiSndIndex,3,3);//判断当前是否在播放?返回最低while(SACM_A2000_Status()&0x0001)//为1则表示当前播放{//取语音压缩码并解压缩填充队伍SACM_A2000_ServiceLoop();*P_Watchdog_Clear=0x0001;}//停止SACM_A2000_Stop();}//使用IOA8~IOA15作为键盘输入口unsignedintGetKey(void){unsignedKeyValue=0;//初始化IOA的相应端口为上拉输入 -35-*P_IOA_Dir&=~KEY_ALL;*P_IOA_Attrib&=~KEY_ALL;*P_IOA_Buffer|=KEY_ALL;//等待有键按下,即有端口变为1while(!((*P_IOA_Data)^KEY_ALL)){//清看门狗*P_Watchdog_Clear=1;}while(KeyValue==0){KeyValue=(*P_IOA_Data)^KEY_ALL;*P_Watchdog_Clear=1;}KeyValue=(*P_IOA_Data)^KEY_ALL;//等待按键抬起while(((*P_IOA_Data)^KEY_ALL)){*P_Watchdog_Clear=1;}returnKeyValue;}2、中断程序.INCLUDEa2000.inc.INCLUDEhardware.inc.TEXT.PUBLIC_FIQ; -35-_FIQ://寄存器入栈pushr1,r5to[sp];//判断是否是定时器A的FIQ中断r1=C_FIQ_TMA;testr1,[P_INT_Ctrl];jnzL_FIQ_TimerA;//判断是否是定时器B的FIQ中断r1=C_FIQ_TMB;testr1,[P_INT_Ctrl];jnzL_FIQ_TimerB;L_FIQ_PWM://进入PWM中断r1=C_FIQ_PWM;//清除PWM中断标志[P_INT_Clear]=r1;//出栈恢复popr1,r5from[sp];reti;//定时器A的FIQ中断L_FIQ_TimerA://清中断标志位[P_INT_Clear]=r1;//调用A2000的音频中断服务程序callF_FIQ_Service_SACM_A2000;popr1,r5from[sp];reti;L_FIQ_TimerB:[P_INT_Clear]=r1; -35-popr1,r5from[sp];reti;3、手动播放程序#include"a2000.h"#defineP_Watchdog_Clear(volatileunsignedint*)0x7012voidPlaySnd_Manual(unsignedintSndIndex,unsignedintDAC_Channel);intmain(void){voidKey_Init(void);voidKey_Scan(void);while(1){KeyCode=GetKey();switch(KeyCode){case1:PlaySnd_Manual(0,3);break;case2:PlaySnd_Manual(1,3);break;default:break;}*P_Watchdog_Clear=0x0001;}}//定义hardware.asmunsignedintSP_GetResource(unsignedlongulAddr);voidPlaySnd_Manual(unsignedintuiSndIndex,unsignedintuiDAC_Channel){ -35-//语音资源列表,在Resource.asm中定义externunsignedlongRES_Table;unsignedlongulAddr,ulEndAddr;unsignedintuiRet;//获取要播放的语音的首地址ulAddr=*(&RES_Table+(uiSndIndex<<1));//获取要播放的语音的结束地址ulEndAddr=*(&RES_Table+(uiSndIndex<<1)+1);//播放的初始化,手动方式SACM_A2000_Initial(0);//初始化解码器SACM_A2000_InitQueue();//初始化播放队列SACM_A2000_InitDecoder(uiDAC_Channel);while(1){//播放队列是否为空while(SACM_A2000_TestQueue()!=1){//地址超出。则退出队列填充操作if(ulAddr>=ulEndAddr){break;}//填充队伍uiRet=SP_GetResource(ulAddr);//从存储器中获取语音资源SACM_A2000_FillQueue(uiRet);ulAddr++;}//当前还处到播放状态,则进行解码 -35-if(SACM_A2000_Status()&0x0001){SACM_A2000_Decoder();}else{//否则,停止播放SACM_A2000_Stop();//退出播放循环break;}*P_Watchdog_Clear=1;}}//使用IOA8~IOA15作为键盘输入口unsignedintGetKey(void){unsignedKeyValue=0;//初始化IOA的相应端口为上拉输入*P_IOA_Dir&=~KEY_ALL;*P_IOA_Attrib&=~KEY_ALL;*P_IOA_Buffer|=KEY_ALL;//等待有键按下,即有端口变为1while(!((*P_IOA_Data)^KEY_ALL)){//清看门狗*P_Watchdog_Clear=1; -35-}while(KeyValue==0){KeyValue=(*P_IOA_Data)^KEY_ALL;*P_Watchdog_Clear=1;}KeyValue=(*P_IOA_Data)^KEY_ALL;//等待按键抬起while(((*P_IOA_Data)^KEY_ALL)){*P_Watchdog_Clear=1;}returnKeyValue;} -35-附录2硬件实物图片