基于单片机的简易音乐播放器的设计 下载本文

天津天狮学院

毕业实践报告

题目:基于单片机的简易音乐播放器的设计

二级学院 电子与计算机学院 专 业 电子信息工程技术 学生姓名 卫小丽 指导教师 苗艳华

2012年06月01日

摘 要

本文是基于单片机控制的音乐播放器的设计, 它可以实现音乐的播放,可以通过功能键来选择乐曲,播放或暂停。共有K1到K4四个功能键,K1-K3分别播放三首不同音乐,K4为暂停键。主控芯片采用AT89C52,辅以必要的电路,采用C语言进行编程,编程后利用KEIL C51来进行编译,再将生成的HEX文件装入芯片中,采用proteus软件来仿真,检验功能得以正常实现。通过烧写不同的程序,可以实现多首不同音乐的更换。

本文将围绕基于单片机的自动音乐播放器,介绍一些关于单片机的基础知识、模块电路设计、音乐播放器的原理(其中包括了音乐编程原理)、以及仿真软件的使用。

关键词:单片机AT89C52,音乐播放,proteus

目 录

一、功能介绍 .............................................................. 1 1.1 功能特点 ............................................................ 1 1.2 原理说明 ............................................................ 1 二、硬件电路设计 .......................................................... 1 2.1 系统方案设计 ........................................................ 1 2.2 模块电路的设计 ...................................................... 2 2.2.1 AT89C52型单片机的介绍 .......................................... 2 2.2.2单片机最小系统的设计 ............................................ 4 2.2.3蜂鸣器电路设计 .................................................. 5 2.2.4按键电路设计 .................................................... 6 2.2.5 LED显示电路设计 ................................................ 6 三、软件设计 .............................................................. 7 3.1系统主模块流程图 .................................................... 7 3.2音乐产生原理 ........................................................ 7 3.2.1音调 ............................................................ 8 3.2.2节拍 ............................................................ 9 四、PROTEUS仿真应用 ..................................................... 10 4.1 PROTEUS软件简介 ................................................... 10 4.2 仿真结果 ........................................................... 11 五、结论 ................................................................. 12 参考文献 ................................................................. 13 致谢 ..................................................................... 14 附录1 ................................................................... 15 附录2 ................................................................... 16

一、功能介绍

1.1 功能特点

本设计是一个基于AT89C52系列单片机的音乐播放器,依据单片机技术原理,通过硬件电路设计以及软件编译,设计出一个多功能音乐播放器。该音乐播放器主要由按键电路、晶振电路、复位电路以及扬声器组成。最后利用proteus对音乐播放器进行仿真调试。

1.2 原理说明

当按键按下时,判断键值,启动计数器T0,产生一定频率的脉冲,驱动蜂鸣器,放出乐曲。其中:

1) 硬件电路中用P2.0-P2.3控制4个按键,K1-K3分别控制三首音乐,K4为停止键;

2)P1.0-P1.3为LED显示,四个发光二极管分别对应四个按键,显示所播放歌曲; 3)用P3.7口控制蜂鸣器;

4)电路为12MHz晶振频率工作,起振电路中C1,C2均为22pf。

二、硬件电路设计

2.1 系统方案设计

硬件方框图如图2-1所示。主要由单片机核心芯片AT89C52,LED发光二极管,蜂鸣器,晶振电路,复位电路组成,由引脚输出定时器产生的各种固定频率的方波信号,然后由蜂鸣器产生各种频率的声音。由于该方案中使用内部振荡电路,XTAL1、XTAL2引脚外接石英晶体和微调电容构成晶振电路。

1

图2-1 设计方框图

2.2 模块电路的设计

2.2.1 AT89C52型单片机的介绍

AT89C52是美国Atmel公司生产的低功耗、高性能CMOS 8位单片机,其管脚图如图2-2所示。片内含8KB的可反复檫写的程序存储器和256B的随机存取数据存储器(RAM),器件采用Atmel公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内配置通用8位中央处理器(CPU)和Flash存储单元,功能强大的AT89C52单片机可灵活应用于各种控制领域。

图2-2 AT89C52引脚图

主要性能参数如下:

1) 与MCS-51产品指令和引脚完全兼容;

2

2) 8K字节可重擦写Flash闪速存储器; 3) 1000次擦写周期; 4) 全静态操作:0HZ-24HZ; 5) 三级加密程序存储器; 6) 256*8字节内部RAM; 7) 32个可编程I/O口线; 8) 3个16位定时/计数器; 9) 8个中断源;

10) 可编程串行UART通道; 11) 低功耗空间和掉电模式。 各引脚功能如下: 1.时钟引脚

XTAL1:接外部晶体的一个引脚。在单片机内部,它是构成片内振荡器的反相放大器的输入端。当采用外部振荡器时,该引脚接收振荡器的信号,即把此信号直接接到内部时钟发声器的输入端。

XTAL2:接外部晶体的另一个引脚。在单片机内部,它是构成内部振荡器的反相放大器的输出端。当采用外部振荡器时,此引脚应悬浮不连接。

注意:如果采用片内的振荡电路,要在单片机的引脚XTAL1和XTAL2之间连接一个石英晶体或陶瓷谐振器,并接两个电容到地。 2.控制线或其他电源的复位引脚

RST:复位输入端。

ALE/PROG:当访问外部寄存器时,地址锁存允许的输出电平用于锁存地址的低位字节。

PSEN:外部程序存储器的选通信号。在有外部程序存储器取指令期间,每个机

器周期两次PSEN有效。但在访问外部数据存储器时,这两次有效的PSEN信号将不出现。

EN/Vpp:当EN保持低电平时,则在此期间访问外部程序存储器(0000H-FFFFH),

不管是否有内部程序存储器。注意要加密方式1时,EN将内部锁定为RESET;当EN断保持高电平时,此间访问内部程序存储器。在Flash编程期间,此管脚也用于施加12V编程电源(Vpp)。 3. 输入/输出引脚

P0口:P0口为一个8位漏极开路双向I/O口,每脚可吸收8个TTL门电流。当P1口的管脚第一次写“1”时,被定义为高阻输入。P0口能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在Flash编程时,P0口作为原码输入口,当Flash

3

进行校验时,P0口输出原码,此时,P0口外部必须被拉高。

P1口:P1口为一个内部提供上拉电阻的8位双向I/O,P1口缓冲器能接收输出4个TTL门电流。P1口管脚写入“1”后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在Flash编程和校验时,P1口为第八位地址接收。

P2口:P2口为一个内部提供上拉电阻的8位双向I/O,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高。且作为输入。并因此作为输入时,P2口的管脚被外部拉底,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部8位地址数据校验时,P2口输出其特殊功能起存器的内容。P2口在Flash编程和校验时,接收高8位地址信号和控制信号。

P3口:P3口为一个内部提供上拉电阻的8位双向I/O,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。P3口也可作为一些特殊功能口,如表2-1所示。

表2-1 P3口特殊功能 口 P3.0 P3.1 P3.2 P3.3 P3.4 P3.5 P3.6 P3.7 2.2.2单片机最小系统的设计

管脚 RXD TXD INT0 INT1 备选功能 串行输入口 串行输出口 外部中断0 外部中断1 计时器0外部输入 计时器1外部输入 外部数据存储器写选通 外部数据存储器读选通 T0 T1 WR RD 单片机的最小系统设计包括:时钟电路、复位电路,如图2-3所示。在内部方式时钟电路中,必须在XTAL1和XTAL2引脚两端跨接石英晶体振荡器和两个微调电容构成振荡电路,通常C1和C2一般取30pF,晶振的频率取值在1.2MHz~12MHz之间。复位电路就好比电脑的重启部分,当电脑在使用中出现死机,按下重启按钮电脑内部的程序从头开始执行。其中,电容的大小是10uF,电阻的大小是10k。

4

图2-3 单片机最小系统

2.2.3蜂鸣器电路设计

蜂鸣器发声原理是电流通过电磁线圈,使电磁线圈产生磁场来驱动振动膜发声的,因此需要一定的电流才能驱动它,单片机IO引脚输出的电流较小,单片机输出的TTL电平基本上驱动不了蜂鸣器,因此需要增加一个功率放大的电路。由单片机P3.7 接口外接一个1K电阻和两个NPN型三极管来驱动蜂鸣器。其主要任务是输出大信号和大功率,对音频信号有效不失真的进行放大以推动扬声器发出声音,原理图如图2-4所示。

图2-4 蜂鸣器电路

5

2.2.4按键电路设计

采用4个按钮来实现选择歌曲播放,由P2.0-P2.3控制,外接四个10K的上拉电阻,并通过三个与门接P3.2实现外部中断。原理图如图2-5所示。

图2-5 按键电路

2.2.5 LED显示电路设计

四个发光二极管分别由P1.0-P1.3控制,播放第一首歌时D1亮,第二、第三首歌时D2、D3亮,停止时D4亮,其中电阻为220Ω。原理图如图2-6所示。

图2-6 LED显示电路

6

三、软件设计

3.1系统主模块流程图

主模块是系统软件的主框架。结构化程序设计一般有“自上而下”和“自下而上”两种方式,“自上而下”法的核心就是主框架的构建。它的合理与否关系到程序最终的功能的多少和性能的好坏。本系统的主模块程序框图如图3-1所示。开始系统初始化,判断是否有键按下,当K1键按下时,播放第一首歌,K4键按下停止播放,并返回到系统初始化,再判断是否有键按下。K2、K3键也分别控制两首歌的播放。

图3-1 系统主模块流程图

3.2音乐产生原理

单片机发音原理:单片机演奏音乐基本是单音频率,它不包含相应幅度的谐波频率,也就是说不能象电子琴那样能奏出多种音色的声音,但一定要弄清楚两个概念即可,也就是“音调”和“节拍” 。

7

音调:表示一个音符唱多高的频率。 节拍:表示一个音符唱多长的时间。 3.2.1音调

在音乐中所谓“音调”,其实就是我们常说的“音高”。在音乐中常把中央C上方的A音定为标准音高,其频率f=440Hz,其余与其比较。f1和f2为两个音符,当这两个音符的频率相差一倍时,也即f2=2×f1时,则称f2比f1高一个倍频程。在音乐中1与1,2与2,正好相差一个倍频程,在音乐学中称它相差一个八度音。在一个八度音内,有12个半音。以1—i八音区为例,12个半音是:1—#1、#1—2、2—#2、#2—3、3—4、4—#4,#4—5、5一#5、#5—6、6—#6、#6—7、7—i 。这12个音阶的分度基本上是以对数关系来划分的。如果我们只要知道了这十二个音符的音高,也就是其基本音调的频率,我们就可根据倍频程的关系得到其他音符基本音调的频率。

确定一个频率所对应的定时器的定时初值的方法:

以标准音高A为例:标准音高A的频率f = 440 Hz,其对应的周期为: T = 1/ f = 1/440 =2272μs。因此,需要在单片机I/O端口输出周期为T =2272μs的方波脉冲,如图3-2所示。

..

图3-2 方波脉冲

由上图可知,单片机上对应蜂鸣器的I/O口来回取反的时间应为:

t = T/2 = 2272/2 = 1136μs

这个时间t也就是单片机上定时器应有的中断触发时间。一般情况下,单片机奏乐时,其定时器为工作方式1,它以振荡器的十二分频信号为计数脉冲。设振荡器频率为f0,则定时器的予置初值由下式来确定:

t = 12 *(TALL – THL)/ f0

式中TALL = 216 = 65536,THL为定时器待确定的计数初值。因此定时器的高低计数器的初值为:

TH = THL / 256 = ( TALL – t* f0/12) / 256 TL = THL % 256 = ( TALL – t* f0/12) %6

8

将t=1136μs代入上面两式(注意:计算时应将时间和频率的单位换算一致),即可求出标准音高A在单片机晶振频率f0=12Mhz,定时器在工作方式1下的定时器高低计数器的予置初值为 :

TH440Hz = (65536 – 1136 * 12/12) /256 = FBH TL440Hz = (65536 – 1136 * 12/12)%6 = 90H

根据上面的求解方法,我们就可求出其他音调相应的计数器的予置初值。 3.2.2 节拍

音符的节拍我们可以举例来说明。在一张乐谱中,我们经常会看到这样的表达式,

43如1=C 、1=G…… 等等,这里1=C,1=G表示乐谱的曲调,和我们前面所谈的音

44433调有很大的关联,、就是用来表示节拍的。以为例加以说明,它表示乐谱中以

444四分音符为节拍,每一小结有三拍。如图3-3所示。

图3-3 音乐节拍

其中1 、2 为一拍,3、4、5为一拍,6为一拍共三拍。1 、2的时长为四分音符的一半,即为八分音符长,3、4的时长为八分音符的一半,即为十六分音符长,5的时长为四分音符的一半,即为八分音符长,6的时长为四分音符长。那么一拍到底该唱多长呢?一般说来,如果乐曲没有特殊说明,一拍的时长大约为400—500ms 。我们以一拍的时长为400ms为例,则当以四分音符为节拍时,四分音符的时长就为400ms,八分音符的时长就为200ms,十六分音符的时长就为100ms。

可见,在单片机上控制一个音符唱多长可采用循环延时的方法来实现。首先,我们确定一个基本时长的延时程序,比如说以十六分音符的时长为基本延时时间,那么,对于一个音符,如果它为十六分音符,则只需调用一次延时程序,如果它为八分音符,则只需调用二次延时程序,如果它为四分音符,则只需调用四次延时程序,依次类推。

通过上面关于一个音符音调和节拍的确定方法,我们就可以在单片机上实现演奏音乐了。具体的实现方法为:将乐谱中的每个音符的音调及节拍变换成相应的音调参数和节拍参数,将他们做成数据表格,存放在存储器中,通过程序取出一个音符的相关参数,播放该音符,该音符唱完后,接着取出下一个音符的相关参数,如此直到播放完毕最后一个音符,根据需要也可循环不停地播放整个乐曲。另外,对于乐曲中的休止符,一般将其音调参数设为FFH,FFH,其节拍参数与其他音符的节拍参数确定方法一致,乐曲结束用节拍参数为00H来表示。

9

下面给出部分音符(三个八度音)的频率以及以单片机晶振频率f0=12Mhz,定时器在工作方式1下的定时器高低计数器的予置初值,如下表3-1所示。

表3-1 音符频率与定时器初值关系表 C调 音符 1 1# 2 2# 3 4 4# 5 5# 6 6# 7 频率 262 277 293 311 329 349 370 392 415 440 466 494 Hz TH/TL F88B F8F2 F9B7 FA14 FA66 FAB9 FB03 FB4A FB8F FBCF FBCF FC0B C调 音符 频率 523 553 586 621 658 697 739 783 830 879 931 987 Hz TH/TL FC43 FC78 FCAB FCDB FD08 FD33 FD5B FD81 FDA5 FDC7 FDE7 FE05 C调 音符 频率 1045 1106 1171 1241 1316 1393 1476 1563 1658 1755 1860 1791 Hz TH/TL FB21 FE3C FE55 FE6D FE84 FE99 FEAD FEC0 FE02 FEE3 FEF3 FF02 1 1# 2 2# 3 4 4# 5 5# 6 6# 7 1 1# 2 2# 3 4 4# 5 5# 6 6# 7 四、Proteus仿真应用

4.1 Proteus软件简介

Proteus软件是英国Labcenter electronics公司出版的EDA工具软件(该软件中国总代理为广州风标电子技术有限公司)。它不仅具有其它EDA工具软件的仿真功能,还能仿真单片机及外围器件。它是目前最好的仿真单片机及外围器件的工具。虽然目前国内推广刚起步,但已受到单片机爱好者、从事单片机教学的教师、致力于单片机开发应用的科技工作者的青睐。Proteus是世界上著名的EDA工具(仿真软件),从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB设计,真正实现了从概念到产品的完整设计。是目前世界上唯一将电路仿真软件、PCB设计软件和虚拟模型仿真软件三合一的设计平台,其处理器模型支持8051、HC11、PIC10/12/16/18/24/30/DsPIC33、AVR、ARM、8086和MSP430等,2010年又增加了Cortex

10

和DSP系列处理器,并持续增加其他系列处理器模型。在编译方面,它也支持IAR、Keil和MPLAB等多种编译器。

4.2 仿真结果

当按下K1键时,显示部分电路中D1灯亮,同时播放第一首歌曲,仿真图如图4-1所示。K4键为停止键,当K4键按下时,同时D4灯亮,停止播放歌曲,仿真图如图4-2所示。

图4-1 仿真效果图1

11

图4-2 仿真效果图2

五、结论

经过这次毕业设计,我觉得自己学到了不少东西。归纳起来,主要有以下几点: 1、通过这次毕业设计,我能将三年所学到的专业知识与实践相联系,将所学到的知识充分运用到本次设计中。同时,我也认识到自己知识上不足的地方,体会到了所学理论知识的重要性,知识掌握得越多,设计得就更全面、更顺利、更好。

2、进一步熟悉了单片机的知识。通过本次设计,我对单片机的基本原理、内部结构、各引脚功能、定时器和中断的应用都有了更深刻的理解。并且,能够以单片机为基础元件设计一个简单的系统。

3、提高了自己查找资料的能力。在设计过程中,我碰到了一些暂时无法解决的问题,于是我通过上网查阅和图书馆借阅资料,或是通过与老师同学交流一步步地解决了。从中我懂得了我们这个专业的知识面相当广泛,同时要懂得与他人交流意见,积极听取别人的建议,懂得团队合作的重要性。

12

参考文献

[1] 郑郁正. 单片机原理及应用. 四川大学出版社,2003. [2] 谭浩强. C程序设计(第二版). 清华大学出版社,1999.

[3] 王晓君,安国臣. MCS—51及兼容单片机原理与选型. 北京:电子工业出版社,2003. [4] 何立民. MCS-51系列单片机应用系统设计[M]. 北京航空航天大学出版社,1990.

[5] 张毅刚、彭喜元、姜守达、乔立岩. 新编MCS-51系列单片机应用设计[M]. 哈尔滨工业大学出版社,2003.6.

[6] 王东锋. 单片机C语言应用100例. 北京:电子工业出版社,2009. [7] 王松武,于鑫,武思军. 电子创新设计与实践. 国防工业出版社,2005. [8] 张毅坤. 单片微型计算机原理及应用. 西安:西安电子科技大学出版社,2005. [9] 房建东,高胜利. 单片机课程设计实例指导. 北京航空航天出版社,2002. [10] 沙占有,王彦朋. 单片机外围电路设计. 电子工业出版社,2009.

[11] 袁兆山. 音乐播放器. 电气自动化, 2006, 23(3): 53-55.

[12] 侯静. 简易的单片机音乐控制. 电子信息工程,2007, 34(2): 126-128.

13

致谢

毕业设计是大学中学习和实践的一个重要环节。它综合的考察了一个学生对过去所学的知识的运用能力和对新知识吸收、消化能力,通过设计,可以培养我们独立思考、开拓创新、勇于探索的能力。在指导老师的精心指导下,我查阅了大量的文献资料,经过三个月的学习、讨论、设计、调试,最终完成了设计方案。通过设计,我们不仅掌握了设计的基本步骤,还学会了科学系统的设计方法,拓宽了知识面。在本课题设计中,为了熟悉课题,我通过图书馆、互联网学习查阅了许多相关的资料,加强了自学能力并且有意识地将掌握知识归纳总结运用到实践中来。

在这次毕业设计过程当中,离不开学校指导老师对我们的全力支持。他们尽最大努力为我们的毕业设计提供好的条件,以使我们的毕业设计能够顺利完成。

在此,我特别感谢苗艳华老师。苗老师在本次设计中给与了我很大的帮助,在理论上使我有了良好的基础,对整个设计有了清楚的思路。在设计过程中给我提出了许多宝贵的意见,并且帮助我一起解决设计中遇到的问题,为本次毕业设计耗费了许多的心血。同时,我也要感谢在设计中给予我支持的其他老师和同学!

14

附录1

整机原理图

15

附录2

#ifndef uchar

#define uchar unsigned char #endif #ifndef uint

#define uint unsigned int #endif

#include #include #include #include #define

/********外部函数声明**********/

//extern void int0_init(); //外部中断0初始化 //extern void key_init();

/********变量声明**********/ //sbit led=P1^0;

/********延时子函数**********/ void Delay1ms(unsigned int count) {

unsigned int i,j; for(i=0;i

16

ledd P1

//按键初始化

extern uchar key_scan(); //键值扫描

}

//*****************************Music****************************************************** //挥着翅膀的女孩

unsigned char code Music_Girl[]={ 0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x03,

0x16,0x03, 0x17,0x03, 0x18,0x03,

0x19,0x02, 0x18,0x02, 0x18,0x03,

0x17,0x03, 0x17,0x03, 0x18,0x02,

0x10,0x03, 0x15,0x03, 0x16,0x03,

0x17,0x02, 0x19,0x02, 0x1A,0x03,

0x1B,0x03, 0x17,0x03, 0x18,0x03,

0x19,0x02, 0x18,0x03, 0x17,0x03,

0x18,0x03, 0x16,0x03, 0x17,0x03,

0x18,0x03, 0x20,0x03, 0x20,0x02,

0x1F,0x03, 0x20,0x03, 0x21,0x03,

0x20,0x03, 0x1F,0x66, 0x1F,0x03,

0x1B,0x03, 0x15,0x03, 0x1A,0x66,

0x1A,0x03, 0x15,0x03, 0x17,0x03,

17

0x17,0x03,

0x16,0x03,

0x15,0x02,

0x15,0x03,

0x17,0x03,

0x1F,0x03,

0x16,0x03,

0x1F,0x03,

0x17,0x03,

0x1B,0x03,

0x1F,0x03,

0x19,0x03,

0x19,0x03,

0x17,0x03,

0x17,0x03,

0x18,0x03,

0x16,0x02,

0x18,0x03,

0x1F,0x03,

0x17,0x03,

0x1F,0x02,

0x18,0x03,

0x1F,0x66,

0x1B,0x03,

0x19,0x03,

0x15,0x03,

0x16,0x66, 0x18,0x03, 0x19,0x03,

0x1F,0x03, 0x20,0x03, 0x21,0x03,

0x20,0x03, 0x1F,0x66, 0x1F,0x03,

0x17,0x04, 0x1B,0x03, 0x1F,0x03, 0x18,0x04, 0x1F,0x66, 0x1B,0x03, 0x1B,0x03, 0x15,0x03, 0x1A,0x66,

0x1A,0x03, 0x1F,0x03, 0x1B,0x03,

0x1F,0x00, 0x1A,0x03, 0x1B,0x03,

0x1B,0x03, 0x19,0x02, 0x17,0x03,

0x15,0x17, 0x17,0x03, 0x18,0x03,

0x17,0x04, 0x17,0x04, 0x18,0x0E,

0x18,0x66, 0x17,0x03, 0x18,0x03,

0x20,0x03, 0x1B,0x03, 0x1F,0x66,

0x20,0x03, 0x1F,0x03, 0x1B,0x03,

0x1F,0x66, 0x1B,0x03, 0x19,0x03,

0x19,0x03, 0x1A,0x03, 0x19,0x03,

0x15,0x03, 0x16,0x66, 0x17,0x04,

0x18,0x04, 0x1F,0x03, 0x1B,0x03,

0x1F,0x66, 0x20,0x03, 0x1F,0x03,

18

0x19,0x03, 0x19,0x03, 0x1A,0x03, 0x1A,0x03, 0x15,0x03, 0x18,0x0E, 0x17,0x03, 0x20,0x02, 0x21,0x03, 0x1F,0x04, 0x15,0x03, 0x15,0x03, 0x18,0x03, 0x20,0x03,

0x19,0x03, 0x19,0x03, 0x1A,0x03, 0x19,0x03, 0x16,0x03, 0x18,0x03, 0x18,0x03, 0x1F,0x03, 0x20,0x03, 0x1B,0x0E, 0x1A,0x66, 0x17,0x03, 0x19,0x03, 0x21,0x03,

0x1B,0x03, 0x1B,0x03, 0x19,0x03,

0x19,0x03, 0x1A,0x03, 0x19,0x03,

0x19,0x03, 0x1F,0x00, 0x18,0x02,

0x18,0x03, 0x15,0x03, 0x15,0x02,

0x18,0x66, 0x15,0x00, 0x00,0x00}; //同一首歌

0x1F,0x66, 0x15,0x03, 0x1F,0x03, 0x1A,0x03, 0x16,0x02,

0x1F,0x03, 0x1A,0x66, 0x1B,0x03, 0x19,0x0D, 0x17,0x02,

unsigned char code Music_Same[]={ 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x66, 0x18,0x03,

0x17,0x02, 0x15,0x02, 0x10,0x02,

0x15,0x00, 0x16,0x02, 0x17,0x02,

0x17,0x03, 0x15,0x02, 0x18,0x66,

0x17,0x03, 0x17,0x03, 0x16,0x00,

0x17,0x01, 0x1B,0x70, 0x1A,0x03,

0x1A,0x01, 0x1A,0x03, 0x1B,0x02,

0x1A,0x0D, 0x18,0x66, 0x18,0x03,

0x19,0x02, 0x18,0x0D, 0x17,0x03,

0x16,0x01, 0x10,0x03, 0x0F,0x0C,

0x10,0x02, 0x1A,0x01, 0x18,0x66,

0x15,0x00,

0x1F,0x01,

0x11,0x02,

0x11,0x03,

0x1A,0x02,

0x19,0x0C,

0x19,0x03,

0x17,0x00,

0x19,0x02,

0x19,0x03,

0x19,0x02,

0x1B,0x02,

0x19,0x02,

0x16,0x03,

0x18,0x03,

0x19,0x02,

0x0F,0x01,

0x15,0x02,

0x15,0x02,

0x16,0x01,

19

0x19,0x03, 0x1B,0x03, 0x1B,0x03,

0x1B,0x0C, 0x17,0x00, 0x1F,0x01,

0x1A,0x01, 0x1A,0x01, 0x10,0x02,

0x10,0x03, 0x18,0x0D, 0x17,0x03,

0x16,0x00, 0x16,0x02, 0x17,0x70,

0x18,0x03, 0x15,0x03, 0x16,0x66,

0x16,0x03, 0x15,0x03, 0x10,0x02,

0x10,0x01, 0x10,0x03, 0x0F,0x0C,

0x1A,0x02, 0x16,0x03, 0x18,0x66,

0x18,0x03, 0x16,0x03, 0x19,0x00,

0x00,0x00 }; //两只蝴蝶

0x1A,0x01, 0x1A,0x0D, 0x18,0x66, 0x10,0x03, 0x0F,0x01, 0x17,0x02, 0x16,0x02, 0x11,0x01, 0x19,0x02, 0x18,0x02,

0x1B,0x02, 0x19,0x03, 0x19,0x03, 0x1A,0x0C, 0x15,0x02, 0x15,0x03, 0x16,0x03, 0x11,0x66, 0x16,0x03, 0x17,0x03,

unsigned char code Music_Two[] ={ 0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03,

0x16,0x03, 0x15,0x03, 0x16,0x02,

0x16,0x0D, 0x15,0x03, 0x10,0x03,

0x10,0x0E, 0x17,0x03, 0x16,0x03,

0x17,0x01, 0x16,0x03, 0x15,0x01,

0x10,0x03, 0x16,0x0D, 0x17,0x03,

20

0x15,0x01, 0x17,0x03, 0x15,0x04, 0x16,0x03, 0x15,0x03,

0x10,0x03, 0x16,0x03, 0x0F,0x01, 0x17,0x03, 0x16,0x02,

0x16,0x03, 0x15,0x03, 0x16,0x01,

0x17,0x03, 0x16,0x03, 0x17,0x03,

0x16,0x03, 0x15,0x03, 0x16,0x02,

0x15,0x03, 0x16,0x03, 0x15,0x01, 0x10,0x03, 0x17,0x01, 0x10,0x03, 0x16,0x0D, 0x15,0x03, 0x10,0x03,

0x10,0x0E, 0x17,0x03, 0x19,0x03,

0x19,0x01, 0x19,0x03, 0x17,0x01,

0x16,0x03, 0x16,0x0D, 0x17,0x03,

0x16,0x03, 0x10,0x0D, 0x15,0x00,

0x19,0x03, 0x1F,0x03, 0x1B,0x03,

0x1B,0x03, 0x16,0x03, 0x16,0x03,

0x16,0x0D, 0x17,0x03, 0x19,0x03,

0x1A,0x02, 0x17,0x0D, 0x16,0x03,

0x16,0x01, 0x19,0x03, 0x17,0x03,

0x19,0x02, 0x1A,0x03, 0x1A,0x0E,

0x1B,0x04, 0x1A,0x03, 0x1A,0x0E,

0x1B,0x04, 0x17,0x03, 0x16,0x03,

0x17,0x0D, 0x19,0x01, 0x19,0x03,

21

0x17,0x03, 0x15,0x04, 0x19,0x03, 0x16,0x03, 0x15,0x03, 0x19,0x03, 0x1A,0x03, 0x17,0x01, 0x1A,0x02, 0x17,0x03, 0x1F,0x02, 0x17,0x02, 0x1A,0x03, 0x16,0x03,

0x16,0x03, 0x0F,0x01, 0x1A,0x03, 0x16,0x02, 0x10,0x03, 0x1A,0x03, 0x17,0x0D, 0x17,0x03, 0x10,0x03, 0x19,0x03, 0x1B,0x03, 0x1A,0x03, 0x19,0x03, 0x17,0x03,

0x19,0x03, 0x1B,0x03, 0x1B,0x03,

0x1A,0x03, 0x16,0x03, 0x16,0x03,

0x17,0x01, 0x19,0x03, 0x1A,0x02,

0x1A,0x02, 0x16,0x03, 0x16,0x01,

0x17,0x03, 0x17,0x03, 0x19,0x03,

0x1F,0x02, 0x1A,0x0E, 0x1B,0x04,

0x17,0x02, 0x1A,0x0E, 0x1B,0x04,

0x17,0x16, 0x1A,0x0E, 0x1B,0x04,

0x1A,0x03, 0x16,0x03, 0x0F,0x02,

0x1A,0x03, 0x17,0x0D, 0x17,0x03, 0x10,0x03, 0x19,0x03, 0x1B,0x03, 0x1A,0x03, 0x1A,0x03, 0x19,0x03,

0x1F,0x03, 0x16,0x03, 0x17,0x03, 0x17,0x0D, 0x19,0x03, 0x1A,0x03, 0x1A,0x03, 0x1A,0x03, 0x17,0x03,

0x10,0x03, 0x15,0x00, 0x00,0x00 }; //*********************************************************************************** void main() {

// uchar key_buff; // key_4_interrupt();

key_4int(); InitialSound(); while(1) {

{

uchar key_buff=0; key_buff=key_scan(); }

22

// if(key_flag==1) // // // //

switch(key_value) { case 1:

{

//

key_value=0; ledd

= 0xfe;

Play(Music_Girl,0,3,360); Delay1ms(100); }

break;

case 2:

{

//

key_value=0; ledd

= 0xfd;

Play(Music_Same,0,3,360);

Delay1ms(100); } break; case 3:

{

//

key_value=0; ledd

= 0xfb;

Play(Music_Two,0,3,360); Delay1ms(100); } break;

case 4:

{

// uchar i; // led=0;

ledd

= 0xf7;

// key_value=0; // for(i=0;i<20;i++) //

led=!led;

23

Delay1ms(100);

} break; default: break;

} /* if(key_value==1)

{

key_value=0; ledd

= 0xf7;

Play(Music_Girl,0,3,360); Delay1ms(100); } if(key_value==2)

{

key_value=0; ledd

= 0xfb;

Play(Music_Same,0,3,360); Delay1ms(100); } if(key_value==3)

{

key_value=0; ledd

= 0xfd;

Play(Music_Two,0,3,360); Delay1ms(100); } if(key_value==4)

{ uchar i; led=0; ledd

= 0xfe;

key_value=0;

for(i=0;i<20;i++)

24

} }

led=!led; Delay1ms(100); }

} */

/*============================================================================

*******************************键盘部分说明***********************

============================================================================*/

#include%uchar8 key_value=0;

/*============================================================================

**函数名称:key_4_interrupt() **函数参数:无 **返回数值:

**函数功能:键盘中断服务函数 **函数描述:无

============================================================================*/

void key_4_interrupt() interrupt 0 {

bit x = 0; EX0

= 0;

key_4delay(5);

key_value = read_key(); while(x==0)

25

; }

{

x = keyint; }

EX0 = 1;

/*============================================================================

**函数名称:key_4delay(usint8 x) **函数参数:x 需延时的ms数 **返回数值:无

**函数功能:键盘中断服务函数 **函数描述:无

============================================================================*/

void key_4delay(usint8 x) { }

/*============================================================================

26

usint8 i; for(x;x>0;x--) {

for(i=124;i>0;i--) { } }

;

**函数名称:read_key() **函数参数:无 **返回数值:

**函数功能:键盘中断服务函数 **函数描述:无

============================================================================*/

uchar8 read_key() { }

key1 {

case 0xfe: }

return key;

key = 1; break; key = 2; break; key = 3; break; key = 4; break; break; case 0xfd: case 0xfb: case 0xf7: default:

= key_port;

switch(key1) uchar8 key,key1; key_port = 0xff;

27

/*============================================================================

**函数名称:key_4int() **函数参数:无 **返回数值:

**函数功能:键盘初始化函数/模块测试时的主函数 **函数描述:无

============================================================================*/

//void main() void key_4int() {

IT0 = 1; EX0 = 1; EA = 1;

//外部中INT0中断触发方式设置,0:电平控制 //外部中断0,允许中断 //开放总中断。 //

1:脉

冲触发。

// _nop_(); // _nop_(); // _nop_(); // _nop_(); // _nop_(); // while(1) // { // ; // } } 头文件

/*============================================================================

************************

********************************

28

============================================================================*/ #ifndef #define

/************包含文件说明***********/

#include\#include\#include \

/*********外部调用函数申明**********/

extern void

key_4delay(usint8 x);

//延时子程序

//读键值子函数 //键盘部分初始化子函数

extern uchar8 read_key(); extern void key_4int();

/*********外部使用变量申明**********/

extern uchar8 key_value;

/*************键盘接口**************/ #define

key_port P2

= P2^0; = P2^1; = P2^2; = P2^3;

//键盘接口

键值为1 键值为2 键值为3 键值为4

sbit key1 sbit key2 sbit key3 sbit key4 #endif

//按键1 //按键2 //按键3 //按键4

//键值

key_4_H key_4_H

sbit keyint = P3^2; //按键中断接线端口

29