公交车报站器设计毕业设计

南华大学船山学院毕业论文毕业设计论文公交车报站器设计毕业设计(论文)原创性声明和使用授权说明原创性声明本人郑重承诺:所呈交的毕业设计(论文),是我个人在指导教 师的指导下进行的研究工作及取得的成果 尽我所知,除文中特别加 以标注和致谢的地方外,不包含其他人或组织已经发表或公布过的研 究成果,也不包含我为获得 及其它教育机构的学位或学历而使用过的材料对本研究提供过帮助和做出过贡献的个人或集体, 均已在文中作了明确的说明并表示了谢意作者签名: 日 期: 指导教师签名: 日 期: 使用授权说明本人完全了解 大学关于收集、保存、使用毕业设计(论文)的规定,即:按照学校要求提交毕业设计(论文)的印刷本和电 子版本;学校有权保存毕业设计(论文)的印刷本和电子版,并提供 目录检索与阅览服务;学校可以采用影印、缩印、数字化或其它复制 手段保存论文;在不以赢利为目的前提下,学校可以公布论文的部分 或全部内容作者签名: 日 期: 目录1系统总体方案 51.1公交车报站器可选方案 5.1.2设计方案的可行性分析和选择 71.3公交车报站器的硬件框图 7.2系统硬件设计 82.1 SPCE061A 简介 .8.2.2系统电源设计 1.22.3语音存储电路设计 .122.4音频输出电路设计 .142.5显示电路设计 1.52.6键盘电路设计 1.63系统软件设计 173.1语音处理 1.73.2主函数流程图 1.93.3初始化函数 263.4语音播放的实现 313.5更新时间 343.6设置时间 35参考文献 48谢辞 49附录一 公交车报站器电路图 51附录二公交车报站器程序 52在当今社会,即使在私家车越来越多的今天,公交车仍然是人们出行的首选, 因为公交车具有方便、快捷、车票便宜等优点。
传统的公交车报站主要由售票员 报站,但是有些售票员有着浓重的地方口音,给外地人乘坐公交车造成了困难, 另外,随着无人售票车逐渐增多,公交车报站器就越显得重要了目前我国公交车辆己从原有的人工语音报站发展到现在的自动语音报站 就 报站语音而论,绝大多数报站装置都采用IsD系列的语音芯片,部分报站产品也 有采用最新的数字语音处理合成技术, 两者各有优缺点前者成本低,但音质较 差,且更改报站信息不灵活,当公交车辆临时改道时必须重新对语音芯片编程 ; 后者受信息容量、语音音质的限制,且更换信息仍需专业设备因此设计一款能 够方便地更换报站信息、播放高音质语音信息的公交车报站器愈显重要本方案利用单片机的语音处理功能,以及其强大的处理能力,完成语音的合 成技术,再配合存储器,扩大存储容量,很容就可以实现公交车报站器,从而为 市民提供了更加人性化的服务这些优点使得本方案成为制作公交报站器一种最 经济实用的选择第5页共74页1系统总体方案公交报站系统的设计要求报站系统可以完整地播放一条公交线路的站名 可以在显示屏上显示当前的时间,具有时间日期的设置功能,还可以播放音乐或广 告经过查阅资料,可选方案有基于 MP3/U盘的公交车报站设计,基于GPS勺公 交车报站器系统设计和基于SPCE061A勺公交车报站系统设计等•1.1公交车报站器可选方案1.1.1基于MP3/U盘的公交车报站设计方案采用AT89C51SND1单片机(内部集成MP3解码器)作为主控CPU及解码MP3 数据,实现对报站信息播放、点阵字符显示、文件存储以及用作优盘功能时 USBUSB接口电 路与PC机联机的控制。
利用FAT16在K9F1208上实现文件系统,形成一个 Windows 可识别访问的64MB寻址区域结合USB控制器,系统可作为优盘在 Windows下使 用,从而实现在Windows下对文件的管理以及数据存储功能这样通过程序的设 定,公交车可通过键盘实现 MP3格式声音信号的报站以及各种信息的广播列表 文件在系统对闪存初始化时生成,系统在对闪存进行格式化的同时生成该名为 SCHED-ULE.LS的列表文件该列表文件可在 Windows下利用记事本打开,编辑 所需播放的MP3名称播放报站信息的同时通过16个16X 16的LED点阵显示相 应的播放内容系统框图如图1.1所示闪存电路—功放电路I ledJ >点阵MCU 显示f ~ 电路 + 键盘I 指示电 -路图1.1方案一系统框图南华大学船山学院毕业论文1.1.2基于GPS的公交车自动报站系统设计方案GPS的公交车自动报站系统利用 GPS通过GPS接收单元接收卫星发送的信号确 认车辆的动态位置(经度、纬度)、时间、状态等信息,与公交线路信息库中存储 的车站的位置进行比较,根据预先设定的距离和规则向乘客通报车站和线路的语 音信息;并且能把车辆运行的详细情况记录下来, 对公共汽车的运营状况进行全程监控并记录。
系统的组成见图1.2天线图1.2方案二系统框图1.1.3基于SPCE061A的公交车报站系统设计方案系统以SPCE061A为核心,可以划分为键盘输入、数码管显示、 SPR4096资源存储与语音播放等部分,如图1.3所示SPCE061舲为整个系统的核心控制, 并且负责语音的输出SPR4096作为语音资源的存储介质LED键盘显示模组作 为时间显示与用户输出设备.使用SPCE061可以非常方便灵活的实现语音的录 放两路10位精度的DAC只需要外接功放(SPY0030A即可完成语音的播放语音存储电路第6页共74页语音输出电路单片机控制系南华大学船山学院毕业论文键盘电路 ——|I 四 显示电路第43页共74页图1.3方案三系统框图1.2设计方案的可行性分析和选择这三种方案各有各的优势基于 MP3/U盘的公交报站系统能够作为U盘与 电脑连接,可自行下载报站器的播放内容,也可方便地更改播放内容,播放高品 质的音乐,无报站播放时可作为 MP3播放器,提高公交车服务质量但是 MP3 操作页面对于司机来说太小,分散过多的注意力,实用性不够基于 GPS的公交报站系统用先进的卫星定位,进站、出站自动播报站名及服务用语,准确、及 时、完全不需要人工介入,实现了公交车报站器的完全智能化。
国内 GPS语音自动报站系统处于试验阶段,可行性太小基于 SPCE061A公交报站系统,SPCE061A芯片有语音处理能力使得系统设计简化,外围电路较少;另外具有一套 指令系统和集成开发环境易学易用效率较高SPR4096能够存储大量语音数据, 符合任务书所给要求1.3公交车报站器的硬件框图查阅各种相关资料,设计出公交报站系统系统电路原理图见附录2系统硬件设计硬件电路设计可以分为单片机控制系统设计; 语音存储电路设计;音频输出电路设计;显示电路设计2.1 SPCE061A 简介SPCE061型单片机是凌阳科技公司推出的一款 16位微处理器,具有体积小、 集成度高、易扩展、可靠性高、功耗低、结构简单、中断处理能力强等特点,内 嵌32K字闪存FLASH处理速度高,能够很方便的完成普通单片机的功能,尤其 适应于数字语音播报和识别等应用领域,是数字语音识别与语音信号处理的理想 产品,得到广泛的应用SPCE061A单片机的主要性能有:16位u nSP微处理器工作电压(CPU VDD为 3.0~3.6V,(I/O)VDDF为 3.0~5.5VCPU寸钟:0.32~49.152MHz内置2K字SRAM内置32K字FLASH可编程音频处理晶体振荡器系统处于备用状态下(时钟处于停止状态),耗电仅为2uA/3.6V2个16位可编程定时器/计数器(可自动预置初始计数值)2个10位DAC (数/模转换)输出通道32位通用可编程输入/输出通道14个中断源可来自定时器 A/B、时基、2个外部时钟源输入和键唤醒具备触键唤醒的功能使用凌阳音频编码SACM_S480可以播放压缩的语音资源锁相环PLL振荡器提供系统时钟信号32768Hz实时时钟7通道10位电压模/数转换器(ADC和单通道声音模/数转换器 声音模/数转换器输入通道内置麦克风放大器,并具有自动增益控制(AGC功能具备串行设备接口具备低电压复位功能和低电压检测功能内置在线仿真电路接口具有WatchDog功能图2.1为SPCE061A单片机的内部结构框图:IOA15 -0 IOB15-0图2.1 SPCE061A 内部结构图SPCE061A引脚排列如图2.2所示,引脚功能如表2.1所示1314151617].K].92021222324252b272S29303132]2OSC321 > > >XTESTVDD X1CE XI 匚 ECLK X1CESDAV5S PUX DAC1 DAC2 \KEF2 \SSAGC OP1 XUCCUT VUCN PFLSE \C XC• IN ■>- 3C kno sc 1=0-_z二 A OZHM sc- 壬o一 zm 空c一 ur.m匚匚匚匚匚FI0B11IOB12 IOB1?JOB 14JOB 15 XSLEEP VSS XROMTJOA15 JOA14 10AI?纟LV3一C?c_ k
IOB1O-O除用作普通的IO端口,还可作为如下功能:IOB10输入输出IOB10:通用异步串行数据发送管脚 TxIOB9输入输出IOB9: TimerB脉宽调制输出管脚 BPWMOIOB8输入输出IOB8: TimerA脉宽调制输出管脚 APWMOIOB7输入输出IOB7:通用异步串行数据接收管脚 RxIOB6输入输出IOB6 :双向IO端口IOB5输入输出IOB5 :外部中断源EXT2的反馈管脚IOB4输入输出IOB4 :外部中断源EXT1的反馈管脚I0B3输入输出IOB3 :外部中断源EXT2I0B2输入输出IOB2 :外部中断源EXT1I0B1输入输出IOB1 :串行接口的数据传送管脚IOB0输出IOB0:串行接口的时钟信号DAC1输出DAC1数据输出管脚DAC2输出DAC2数据输出管脚OSCI输入32768Hz晶振输入管脚OSCO输出32768Hz晶振输出管脚VCP输入PLL的RC滤波器连接管脚AGC输入AGC的控制管脚MICN输入麦克风负向输入管脚MICP输入麦克风正向输入管脚VREF2输出电压源2.0V产生5mA的驱动电流,可用作外部 ADC Line_In通道的取咼参考输入电压,不可作为电压源使用MICOUT输出麦克风1阶放大器输出管脚,管脚外接电阻决定 AGC增益倍数OPI输入麦克风2阶放大器输入管脚VRTPAD输入ADC Line_ln通道的最高参考输入电压管脚VMIC输出麦克风电源VCM输出AD参考电压(由内部ADC产生)VDD输入逻辑电源的正向电压VSS输入逻辑电源和IO 口的参考地VDDIO输入IO端口的正向电压管脚VSSIO输入IO端口的参考地AVDD输入模拟电路(A/D、D/A和2V稳压源)正向电压AVSS输入模拟电路(A/D、D/A和2V稳压源)参考地RSETB输入低电平有效的复位管脚SLEEP输出睡眠模式(高电平激活)ICE输入激活ICE(高电平激活ICECLK输入ICE串行接口时钟管脚ICESDA输入输出ICE串行接口数据管脚TEST输入测试模式时接咼电平,正常模式时接地GND或悬浮ROMT输入测试闪烁存储器,正常模式时悬浮NC输入正常使用时接地2.2系统电源设计图2.3是电源部分的电路,61单片机的内核工作电压是3.3V,而10 口电压 可以是3.3V也可以是5V。
公交蓄电池12V直流电压经过7805产生5V电压,再 经过SPY0029后产生3.3V电压分别给系统供电LM7805是常用的三端正电源稳压电路,使用的是 TO-220封装,能提供直流 电源5V的输出电压,内含短路和热过载保护电路,应用范围非常广泛带散热 片时能持续提供1A的电流,如果使用外围器件,它还能提供不同的电压和电流 它有三个引脚,引脚1为输入电压,引脚2为+5V输出电压,引脚3接地SPY0029是凌阳公司设计的电压调整IC,采用CMO工艺,具有静态电流低, 驱动能力强,线性调整出色等特点它有三个引脚,引脚 1接地,引脚2为输入 电压,引脚3为输出电压2.3语音存储电路设计因为SPCE061A勺FLASH只有32K字,要存放大量的语音资源,就要外扩存 储器本次设计选用SPR4096芯片2.3.1 SPR4096芯片简介SPR4096是一个高性能的 4M-bit(512K X 8-bit)FLASH,分为 256 个扇区(Sector),每个扇区为 2KB SPR4096还内置了一个 4KX 8bit 的 SRAMSPR4096内置了一个总线存储器接口和一个串行接口,它允许单片机通过8bit并行模式或者1bit串行模式访问FLASH/SRA存储区。
本设计使用品行模 式,串行接口的工作频率可达 5MHz有两个电源输入端 VDDI和VDDQ.VDD是给 内部FLASH和控制逻辑供电的;VDD(是专门为I/O供电的最大读电流为2mASPR4096按串行接口模式工作,要把CF2〜CF0均接高电平CF7为低电平时 选中FLASH高电平时选中SRAM.3.3.2语音存储电路图2.4是SPR4096与单片机的硬件连接图 SPR4096的 SCK接 SPCE061A勺IOB0,SDA接 SPCE061A勺 IOB1CF(〜CF2 接高电平,CF7 接低电平,选中 FLASH图2.4 SPR4096电路图2.4音频输出电路设计SPCE061A内置2路10位精度的DAC,芯片输出的音频信号功率较小,在报 站时要求比较大的声音,就要对芯片输出的声音信号进行功率放大,因此电路选 用了 SPY0030音频功率放大电路图2.5为音频输出电路SPCE061A勺音频输出采用双通道数/模转换 DAC 方式,即数字信号通过10位DAC转换成3mA驱动的电流模拟信号输出语音提 示输出直接采用DAC1道,经信号放大后,由SPEAKER扬声器)输出图2.5音频输出电路SPY0030芯片是一个音频驱动,其增益可以通过外部电阻(最长增益调整为20)。
它的输出功率约700mWV电压可调范围很广(2.4V-6.8V ),具有双端输出 模式,低失真,低待机电流等特点简单易用,仅需 2.4V(两颗电池)即可工作图2.6为SPY0030芯片的引脚图表2.2为引脚功能表SPKVDDSPPCEIINNAC INA二图2.6 SPY0030芯片引脚图表22 SPY0030芯片引脚功能表引脚名称引脚号类型引脚功能VDD8输入电源的正向电压VSS3输入电源地SPP2输出音频输出正极SPN1输出音频输出负极ACIN5输入信号输入正极INN4输入信号输入负极CE7输入芯片使能VREF6输出参考电压2.5显示电路设计图2.7为显示电路图整个显示过程中采用动态显示,即六位显示器逐一轮 流显示,每位持续1ms,10ms或20ms之内循环一遍,刷新速度不要小于每秒三 十桢由于视觉暂留,我们看到的便是 6只显示器同时在显示U2fTWD056q3E"CR17眈3W8A口di!4Q14 nimotm1H2OUT2曲OUT^1W4OUT4恥OUT5OUT61N?OUT?GNDCCMDIG —】MGS~2D ?DIR *DTG3 5DIP 赶UTGi~79CC4DD2EE]FT12W$HH3H呂IR10dOH2图2.7显示电路图显示电路中只要有 ULN2003A WD0521C和 WD05643C等元器件组成。
ULN2003A:其内部为三极管阵列,它的IN脚相当于三极管的B极,OUT较相当于三极管的C极若IN脚输入高电平,对应的OUT脚接地;IN脚输入低电平,对应的OUT脚截止输出WD0521CX共阴极2位数码管.a〜dp为数码管的段信号,G1、G2为2位数 码管的位信号段信号高有效,位信号低有效WD05643CXfc阴极4位数码管.a〜dp为数码管的段信号,di、d2为时钟冒 号的段信号;G1〜G4为4位数码管的位信号,G5为时钟冒号的位信号段信号咼有效,位信号低有效2.6键盘电路设计键盘输入电路如图2.8所示各按键功能不同,根据各按键功能列出表2.3.表2.3键盘各按键功能表按键公交车报站状态时间设置状态S0逐次播放上仃各站提示语,每按一次按顺序播放一个无效S1逐次播放下仃各站提示语,每按一次按顺序播放一个无效S2播放警告用语“车辆拐弯,请注意安全”无效S3播放提示语“车上有老弱病残孕乘客,请让座”无效S4播放娱乐音乐或广告无效S5进入设置时间状态设置切换S6显示在时间/日期/年之间切换增加S7打开或关闭数码管减小3系统软件设计3.1语音处理语音处理是建立在语言学和数字信号处理基础之上的综合学科。
语音处理大致可以分为A/D采样输入、编码处理、存储、解码处理以及 D/A等SPCE061A是16位单片机,有2个16位定时/计数器;CPU时钟最高达 49MHz,16位乘法器和内积运算,有能力执行复杂压缩算法,有完善的语音处 理函数库支持等这些都无疑为语音的播放、录放、合成及识别提供了条件3.1.1压缩存储采样输入是指音频采样和量化,将模拟的(连续的)声音波形数字化(离散 化);语音信号的时域分析,直接利用语音信号的时域波形进行分析;语音信号 的频域分析,对语音信号的频谱、功率谱等进行分析;语音信号的线性预测分析, 把语音信号用一个模型来表示,利用模型的参数来描述语音信号的波形和频谱特 性编码处理采用压缩编码,它具有高效存储和高速传输等特点 压缩编码可分 为三类:1. 波形编码:sub-band即SACM_A2000特点:高质量、高码率,适于高保真 语音/音乐2. 参数编码:声码器(vocoder )模型表达,抽取参数与激励信号进行编码女口: SACM_S240特点:压缩比大,计算量大,音质不高,廉价!3. 混合编码:CELP即SACM_S480特点:综合参数和波形编码之优点 本次系统设计方案采用混合编码方式。
压缩分无损压缩和有损压缩无损压缩一般指:磁盘文件,压缩比低:2:1〜 4:1而有损压缩则是指:音/视频文件,压缩比可高达 100:1凌阳音频压缩算法根据不同的压缩比分为以下几种:SACM_A2O0O压缩比为 8: 1, 8:1.25 , 8:1.5SACM_S480 压缩比为 80:3 , 80:4.5SACM_S240 压缩比为 80:1.5按音质排序:A2000>S480>S240压缩算法中SACM_A2000 SACM_S48、SACM_S240主要是用来放音,可用 于语音提示,而DVR则用来录放音3.1.2语音识别语音的识别可分为下列几个部分:预处理,语音信号数字化;特征提取,抽 取反应语音本质的特征参数,形成特征矢量序列;语音模型库,从一个或多个讲 话者多次重复讲话中提取的语音参数模板;模式匹配,把输入语音的特征参数与 语音模型库进行比较分析,得到识别结果识别的过程可用图 3.1表示图3.1语音的识别3.1.3语音合成语音合成是将以其他方式表示或存储的信息转换成语音 最常见的语音合成技术是将文本转换为语音(TTS文本转换成语音如图3.2所示图3.2文本转换成语音图3.2主函数流程图在主函数中完成SPR4096的初始化、键盘、显示的初始化,并且进行显示 时间与播报公交车报站的站点,然后进入循环根据键盘的值执行相关的操作。
主函数流程图如图3.3所示主函数程序:int main (void){//局部变量初始化un sig ned int uiKey;un sig ned int uiOn_Off;un sig ned int uiKey1_Co unt;un sig ned int uiKey2_C ount;un sig ned int uiflag;un sig ned int uiTemp; uiOn_Off = 0;//键盘值//数码管显示或不显示标志〃key1按下次数〃key2按下次数〃按键keyl、key2的奇偶标志〃临时变量uiKey1_Cou nt = 0; //uiKey2_Cou nt = 16; ////初始化SPR模组,SPR4096//初始化数码管//初始化键盘//初始化显示时间uiflag = 0; SP_SIOI ni tial();DIG」n it();Key_Ini t();Time」nit();DIG_Set(1,0);DIG_Set(2,0);DIG_Set(3,Data[uiHour_H]);DIG_Set(4,Data[uiHour_L]);DIG_Set(5,Data[uiMi ni te_H]);DIG_Set(6,Data[uiMi ni te_L]);Broadcast(52); // 播放站点while(1){if(uiDisp == 0) // 显示时间{DIG_Set(1,0);DIG_Set(2,0);DIG_Set(3,Data[uiHour_H]);DIG_Set(4,Data[uiHour_L]);DIG_Set(5,Data[uiMi ni te_H]);DIG_Set(6,Data[uiMi ni te_L]);}if(uiDisp == 1) // 显示月日{DIG_Set(1,Data[uiM on th_H]);DIG_Set(2,Data[uiM on th_L]);DIG_Set(3,0x0077);DIG_Set(4,Data[uiDay_H]);DIG_Set(5,Data[uiDay_L]);DIG_Set(6,0x007f);}if(uiDisp == 2) // 显示年{DIG_Set(1,0x0040);DIG_Set(2,Data[uiYear_H]);DIG_Set(3,Data[uiYear_MH]);DIG_Set(4,Data[uiYear_ML]);DIG_Set(5,Data[uiYear_L]);DIG_Set(6,0x0040);}uiKey = Key_Get(); 〃得到键值,扫建程序在128Hz中断中调用switch(uiKey){〃选择S480放音,在中断FIQcase KEY1:uiA2000_S480 = 0;uiKey = 0;if(uiflag < 1){uiKey1_Cou nt++;NextStation(uiKey1_Count); 〃播放提示下一站 ***uiflag = 1;}else{uiflag = 0;ComingStation(uiKey1_Count);//**** 站到了 ***}if(uiKey1_Cou nt == 16){uiKey1_Cou nt = 0; 〃如果是终点站,重新初始化}break;case KEY2:uiA2000_S480 = 0;if(uiflag == 0){uiKey2_Cou nt--;NextStatio n(uiKey2_Cou nt);uiflag = 1;}else{uiflag = 0;Comi ngStatio n(uiKey2_Cou nt);}if(uiKey2_Cou nt == 0){uiKey2_Cou nt = 16;break;case KEY3:uiA2000_S480 = 0;PlayS nd_S480(65,3);break;//播放提示语,车在运行中,请做好扶稳case KEY4:uiA2000_S480 = 0;PlayS nd_S480(67,3);break;//请让座case KEY5:〃广告或娱乐uiA2000_S480 = 1;PlayS nd_A2000(70,3);break;case KEY6:g_4Hz_ On = 1; uiSetflag++; Set_Time(); break;case KEY7:uiKey = 0; uiDisp++;if(uiDisp == 3)uiDisp = 0;if(uiDisp == 0)〃进入4Hz中断代码,实现闪烁效果//设置时间//切换显示时间/月曰/年uiTemp = *P」NT_Ctrl_New; //打开2Hz中断,显示秒针uiTemp |= C」RQ5_2H z;*P」N T_Ctrl_New = uiTemp;else{uiTemp = *P」NT_Ctrl_New; //关闭2Hz中断,不显示秒针uiTemp &= Oxfffb;*P」N T_Ctrl_New = uiTemp;uiTemp = *P」OB_Buffer;uiTemp &= 0xfffb;*P」O B_Data = uiTemp;}break;case KEY8:if(u iOn_Off == 0){DIG_Off(); //关闭数码管uiOn_Off = 1;}else{DIG_O n(); 〃打开数码管uiOn_Off = 0;}break;default:break;}*P_Watchdog_Clear = 0x0001; // 清看门狗}}3.3初始化函数系统要对SPR4096键盘、显示、时间初始化SPR409砌始化流程图如图3.4所示。
图3.4 spr4096 初始化SPR4096初始化程序如下:.PUBLIC _SP_SIOI nitial_SP_SIOI nitial: .PROC//系统时钟设定r1 = 0x0098; 〃Fosc=49mHz[P_SystemClock] = r1;r1 = [P」O B_Dir];r1 |= 1; //set bit0 output for sck[P」OB_Dir] = r1;r1 = [P_I OB_Attrib];r1 |= 1; //buffer output[P」OB_Attrib] = r1;r1 = [P」OB_Buffer];r1 |= 1; //output high[P_l OB_Data] = r1;retf.ENDP键盘初始化流程图如图3.5所示,//初始化IO为下拉输入//初始化变量初始化IOB8-IOB15为下拉电阻输入口初始化键盘变量打开 128Hz (IRQ6_TMB)中断图3.5键盘初始化键盘初始化程序如下:F_Key_l nit:_Key_l nit:push r1 to [sp]INT Offr1 = [P_Key_Dir]r1 &= ~Key_ALL[P_Key_Dir] = r1r1 = [P_Key_Attrib] r1 &= ~Key_ALL[P_Key_Attrib] = r1r1 = 0[Sea nCnt] = r1[KeyCode] = r1[KeyUp] = r1r1 = C_TMB2_128Hz // 开启 IRQ6_TMB2(128HZ中断[P_TimeBase_Setup] = r1r1 = [P」N T_Mask]r1 |= C」RQ6_TMB2[P_INT_Mask] = r1INT FIQ,IRQpop r1 from [sp]Retf.ENDP数码管初始化流程图如图3.6所示,图3.6数码管初始化数码管初始化程序如下:_DIG」nit:F_DIG」nit:push r1,bp to [sp]INT Offr1 = DIG_Cou ntr2 = 0x0000bp = R_DIG_Buf?DIG _ln itBuf:[bp++] = r2r1 -= 1jnz ?DIG」n itBuf [R_CurDIG] = r2 r1 = [P_SEG_Attrib] r1 |= PIN_SEG_ALL [P_SEG_Attrib] = r1 r1 = [P_SEG_Buf] r1 &= ~PIN_SEG_ALL [P_SEG_Data] = r1 r1 = [P_SEG_Dir] r1 |= PIN_SEG_ALL [P_SEG_Dir] = r1 r1 = [P_DIG_Attrib] r1 |= PIN_DIG_ALL [P_DIG_Attrib] = r1 r1 = [P_DIG_Buf] r1 &= ~PIN_DIG_ALL [P_DIG_Buf] = r1 r1 = [P_DIG_Dir] r1 |= PIN_DIG_ALL [P_DIG_Dir] = r1 r1 = [P」N T_Mask] r1 |= C_IRQ4_4KHz [P_INT_Mask] = r1 INT FIQ,IRQ pop r1,bp from [sp] retf//Clear Display Buffer//Reset Dig Poi nter//In itial IO Ports for Seg//In itial IO Ports for Dig//En able IRQ4_4KHz Int.ENDP时间初始化流程图如图3.7所示。
时间初始化程序:void Time」ni t(void){//设置IOB2为高电平输出un sig ned int uiTemp; uiTemp = *P」0 B_Dir; uiTemp |= 0x0004;*P_IOB_Dir = uiTemp; uiTemp = *P」O B_Attrib;uiTemp |= 0x0004;*P」OB_Attrib = uiTemp;uiTemp = *P」O B_Data;uiTemp |= 0x0004;*P」OB_Data = uiTemp;uiTemp = *P_INT_Ctrl_New; // 开 2Hz、4Hz 中断uiTemp |= C」RQ5_2H z;uiTemp |= C」RQ5_4H z;*P」N T_Ctrl_New = uiTemp;3.4语音播放的实现由于语音资源存储在外廓的存储器 SPR4096上面,要实现语音播放必须采用手动方式需要获得语音资源,关键解决语音资源的起始地址,然后通过读取函数获得语音资源函数流程图如图 3.8所示开始取得语音资源的开始地址与结束地址初始化放音,队列与解码YN获得语音资源判断解码队列是否为Y是否播放结束?I N语音资源解码1语音播放T结束NY结束放音是否有键按下?清看门狗图3.8手动方式播放流程图手动方式播放程序:void PlayS nd_A2000(u nsig ned int Sndln dex,u nsig ned int DAC_Cha nnal)//语音播放状态//存储语音资源//语音资源的最高字节地址//语音资源的高字节地址//语音资源的低字节地址//语音资源的最低字节地址//语音资源的末地址{un sig ned int uiStatus;un sig ned int uiRet;un sig ned long ulC on _AddrHighest;un sig ned long ulC on _AddrHigh;un sig ned long ulC on _AddrLow;un sig ned long ulC on _AddrLowest;un sig ned long ulC on_En dAddr;un sig ned long ulC on _StartAddr;un sig ned int uiKey;ulCon_AddrHighest = SP_SIOReadAByte(BASE_START_ADDRESS +Sn dI ndex*12); // 第一个播放文件地址ulCon_AddrHighest = ulCon_AddrHighest << 24;ulCon_AddrHigh = SP_SIOReadAByte(BASE_START_ADDRESS + Sn dI ndex*12+1);ulCon_AddrHigh = ulCon_AddrHigh << 16;ulCon_AddrLow = SP_SIOReadAByte(BASE_START_ADDRESS + Sndln dex*12+2);ulCon_AddrLow = ulCon_AddrLow << 8;ulCon_AddrLowest = SP_SIOReadAByte(BASE_START_ADDRESS +Sn dI ndex*12+3);ulCon_StartAddr = ulCon_AddrHighest | ulCon_AddrHigh//开始地址| ulCon_AddrLow | ulCon_AddrLowest;ulCon_AddrHighest = SP_SIOReadAByte(BASE_END_ADDRESSdI ndex*12); ulCon_AddrHighest = ulCon_AddrHighest << 24;ulCon_AddrHigh = SP_SIOReadAByte(BASE_END_ADDRESSdI ndex*12+1);ulCon_AddrHigh = ulCon_AddrHigh << 16;ulCon_AddrLow = SP_SIOReadAByte(BASE_END_ADDRESS + Sndln dex*12+2);ulCon_AddrLow = ulCon_AddrLow << 8;ulCon_AddrLowest = SP_SIOReadAByte(BASE_END_ADDRESS +Sndln dex*12+3);ulCon_E ndAddr = ulCon_AddrHighest | ulCon_AddrHigh//结束地址| ulCon_AddrLow | ulCon_AddrLowest;SACM_A2000_I ni tial(0);//初始化放音SACM_A2000_I ni tQueue();//初始化队列SACM_A2000_I ni tDecoder(DAC_Cha nn al);//初始化解码uiStatus = 1;//初始化放音状态while(uiStatus){while(SACM_A2000_TestQueue() != 1){if(ulCon_StartAddr >= ulCon_E ndAddr){uiStatus = 0;//解码队列是否为空//文件结束?//如果文件结束,结束放音break;}uiRet = SP_SIOReadAWord(ulCon_StartAddr);〃 取得语音资源SACM_A2000_FillQueue(uiRet); // 填充解码队列ulCon_StartAdd叶+; //移动资源指针ulCon_StartAdd 叶+;}if(uiStatus) // 解码{SACM_A2000_Decoder();//停止放音}else{SACM_A2000_Stop();}uiKey = Key_Get();if(uiKey != 0)uiStatus = 0;*(u nsig ned int *)0x7012 = 0x0001;}}3.5更新时间可以使用SPCE061A单片机的2Hz时基中断,在2Hz时基中断中调用更新函 数,函数要作的就是换算好进位的关系。
比如60秒进位1分钟,然后秒清零<更新时间程序如下:void Time_R un(v oid){//更新时分if(g_uiSeco nd_half == 120){g_uiSec on d_half = 0;uiMi ni te_L++;}if(uiMi ni te_L == 10){uiMi nite_L = 0;uiMi ni te_H++;}if(uiMi nite_H == 6){uiMi ni te_H = 0;uiHour_L++;}if((uiHour_H == 2)&&(uiHour_L == 4)){uiHour_H = 0;uiHour_L = 0;uiDay_L++;}else{if(uiHour_L == 10){uiHour_L = 0;uiHour_H++;}}3.6设置时间在设置时间时出现动态闪烁效果,这个问题使用 4Hz的时基中断改变标志 位,在设置时间函数中根据这个标志位显示或关闭数码管,出现闪烁效果 时间设置流程图如图3.9所示.根据标志分别设置图3.9时间设置流程图清看门狗修改标志根据键值时间设置程序如下:void Set_Time(void){un sig ned int uiKey;un sig ned int uiTemp;while(1){uiKey = Key_Get();*P_Watchdog_Clear = 0x0001;〃调整分钟if(uiSetflag == 1){if(g_Light == 1){DIG_Set(3,Data[uiHour_H]);DIG_Set(4,Data[uiHour_L]);DIG_Set(5,Data[uiMi ni te_H]);DIG_Set(6,Data[uiMi ni te_L]);}if(g_Light == 0){DIG_Set(3,Data[uiHour_H]);DIG_Set(4,Data[uiHour_L]);DIG_Set(5,0);DIG_Set(6,0);}switch(uiKey){case KEY6:uiSetflag = 2;uiKey = 0;break;case KEY7:uiMi ni te_L++;if(uiMi ni te_L == 10){uiMi ni te_L = 0;uiMi ni te_H++;if(uiMi ni te_H == 6)uiMi ni te_H = 0;}break;case KEY8:uiMi ni te_L--;if(uiMi nite_L == 0xffff){uiMi ni te_L = 9;uiMi ni te_H--;if(uiMi ni te_H == 0xffff) uiMi ni te_H = 5;}break;default:break;}}〃调整小时if(uiSetflag == 2){if(g_Light == 1){DIG_Set(3,Data[uiHour_H]);DIG_Set(4,Data[uiHour_L]);DIG_Set(5,Data[uiMi ni te_H]);DIG_Set(6,Data[uiMi ni te_L]);}if(g_Light == 0){南华大学船山学院毕业论文DIG_Set(3,0);DIG_Set(4,0);DIG_Set(5,Data[uiMi ni te_H]);DIG_Set(6,Data[uiMi ni te_L]);}switch(uiKey){case KEY6:uiSetflag = 3;uiKey = 0;break;case KEY7:uiHour_L++;if(uiHour_L == 10){uiHour_L = 0;uiHour_H++;if((uiHour_H == 2)&&(uiHour_L ==4)){uiHour_H = 0;uiHour_L = 0;}}break;case KEY8:if((uiHour_H == 0)&&(uiHour_L == 0)){uiHour_H = 2;uiHour_L = 3;else{uiHour_L--;if(uiHour_L == Oxffff){uiHour_L = 9;uiHour_H--;if(uiHour_H == Oxffff)uiHour_H = 0;}}break;default:break;}}〃调整日if(uiSetflag == 3){uiTemp = *P」NT_Ctrl_New; //关闭2Hz中断,不显示秒针uiTemp &= 0xfffb;*P」N T_Ctrl_New = uiTemp;uiTemp = *P」O B_Buffer;uiTemp &= 0xfffb;*P」O B_Data = uiTemp;if(g_Light == 1){DIG_Set(1,Data[uiM on th_H]);DIG_Set(2,Data[uiM on th_L]);DIG_Set(4,Data[uiDay_H]);DIG_Set(5,Data[uiDay_L]);DIG_Set(6,0x007f);}if(g_Light == 0){DIG_Set(1,Data[uiM on th_H]);DIG_Set(2,Data[uiM on th_L]);DIG_Set(3,0x0077);DIG_Set(4,0);DIG_Set(5,0);DIG_Set(6,0x007f);}switch(uiKey){case KEY6:uiSetflag = 4;uiKey = 0;break;case KEY7:uiDay_L++;if(uiDay_L == 10){uiDay_L = 0;uiDay_H++;}i。