《音乐播放器按键控制模块》由会员分享,可在线阅读,更多相关《音乐播放器按键控制模块(8页珍藏版)》请在金锄头文库上搜索。
1、4.2.1 键盘的实现凌阳 SPCE061A 单片机精简开发板自身带有 4 个按键,分别为 S1、S2、S3、 S4,其中S4用于对单片机进行复位,因此还有S1、S2、S3三个按键可用。在 SPCE061A中,S1、S2、S3都在内部与IOAOIOA2相连接,因此可以通过控制IOA 口低八位控制这几个键,在程序中,S1、S2、S3相当于一个1X3的键盘,通过 读写IOA 口低八位,得到端口数据,通过移位运算等,即可得到键值,并将键值 存放于变量KeyCode中。为实现通过IOA 口控制1X3的键盘,需要将IOA 口低八位设置为输入模式, 只有这样才能确保能够读取IOA 口的状态;同时,将IRQ
2、6中断作为键盘的中断, 每当IRQ6中断到来,系统自动调用键扫描程序Key_Scan(),扫描键盘,通过检 测按键的抬起状态和抬起时间,判断是否有键按下。程序中, IRQ6 中断由按键 扫描初始化程序启动,在初始化程序中,首先完成对 IO 口的输入以及变量的初 始化,然后开启IRQ6中断。之后,没每当有键按下,便会产生一个IRQ6中断, 并进入中断服务子程序,在进入该程序以后,调用键扫描程序扫描键盘,读取键 值并存储。在键盘实现中,定义3 个全局变量 KeyCode、 ScanCnt、 KeyUp 分别用来保存 得到的键值、按键持续时间、按键抬起标志,当本次扫描有键按下时, KeyUp 置 0
3、,若本次得到的键值与上次键值相等时,则ScanCnt加1,否则保存新键值并将 ScanCnt 置 1;当本次扫描无键按下,则 KeyUp 置 1。当按键持续时间 ScanCnt 小于4时,则认为没有发生按键;当按键持续时间ScanCnt等于64则认为有发 生一次按键;若ScanCnt介于4于64之间且按键抬起标志KeyUp为1时,则认 为发生一次按键。键盘的实现,主要是完成四个函数,即键盘初始化程序Keynit()、键扫描 程序Key_Scan()、取键值程序Key_Get()以及中断服务程序。由于这些程序面向硬 件进行操作,因此使用汇编语言进行编写。键盘初始化程序的流程图如图4.3所示,初始
4、化操作主要包含寄存器数据的 保存、变量的初始化、IOA 口读写方式的设置以及IRQ6 (128HZ)中断的开启等。图 4.3 键盘初始化程序流程图键扫描程序的流程图如图 4.4 所示,键盘扫描程序事实上是一个去抖程序, 先判断是否有键按下,如果有的话,判断键值和上次扫描到的键值是否相同,如 果相同,按键持续时间加 1,也就是延时;如果不同,按键持续时间赋 1,保存 键值以便和下次扫描键值比较;如果没有键按下,认为键盘已经抬起。图 4.4 键扫描程序流程图取键值程序如图 4.5 所示,由于扫描键盘是在中断中进行的,所以取键值时要先关中断,是否延时到设定时间,即是否扫描了四次键值都相等,如果是,比
5、较按键的时间间隔是否小于0.5s (SeanCnt64),比较时间间隔主要是为了设定 按键时间间隔,如果按键时间间隔小于 0.5s 而且键盘确认抬起,则表示发生一 次按键,将键值保存在变量KeyCode中;否则,键值为0;开中断后,返回键值。/ 一、开始关中断、寄存器入栈*v二ScanCnt64迂- -I NTV匚按键抬起标志为1?二* -Y 图 4.5 键值获取程序流程图图 4.6 所示为 IRQ6 中断服务程序的流程图。开始图 4.6 IRQ6 中断服务程序4.2.2 音频控制的实现凌阳 SPCE061 具有强大的语音处理功能,其提供了许多 S480 音频播放控制 的函数,通过调用这些函数
6、,可方便我们实现对 S480 音频播放的控制,在该系 统中,需要通过按键来控制音频播放,实现其上一曲、下一曲、播放和暂停的功 能,由于设计的键盘是1X3的键盘,而现在需要实现4个功能,因此考虑将播 放和暂停功能合并到一个按键,即在播放时按下该键则暂停播放,若某音频在被 暂停以后按下该键则继续播放。为了能够实现上一曲以及下一曲之间的切换,则需要将音频文件进行编号, SPCE061A IDE 开发中, Resourse.asm 文件中定义了音频文件的相关信息, T_SACM_S480_SpeechTable 定义了资源文件的序号,默认从 0 开始,如下所示:.PUBLIC T_SACM_S480_
7、SpeechTableT_SACM_S480_SpeechTable:.DW _RES_48_48K_SA.DW _RES_72_72K_SA.DW _RES_K72_72K_SA由于程序中,调用SACM_S480_Play()来播放音频,因此在对音频文件进行编 号以后,要实现上一曲及下一曲间的切换则转变为改变音频序号的问题,切换至 上一曲时,应减小序号,切换至下一曲时应增加序号。在本设计中,以全局变量 SnIndex 代表音频的序号,以全局常量 MaxIndex 代表音频资源的总数。在不考虑按键的情况下,要实现 S480 压缩格式音频文件的持续播放,需要 利用如下的代码实现:while(SA
8、CM_S480_Status() & 0x0001)!=0)SACM_S480_ServiceLoop();*P_Watchdog_Clear=0x0001;即 循 环 检 测 S480 语 音 是 否 播 放 结 束 , 没 有 结 束 的 利 用 SACM_S480_ServiceLoop();实现其持续播放,为了能够通过按键控制音频的播放, 需要对该代码进行改动,在其中增加对键值的判断,修改后的代码如下:while( ( ( SACM_S480_Status() & 0x0001 ) != 0 ) & ( iKey != KEY_1)& ( iKey != KEY_2) & ( iKey
9、 != KEY_3) )SACM_S480_ServiceLoop();iKey = Key_Get () ;*P_Watchdog_Clear=0x0001;修改后,循环在有键值的情况下结束,然后对循环结束条件进行判断,根据 判断结果执行相应的动作,代码如下:if( ( ( SACM_S480_Status () & 0x0001 ) =0 ) | ( iKey = KEY_2 ) )播放结束或键值等于KEY_2则播放下一曲SnIndex+;/增加音频序号,增加后若达最大值则回 0if( SnIndex = MaxIndex ) SnIndex=0;play();/播放音频*P_Watchd
10、og_Clear=0x0001;if( iKey = KEY_3 )键值等于KEY_3则实现播放、暂停if( ( SACM_S480_Status() & 0x0001 ) != 0 )/音频没有播放结束SACM_S480_Pause();/则暂停播放*P_Watchdog_Clear = 0x0001;if( iKey = KEY_1 )键值等于 KEY_1if( Snlndex = 0) Snlndex = Maxindex;/减小音频序号,若当前值为 0,SnIndex-;/则为最大值,即音频数量减1play();/播放音频*P_Watchdog_Clear=0x0001;通过这种方法实
11、现对音频播放的控制,当播放结束或键值等于 Key1 导致循 环结束时,这表示系统应该继续播放下一首音频,因此音频的序号加 1,当加 1 以后达到音频数目时,则序号回0,调用play()当前序号的歌曲;当键值等于key2 导致的循环结束时,表明系统应该播放当前音频序号前的音频,当序号等于 0 时,将序号赋值为音频数目后减1,然后调用play()播放当前序号音频;当键值 为 Key3 导致的的结束时,由于此时音频可能在播放也可能不在播放,因此需进 行判断,当音频在播放时,调用SACM_S480_Pause()暂停当前音频的播放,若音 频不在播放则不执行动作。将该方法通过函数进行实现,即contro
12、ll()函数,其函 数流程图如图4.7 所示。开始取键值放音结束? YT键值等于Key2?丫+ 1改变歌曲编号改变歌曲编号1F1r调用play()函 数播放下一曲调用play()函 数播放上一曲1r1T结束结束N=1 一键值等于Key? 一二二一丫十、3 :继续放音并取键值图4.7 Control()函数流程图上述的程序只能实现对正在播放音频的控制,要完成音频模式的完整功能 还需要音频模式的主程序以及play()函数的实现。音频模式的主程序流程图如图 4.8 所示,在系统启动,选择进入音频模式以 后,系统调用该程序,首先对键盘及 S480 放音进行初始化,然后反复读取键值, 当有用的键值产生时,判断该键值,当键值为Key1或Key2时,改变音频序号, 调用 play() 播放上一曲或 下一曲, 当 键值为 key3 时 , 则直接调用 SACM_S480_Resume()方法,恢复播放,然后调用controll()进行控制,这是由于 暂停播放的实现是在播放控制的过程中实现的。图 4.8 音频模式主程序play ()函数流程图如图4.9所示,其主要是完成调用SACM_S480_Play ()方法播放当前序号音频而编写的,在启动播放以后则调用controll()进行控制。结束图 4.9 play() 函数流程