回复: 毕业设计论文-单片机在语音播放与图片显示中的应用
5 系统软件设计
在软件设计上,由于语音资源存放在外部的存储器上,只能采用手动的方式播放语音。另外,需要对图片的显示,在播放语音的同时需要刷新图片,这样采用在中断中填充语音队列的方法来实现。
下面是主函数流程图:
图 5.1 主函数流程图
在主函数中首先初始化SIO,这样可以获得存储在SPR4096上的语音资源的起始地址与结束地址,这样便于语音控制。
A2000语音播放函数设计,由于语音资源存储在外扩存储器SPR4096上,语音播放采用手动播放方式。手动语音播放,关键在于语音资源的取得,需要得到语音资源的地址。下面分析一下刚刚烧录文件的数据格式,如图:
图 5.2 语音文件的数据格式
在上图的前4个字节为"SPRW"的ASCII码,主要的目的在于读取Flash中的文件作为特征码使用(请参考2.4.4节索引表部分),在接下来的4个字节为整合后文件的起始地址00 00 00 56(由于SPR4096的最大地址为0x7ffff,所以使用4个字节标识,即两个字的长度),然后是整合后文件的结束地址。整合的概念,就是将多个资源小文件通过特定的数据格式编成一个索引表加在资源文件的开始,然后是资源文件1,资源文件2……ResWriter工具在用户打开文件时自动的完成上述过程,称为整合。ResWriter工具是对整合后的文件进行烧录。在接下来2个字节(00 01)的数据表示整合的文件有1个资源。
以上是整合后文件的一些信息,再接下来分别是添加的语音资源的长度信息,文件起始存储地址,文件结束存储地址。在本例编程中主要关心的就是语音资源文件起始地址、结束地址。由图 5.2可见第一个文件(未整合的)的起始地址存放在0x0012、0x0013(第13、14个字节),在程序中可以依次求得语音资源。参考下面手动播放语音的函数。
ulCon_AddrHighest = SP_SIOReadAByte(BASE_START_ADDRESS + SndIndex*12); // 第一个播放文件地址
ulCon_AddrHighest = ulCon_AddrHighest << 24;
ulCon_AddrHigh =SP_SIOReadAByte(BASE_START_ADDRESS + SndIndex*12+1);
ulCon_AddrHigh = ulCon_AddrHigh << 16;
ulCon_AddrLow = SP_SIOReadAByte(BASE_START_ADDRESS + SndIndex*12+2);
ulCon_AddrLow = ulCon_AddrLow << 8;
ulCon_AddrLowest = SP_SIOReadAByte(BASE_START_ADDRESS + SndIndex*12+3);
ulCon_StartAddr = ulCon_AddrHighest | ulCon_AddrHigh // 开始地址
| ulCon_AddrLow | ulCon_AddrLowest;
其中BASE_START_ADDRESS定义为0x0012,每个地址采用4个字节存储,在分别取得地址后通过移位然后或操作得到地址。参数SndIndex是由调用函数传递过来的,意义在于使用第几段语音资源。比如使用第一段语音资源,那么传过来0就可以了,与采用自动方式播放语音类似。BASE_START_ADDRESS 是整合后文件的信息长度,在取得整合前文件的信息的时候要跳过这一段数据,即BASE_START_ADDRESS + SndIndex*12为第一段整合前数据文件的起始地址的最高字节(地址采用4个字节表示)。
SPCE061A播放语音的原理如图 5.3所示:
图 5.3 使用SPCE061A实现播放语音
手动播放语音的实现,如图 5.4所示:
图 5.4 手动播放语音
语音播放的解码部分放在1KHz的中断中进行,这样可以在播放语音的时候不影响图片的显示。
在中断中的函数代码如下:
void BMP_Play_IRQ_Service(void)
{
IRQ1KHz_Couter++; //Counter自加1,用于计时,在主函数中判断时间到
while(SACM_A2000_TestQueue() != 1)
{
if(ulCon_StartAddr >= ulCon_EndAddr)
{
ulCon_StartAddr = ulStart_Save;
SACM_A2000_Initial(0); //放音初始化
SACM_A2000_InitQueue();
SACM_A2000_InitDecoder(3);
}
uiRet = SP_SIOReadAWord(ulCon_StartAddr);
SACM_A2000_FillQueue(uiRet);
ulCon_StartAddr++;
ulCon_StartAddr++;
}
SACM_A2000_Decoder();
*(unsigned int *)0x7012 = 0x0001;
}
如果解码队列为空,那么进行填充队列操作,否则只进行解码操作,然后请看门狗退出中断。
6 验证方案
步骤一:使用10Pin排线将SPR模组与61板的正电源、IOB0、IOB1、负电源对应相连,61板I/O口选择3.3V。
步骤二:使用EZ-probe与SPR模组EZ-probe接口相连。
步骤三:按照下图设置SPR模组跳线:
图 6.1 跳线设置
步骤四:启动ResWriter工具,打开语音文件想大声说爱你.16K(SPR Module配套资料\SPR Module Demo\SLAMDUNK\voice路径下),点击自动烧写按钮。如图:
图 6.2 打开语音文件
图 6.3 打开语音文件后ResWriter工具视图
图 6.4 点击自动烧写工具按钮
图 6.5 自动烧录过程
图 6.6 自动校验过程
图 6.7 完成自动烧录
注意:如果没有正确烧录,那么主要的原因是电源没有接入或者跳线选择错误。
步骤五:按照下图选择跳线:
图 6.8 跳线选择
步骤六:将液晶模组、SPR模组与61板按照下图连接起来,如图:
图 6.9 硬件连接图
步骤七:使用IDE将工程文件(SPR Module配套资料\SPR Module Demo\SLAMDUNK路径下)下载到61板上运行,现象是同时播放声音与图片(无需任何操作)。
注意:如果没能听见语音播放,请注意硬件连线喇叭是否接好,跳线是否设置好。
7 结语
通过上面的应用方案可以看到,在需要存储大量资源包括语音资源可以采用凌阳科技有限公司的存储器来解决。凌阳科技推出的存储器保存资料安全可靠,配备可视化工具使用方便。在与单片机相连时采用并行串行可选的方式传递数据,给用户带来了极大的方便。在方案中看到通过工具烧录的资源可以通过索引表来使用语音资源,而且可以播放语音资源,进行语音的录放,在不同的压缩格式中都可以较长时间的播放语音。在需要显示图片的时候可以考虑使用凌阳科技提供的SPLC501液晶,而且已经有了底层驱动程序,用户只需要直接调用显示函数即可完成显示。
8 参考文献
[1] 罗亚非.凌阳16位单片机应用基础[M]. 北京:北京航空航天大学出版社,2003
[2] 凌阳大学计划网站
www.unsp.com.cn