立即注册 登录
返回首页

uid:184758的个人空间

日志

多功能电子琴课程设计模板

已有 972 次阅读2017-8-8 16:04

 

 

信息工程学院

《专业工程技术应用训练》报告

2016-2017学年第2学期)

 

 

课程设计题目:   电子琴

 

 

   名:  蔡沛华         

   号:  0915140902     

   级:  B1409班       

   业:  电子信息工程   

 

 

 

 

 


《专业工程技术应用训练》考查评分表

姓名

蔡沛华

学号

0915140902

班级

B1409班

设计题目

 

分 项 目

平时表现

(20%)

1、出勤率: □全勤    □缺勤较少  □缺勤较多  □全缺

2、进度:   □较快    □正常      □较慢      □没有按时完成

硬件制作(20%)

布局焊接:  □合理          □较合理          □基本合理

□错误较多      □原则性错误

软件编程

(20%)

1、程序编写框架:□合理    □较合理     □基本合理

    □错误较多             □原则性错误

2、程序编写过程:□正确    □较正确     □基本正确

    □错漏较多

功能调试 

(10%)

系统调试结果:□实现    □基本实现     □不能实现

设计报告(15%)

1、硬件设计:  □合理  □较合理   □基本合理  □不合理

2、软件设计:  □合理  □较合理   □基本合理  □不合理

3、联调结果:  □正确  □较正确   □基本正确  □错漏较多

4、过程体会:  □属实  □较属实   □基本属实  □不属实

答辩

(15%)

□思路清晰,内容正确            □思路较清晰,内容较正确  

   □思路基本清晰,内容基本正确    □思路较混乱,内容错漏较多

总评

优秀   良好  中等

及格   不及格

指导教师:      

2017 年       日

 


一、设计任务及要求:

设计任务:

1设计一个简易电子琴;

2利用定时器产生do,re,mi...7个音符的中频率,共8阶信号;

3功能方面:播放模式,够单独播放天空之城、世上只有妈妈好和国歌三首歌曲;能够在三首歌曲和弹奏模式之间切换;弹奏模式,可以单独一次存储回放歌曲;切换模式,切换到歌曲时可以暂停播放歌曲,切换到自由模式也可以弹奏歌曲。

4LED指示相应琴键按下同时当播放歌曲时,用LED灯指示相应音符节奏灯。

求:

首先进行预设计,根据设计的任务要求,先确定设计的硬件电路方案,然后进行硬件电路的初步设计,在计算机上画出硬件电路图,在老师的指导下进行修正硬件电路图,并对所涉及的参数进行计算。

在确定硬件的基础上,要进行软件的总体设计,包括软件主程序和各子程序的设计,同时,要写出详细的操作说明,如歌曲的调整方法,显示窗口的灯切换等,以配合软件的设计。

进入硬件的调试及编程工作,可根据时间进行分工,有调试硬件各功能模块的,如播映音乐、显示节奏灯等,有进行整体程序的编制的,各模块的编制过程中要注意资源的衔接。

最后进入联机调试,联机调试的原则也要采用分步走的原则,各个功能模块要逐步套入,通过一个再增加一项功能,从而达到设计的总体要求,不要上来编制个最大的程序,最后无法查找错误。

最后写出设计报告。

 

指导教师签名:                

2017              


目录

1、绪 言 1

2、系统设计 2

2.1 设计任务 2

2.2 方案比较与论证 2

2.2.1 系统整体流程图 2

2.2.2 电子琴的控制方案论证 2

2.2.3 单片机的选择方案论证 3

2.2.4 显示模块的选择方案论证 4

2.2.5 播音模块的选择方案论证 4

3、 硬件电路设计 5

3.1 电子琴控制电路图 5

3.2 弹琴模块键盘的设计 5

3.3功能模块键盘的设计 6

3.4 播音模块的设计 6

3.5 LED灯显示模块的设计 7

3.6主要元器件 7

4、软件设计 8

4.1流程图 8

4.1.1主流程图 8

4.1.2暂停按键流程图 9

4.1.3切换按键流程图 10

4.2 单片机不同频率声音产生 11

4.3 音乐相关知识 12

4.4 音乐播放原理 12

5、仿真与调试运行 14

5.1 Keil调试 14

5.2 Proteus调试 15

5.3 实物图 16

5.4 Proteus和实物误差分析 16

6、结束语 17

7、参考文献 18

8、附录 19


1、绪 言

近年来随着科技的飞速发展,单片机的应用正在不断地走向深入,同时带动传统控制检测日新月异更新。在实时检测和自动控制的单片机应用系统中,单片机往往是作为一个核心部件来使用,仅单片机方面知识是不够的,还应根据具体硬件结构,以及针对具体应用对象特点的软件结合,加以完善。电子琴是现代社会中的主要计时工具之一,广泛应用于社会生活需要的各个方面,及对音乐有要求的场合。本设计采用STC89C52RC单片机作为主要核心部件,由复位电路、时钟电路、电路组成、弹琴电路、功能键电路和音符灯组成。电子琴的发明极大地推动了流行音乐的发展;电子琴的发明使人们可以演奏出未曾拥有的音色,丰富了人们情感的表现;电子琴的发明推动了音乐的普及,它让音乐真正成为了大众的音乐,成为了人类社会不可缺少的东西;电子琴作为科技与音乐的产物,在信息化和电子化的时代,为音乐的大众化做出了不可磨灭的贡献,现代歌曲的制作,很多都需要电子琴才能完成,然后才通过媒介流传开来,电视剧电影插曲、电视节目音效 、甚至你的手机铃声,都很可能包含电子琴的身影。


2、系统设计2.1 设计任务

 

1设计一个简易电子琴;

2利用定时器产生do,re,mi...7个音符的低中高频率,共8阶信号;

3功能方面:播放模式,够单独播放天空之城、世上只有妈妈好和国歌三首歌曲;能够在三首歌曲和弹奏模式之间切换;弹奏模式,可以单独一次存储回放歌曲;切换模式,切换到歌曲时可以暂停播放歌曲,切换到自由模式也可以弹奏歌曲。

4LED指示相应琴键按下同时当播放歌曲时,用LED灯指示相应音符节奏灯。

2.2 方案比较与论证2.2.1 系统整体流程图

2.2.2 电子琴的控制方案论证

方案一:独立按键式,直接用I/O口线构成的单个按键电路,其特点式每个按键单独占用一根I/O口线,每个按键的工作不会影响其他I/O口线的状态。独立按键的典型应用如图所示。独立式按键电路配置灵活,软件结构简单,但每个按键必须占用一个I/O口线,因此,在按键较多时,I/O口线浪费较大,不宜采用。

方案二:矩阵键盘又称行列键盘,它是用四条I/O线作为行线,四条I/O线作为列线组成的键盘。在行线和列线的每个交叉点上设置一个按键。这样键盘上按键的个数就为4*4个。这种行列式键盘结构能有效地提高单片机系统中I/O口的利用率。

由于电子琴电路比较简单:采用方案一。

2.2.3 单片机的选择方案论证

方案一:采用可编程逻辑期间CPLD 作为控制器。CPLD可以实现各种复杂的逻辑功能、规模大、密度高、体积小、稳定性高、IO资源丰富、易于进行功能扩展。采用并行的输入输出方式,提高了系统的处理速度,适合作为大规模控制系统的控制核心。但本系统不需要复杂的逻辑功能,对数据的处理速度的要求也不是非常高,且从使用及经济的角度考虑我们放弃了此方案

方案二:采用STC公司的STC89S52RC单片机作为控制器。  

STC89C52RC单片机是宏晶科技推出的新一代高速/低功耗/超强抗干扰的单片机,指令代码完全兼容传统8051单片机,12时钟/机器周期和6时钟/机器周期可以任意选择。 

主要特性如下: 

1.增强型8051单片机,6时钟/机器周期和12时钟/机器周期可以任意

选择,指令代码完全兼容传统8051; 

2.工作电压:5.5V~3.3V(5V单片机)/3.8V~2.0V(3V单片机)

3.工作频率范围:0~40MHz,相当于普通8051的0~80MHz,实际工作

频率可达48MHz 

4.用户应用程序空间为8K字节 

5.片上集成512字节RAM 

6.通用I/O口(32个),复位后为:P1/P2/P3是弱上拉,

P0口是漏极开路输出,作为总线扩展用时,不用加上拉电阻,作为I/O口用时,需加上拉电阻。 

7.ISP(在系统可编程)/IAP(在应用可编程),无需专用编程器,无需专用仿真器,可通过串口(RxD/P3.0,TxD/P3.1)直接下载用户程序,数秒即可完成一片 

8.具有EEPROM功能 

9.具有看门狗功能 

10.共3个16位定时器/计数器。即定时器T0、T1、T2 

11.外部中断4路,下降沿中断或低电平触发电路,Power Down模式可

由外部中断低电平触发中断方式唤醒 

12.通用异步串行口(UART),还可用定时器软件实现多个UART

13.工作温度范围:-40~+85℃(工业级)/0~75℃(商业级) 

14.PDIP封装

综合考虑,选择方案二,采用STC公司的STC89S52RC单片机作为控制器。

2.2.4 显示模块的选择方案论证

方案一:采用带字库LCD模块显示。能显示复杂的信息,具有质量轻,体积小,功耗低,指令功能强,接口简单,可靠性强等优点,显示内容丰富,图形美观,易于人机交流,但是价格昂贵。

方案二:首先弹奏和播放音乐时可以对应的节奏灯亮,这些LCD1602液晶屏是做不到的;其次在播放音乐时也可以放音符节奏灯,这样非常美观和既可以听动听的歌又可以看灯。

电子琴选用方案二,显示所需信息。

2.2.5 播音模块的选择方案论证

方案一:采用蜂鸣器:蜂鸣器一般是高阻,直流电阻无限大,交流阻抗也很大,窄带发声器件,通常由压电陶瓷片发声。需要较大的电压来驱动,但电流很小,几mA就可以了,功率也很小。
  有源蜂鸣器,内部有振荡、驱动电路。加电源就可以响,你所说的估计就是那种。优点是用起来省事,缺点是频率固定了,就只一个单音。
  无源的蜂鸣器与喇叭一样,需要加上交变的音频电压才能发声,也可以发出不同频率的声音。不过,蜂鸣器的声音反正是不好听的,所以经常是加上方波,而不是加正弦。

方案二:喇叭则是低阻,直流电阻几乎是0,交流阻抗一般几欧到十几欧。宽频发声器件,通常由利用线圈的电磁力推动膜片。

电子琴选用方案二,播出所需要音乐。


3 硬件电路设计3.1 电子琴控制电路图

 

3.1 电子琴控制线路图

3.2 弹琴模块键盘的设计

 

3.2 电子琴弹琴模块

弹琴从前往后分别代表是do, re, mi, fa ,suo, la, si ,do ”八个按键


3.3功能模块键盘的设计

 

3.3 电子琴功能模块

功能键从前往后分别表示播放天空之城、存储回放、暂停回放、播放世上只有妈妈好、国歌和暂停键。

3.4 播音模块的设计

 

3.4 电子琴播放模块

通过P3.7口然后用三极管NPN对喇叭声音进行放大从而达到声音放大。


3.5 LED灯显示模块的设计

 

3.5 电子琴播放模块

听过控制功能键既播放不同音乐也可以显示相应LED灯,同时播放音乐时利用音乐的音符进行显示音乐节奏灯。

3.6主要元器件

器件

数量

Stc89c52RC单片机

1

四脚按键

16

8欧喇叭

1

发光二极管

10

220欧电阻

8

9103排阻

1

12MHZ晶振

1

22pf电容

2

NPN三极管

1

刀闸开关

1

USB母口

1

电解电容

1

电阻10K

1

40脚底座

1

排针

2

排母

2

杜邦线公对母

1


4软件设计

该程序设计思路比较清晰既从开始到声明变量与函数再到读取按钮开关,判断是否按下,然后就是一个一个按钮的动作。其主程序如图6所示。

4.1流程图4.1.1主流程图

 

4.1.1为主流程图


4.1.2暂停按键流程图

 

4.1.2为暂停按键流程图


4.1.3切换按键流程图

 

4.1.3为切换按键流程图


4.2 单片机不同频率声音产生

1.要产生音频脉冲,只要算出某一音频的周期(1/频率),然后将此周期除以 2,即得出半周期的时间。利用定时器计时这个半周期时间,每当计时到后就将输出脉冲的 I/O 反相,然后重复计时此半周期时间再对 I/O 反相,就可在 I/O 脚上得到此频率的脉冲。

2.利用 8051 的内部定时器,使用其工作在模式 1 下,改变定时值 TH0 及 TL0 可以产生不同频率的音频脉冲。

3.例如频率为 523Hz,其周期 T=1/523=1912us,因此只要令定时器计时 956us/1us=956,

在每次计数 956 次时将 I/O 反相,就可得到中音 DO(523Hz)。

计数脉冲值与频率的关系公式如下:

N=Fi÷2÷Fr

N:计数次数;

Fi:音频脉冲频率;

Fr:单片机的机器周期;

4.定时器初始值的求法如下:

T=65536-N=65536-Fi÷2÷Fr

例如:设 K=65536,F=1000000=Fi=1MHz,求低音 DO(261Hz)、中音 DO(523Hz)、

高音的 DO(1046Hz)的定时器初始值。

T=65536-N=65536-Fi÷2÷Fr=65536-1000000÷2÷Fr=65536-500000/Fr

低音 DO:T=65536-500000/262=63627

中音 DO:T=65536-500000/523=64580

高音 DO:T=65536-500000/1047=65059

 


4.3 音乐相关知识

乐音听起来有的高,有的低,这就叫音高,音高是由发音物体振动频率的高低决定的,频率高声音就高,频率低声音就低,不同音商的乐音是用CDEFGAB表示的,这7个字母就是乐音的音名,它们一般依次唱成DOREMIFASOLASI,这是唱曲时乐音的发音,所以叫唱名。

音持续时间的长短即时值,一般用拍数表示,休止符表示暂停发音。

一首音乐是由许多不同的音符组成的,而每个音符对应着不同的频率,这样就可以利用不同频率的组合,加以与拍数对应的延时,构成音乐。

4.4 音乐播放原理

要想播放出一首曲子,了音符以外,节拍也是音乐的关键组成部分。节拍实际上就是音持续时间的长短,在单片机系统中可以用延时来实现,如果1/4拍的延时是0.4秒,则1拍的延时是1.6秒,只要知道1/4拍的延时时间,其余的节拍延时时间就是它的陪数。如果单片机要自己播放音乐,那么必须在程序设计中考虑到节拍的设置,由于本例实现的音乐发生器是由用户通过键盘输入弹奏乐曲的,所以节拍由用户掌握,不由程序控制。对于不同的曲调我们也可以用单片机的另外一个定时/计数器来完成。音乐的音拍,一个节拍为单位(C调)具体如表3所示:

  3 音乐节拍表

曲调值

DELAY

 

曲调值

DELAY

调4/4

125ms

 

调4/4

62ms

调3/4

187ms

 

调3/4

94ms

调2/4

250ms

 

调2/4

125ms

                          

每一个音的发出需要3个元素,音节,中低高音调,节拍。类似于以下:只有妈妈好数据表

code uchar sszymmh[]={6,2,3,  5,2,1,  3,2,2, 5,2,2, 1,3,2, 6,2,1, 5,2,1,

                      6,2,4,  3,2,2,  5,2,1, 6,2,1, 5,2,2, 3,2,2, 1,2,1,

                      6,1,1,  5,2,1,  3,2,1, 2,2,4, 2,2,3, 3,2,1, 5,2,2,

  5,2,1,  6,2,1,  3,2,2, 2,2,2, 1,2,4, 5,2,3, 3,2,1,

  2,2,1,  1,2,1,  6,1,1, 1,2,1, 5,1,6, 0,0,0 };  

1)三个数字为一组;

2)第一个数字为do,re,mi....中之一;

3)第二个数字为低音<1>,中音<2>,高音<3>之一;

4)第三个数字为节拍,11/4节拍,以此类推。

 


简谱

发音

简谱码

T值

节拍码

节拍数

5

低音SO

1

64260

1

1/4拍

6

低音LA

2

64400

2

2/4拍

7

低音TI

3

64524

3

3/4拍

1

中音DO

4

64580

4

1拍

2

中音RE

5

64684

5

1又1/4拍

3

中音MI

6

64777

6

1又1/2拍

4

中音FA

7

64820

8

2拍

5

中音SO

8

64898

A

2又1/2拍

6

中音LA

9

64968

C

3拍

7

中音TI

A

65030

F

3又3/4拍

1

高音DO

B

65058

 

 

2

高音RE

C

65110

 

 

3

高音MI

D

65157

 

 

4

高音FA

E

65178

 

 

5

高音SO

F

65217

 

 

图为4.2为各音符频率与简谱码T对应表


5仿真与调试运行

在完成了电子琴硬件设计和软件设计以后,便进入系统的调试阶段。系统的调试步骤和方法基本上是相同的,但具体细节和所采用的开发系统以及用户系统选用的单片机型号有关,如可选用Keil软件进行软件调试,用Proteus软件完成硬件调试。

5.1 Keil调试

Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。Keil提供了包括C编译器、宏汇编、链接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(μVision)将这些部分组合在一起。运行Keil软件需要WIN98、NT、WIN2000、WINXP等操作系统。如果你使用C语言编程,那么Keil几乎就是你的不二之选,即使不使用C语言而仅用汇编语言编程,其方便易用的集成环境、强大的软件仿真调试工具也会令你事半功倍。

 

 

5.1 KEIL调试


5.2 Proteus调

Proteus软件是英国Lab Center Electronics公司出版的EDA工具软件(该软件中国总代理为广州风标电子技术有限公司)。它不仅具有其它EDA工具软件的仿真功能,还能仿真单片机及外围器件。它是目前比较好的仿真单片机及外围器件的工具。虽然目前国内推广刚起步,但已受到单片机爱好者、从事单片机教学的教师、致力于单片机开发应用的科技工作者的青睐。

Proteus是英国著名的EDA工具(仿真软件),从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB设计,真正实现了从概念到产品的完整设计。是目前世界上唯一将电路仿真软件、PCB设计软件和虚拟模型仿真软件三合一的设计平台,其处理器模型支持8051、HC11、PIC10/12/16/18/24/30/DsPIC33、AVR、ARM、8086和MSP430等,2010年又增加了Cortex和DSP系列处理器,并持续增加其他系列处理器模型。在编译方面,它也支持IAR、Keil和MPLAB等多种编译器。

 

5.2 proteus调试

 

5.3 实物图

 

 

图为5.3实物图

5.4 Proteus和实物误差分析

本设计中Proteus仿真在电子琴使用功能模块中的存储回放时,出现了按一下弹琴按键,出现两个声音甚至三个声音回放。其次,在播放歌曲时出现了一些杂音。

①可能就是对按键消抖时间不够;也有可能就是按键时间按得太长。所以要想办法设法控制好消抖时间和按键时间。

②喇叭出现一些杂音可能是因为焊接时候接线没焊好;还有就是因为线路较多,单片机所有I/O口几乎全用,因此都对声音有一定的影响。对电路里面的线路逐步检查好。


6结束语

由于此次是第三次课程设计,因而现在已经知道课程设计大概的流程,并且现在我们已经是大三的学生,对于专业课的学习已经更进一步,与之前相比我们知识的广度和深度已有所进步。这个学期已经系统地学习了单片机的原理及应用,在此次的设计中用Keil C51编写。

在设计的过程中,查阅过很多的资料,经过分析后最终确定了方案。由于知识的局限性我们在设计的时候,依然遇到一些问题,最后在老师的指导和帮助下,得到了解决。首先在存储回放这个功能时,遇到很多问题,那就是不知道编写回放程序,经过几天的寻找,在网上找到类似的程序,但是在做仿真的时候,有时候每按一个按键,回放的时候可能是几个声音,改了好几个延时都没出来,但是在焊完硬件和调试后弹琴的声音结果正常回放,这样我知道仿真和实际硬件有很大差距。其次就是设置暂停键的时候,打算通过外部中断进行触发死循环来起到暂停作用,但是后来也调不出来,刚刚开始是没有对外部中断初始化,后来就是while循环位置放错导致按了暂停按键也继续发声音。

总之,在大三这个学期接触到的专业知识的知识面越来越多,因而也知晓了更多的知识。众所周知学习是一个无止境的过程,我们要珍惜现在所拥有的资源。课程设计是一个很好地检验我们能力的过程。在这个过程中我们会遇到这样或者那样的难题,会迷茫会无助,但是当我们解决了遇到的难题之后的那种愉悦之情是永远无法忘怀的。还有就是我看到其他同学做得有更好的课程设计,进一步激发我对单片机和ARM嵌入式的兴趣,为我以后大四以至于毕业工作做好铺垫。

 


 

7、参考文献

[1]路勇.《电子电路实验与仿真》[M]. 北京:清华大学出版社,2014

[2]康华光.《电子技术基础 数字部分》(第五版)[M].北京:高等教育出版社,2016.01     

[3]谢自美.《电子线路设计实验测试》[M]. 武汉:华中科技大学出版社,2006

[4]康华光.《电子技术基础 模拟部分》(第五版)[M].北京:高等教育出版社,2016.01

[5]张毅刚.《单片机原理及应用》(第二版)[M]. 北京:高等教育出版社,2015.5

[6]李广弟等.单片机基础[M].北京航空航天出版社2013.

[7]王东峰.单片机C语言应用100例[M].电子工业出版社2015.

[8]陈海宴.51单片机原理及应用[M].北京航空航天大学出版社2013.

[9]刘守义.单片机技术基础[M].西安电子科技大学出版社2017.

[10]钟富昭等.8051单片机典型模块设计与应用[M].人民邮电出版社2014.

[11]李平等.单片机入门与开发[M].机械工业出版社,2012.


8、附录

#include<AT89X52.h>

#define KeyPort P0

unsigned char High,Low,t,h; //定时器预装值的高8位和低8

sbit SPK=P3^7;          //定义蜂鸣器接口

sbit playSongKey=P3^0;           //功能键

sbit keybofang=P3^1;    //播放键

sbit tingzhi=P3^2;

sbit playSongKey1=P3^4;

sbit playSongKey2=P3^5;

sbit qiehuan=P3^3;

unsigned char code freq[][2]={

  0xD8,0xF7,//00440HZ 1   

  0xBD,0xF8,//00494HZ 2  

  0x87,0xF9,//00554HZ 3  

  0xE4,0xF9,//00587HZ 4    

  0x90,0xFA,//00659HZ 5     

  0x29,0xFB,//00740HZ 6     

  0xB1,0xFB,//00831HZ 7      

  0xEF,0xFB,//00880HZ 1

};

 

unsigned char Time,temp,song3[50],t1,flag=0,count=-1;

unsigned char code YINFU[9][1]={{' '},{'1'},{'2'},{'3'},{'4'},{'5'},{'6'},{'7'},{'8'}};

                          //天空之城

unsigned char code MUSIC[]={

6,2,1,      7,2,1,      1,3,3,  7,2,1,    1,3,2,    3,3,2,    7,2,6,

3,2,1,      3,2,1,      6,2,3,  5,2,1,    6,2,2, 1,3,2,   5,2,6,

3,2,2,      4,2,3,      3,2,1, 4,2,2,   1,3,2, 3,2,5,    1,3,1,

1,3,1,      1,3,1,      7,2,3, 4,2,1,    4,2,2, 7,2,2,   7,2,6,

6,2,1,      7,2,1,      1,3,3, 7,2,1,   1,3,2,   3,3,2,   7,2,6,

3,2,1,      3,2,1,      6,2,3, 5,2,1,   6,2,2,   1,3,2,   5,2,6,

2,2,1,      3,2,1,      4,2,2, 1,3,1,   7,2,2,   1,3,3,   2,3,1,

2,3,1,      3,3,1,      1,3,5, 1,3,1,   7,2,1,   6,2,1,   6,2,1,

7,2,2,      5,2,2,      6,2,6, 1,3,1,   2,3,1,   3,3,3,   2,3,1,

3,3,2,      5,3,2,      2,3,6, 5,2,1,   5,2,1,   1,3,3,   7,2,1,

1,3,2,      3,3,2,      3,3,8, 6,2,1,   7,2,1,   1,3,2,   7,2,2,

2,3,1,      2,3,1,      1,3,3, 5,2,5,   4,3,2,   3,3,2,   2,3,2,

1,3,2,      3,3,6,      3,3,2, 6,3,4,   5,3,2,   5,3,2,   3,3,1,

2,3,1,      1,3,5,      1,3,1, 2,3,2,   1,3,1,   2,3,1,   2,3,2,

5,3,2,      3,3,6,      3,3,2, 6,3,4,   5,3,4,   3,3,1,   2,3,1,

1,3,5,      1,3,1,      2,3,2, 1,3,1,   2,3,3,   7,2,2,   0,0,0

                             

                                      };

unsigned char code MUSIC1[]={ //世上只有妈妈好

6,2,3, 5,2,1, 3,2,2, 5,2,2, 1,3,2, 6,2,1, 5,2,1,

6,2,4, 3,2,2, 5,2,1, 6,2,1, 5,2,2, 3,2,2, 1,2,1,

6,1,1, 5,2,1, 3,2,1, 2,2,4, 2,2,3, 3,2,1, 5,2,2,

5,2,1, 6,2,1, 3,2,2, 2,2,2, 1,2,4, 5,2,3, 3,2,1,

2,2,1, 1,2,1, 6,1,1, 1,2,1, 5,1,6, 0,0,0

                                      };

unsigned char code MUSIC2[]={ //中华人民共和国国歌

5,1,1, 1,2,3, 1,2,1, 1,2,1, 1,2,1, 5,1,1, 6,1,1, 7,1,1, 1,2,2, 1,2,2,

3,2,1, 1,2,1, 2,2,1, 3,2,1, 5,2,2, 5,2,1, 5,2,2,

3,2,2, 3,2,1, 1,2,2, 3,2,1, 5,2,2, 3,2,1, 2,2,2, 2,2,4,

6,2,2,5,2,2,2,2,2,3,2,2,5,2,1,3,2,2,5,2,1,3,2,1,2,2,1,3,2,1,1,2,1,2,2,1,3,2,2,

5,2,2,6,1,1,1,2,1,1,2,1,3,2,2,3,2,1,5,2,2,5,2,1,2,2,1,2,2,1,2,2,1,6,1,1,6,1,1,2,2,4,

5,1,1,1,2,3,1,2,1,3,2,3,3,2,1,5,2,4,5,2,4,

1,2,2,3,2,1,5,2,1,5,1,1,6,2,2,5,2,2,

3,2,2,1,2,1,5,2,1,5,2,1,5,2,1,3,2,1,1,2,1,5,1,2,1,2,2,

3,1,1,1,1,1,5,2,1,5,2,1,5,2,1,3,2,1,1,2,1,5,1,2,1,2,2,5,1,2,1,2,2,5,1,2,1,2,2,1,2,2,

0, 0, 0};

 

                         // 音阶频率表 高八位

unsigned char code FREQH[]={

                         0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8,

                         0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC, //1,2,3,4,5,6,7,8,i

                         0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,

                         0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,

                               } ;

                         // 音阶频率表 低八位

unsigned char code FREQL[]={

                         0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,

                         0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F, //1,2,3,4,5,6,7,8,i

                         0xEE,0x44, 0x6B,0xB4,0xF4,0x2D,

                         0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,

                                };

 

void Init_Timer0(void);//定时器初始化

 

//延时函数大约约2*z+5us

void delay2xus(unsigned char z)

{

   while(z--);

}

// 延时函数大约约1ms

void delayms(unsigned char x)

{

   while(x--)

   {

     delay2xus(200);

     

   }

}

 

 

/*------------------------------------------------

                节拍延时函数

 各调1/4节拍时间:

 4/4  125ms

 2/4  250ms

 3/4  187ms

------------------------------------------------*/

void delayTips(unsigned char t)

{

    unsigned char i;

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

    {

            delayms(250);

    }

    TR0=0;

 }

//播放音乐的函数

void PlaySong()

{

   TH0=High;//赋值定时器时间,决定频率

   TL0=Low;

   TR0=1;      //打开定时器

   switch(t)

                {

                 case 1:h=0xfe;break;

                 case 2:h=0xfd;break;

                 case 3:h=0xfb;break;

                 case 4:h=0xf7;break;

                 case 5:h=0xef;break;

                 case 6:h=0xdf;break;

                 case 7:h=0xbf;break;

                 case 8:h=0x7f;break;      //分别对应不用的音调

                 default:h=0xFF;break;

                }

P1=h;

   delayTips(Time); //延时所需要的节拍                      

}

void Init_EX(void)

{

  EX0=1;EX1=1;

  IT0=1;IT1=1;

 

}

//定时器T0初始化子程序

void Init_Timer0(void)

{

 TMOD |= 0x01;          //使用模式116位定时器,使用"|"符号可以在使用多个定时器时不受影响                     

 EA=1;            //总中断打开

 ET0=1;           //定时器中断打开

}

//定时器T0中断子程序

void Timer0_isr(void) interrupt 1

{

 TH0=High;

 TL0=Low;

 SPK=!SPK;

}

//主函数

void main (void)

{

  unsigned char num,k,i;

  Init_EX();                 

  Init_Timer0();    //初始化定时器0,主要用于数码管动态扫描

  SPK=0;                        //在未按键时,喇叭低电平,防止长期高电平损坏喇叭         

  while (1)

  {

   /* 按键播音 */

   switch(KeyPort)          //对按键进行处理

                {

                 case 0xfe:num= 1;temp=1;delayms(2000);break;

                 case 0xfd:num= 2;temp=1;delayms(2000);break;

                 case 0xfb:num= 3;temp=1;delayms(2000);break;

                 case 0xf7:num= 4;temp=1;delayms(2000);break;

                 case 0xef:num= 5;temp=1;delayms(2000);break;

                 case 0xdf:num= 6;temp=1;delayms(2000);break;

                 case 0xbf:num= 7;temp=1;delayms(2000);break;

                 case 0x7f:num= 8;temp=1;delayms(2000);break;      //分别对应不用的音调

                 default:num= 0;temp=0;delayms(2000);break;

                }

delayms(20000);

    P1 = KeyPort;

    if(num==0)

    {

       TR0=0;

       SPK=0;   //在未按键时,喇叭低电平,防止长期高电平损坏喇叭

          }

    else

    {

            High=freq[num-1][1];

            Low =freq[num-1][0];

            TR0=1;

          }

/* 按键播音存储 */

 

 if(temp==1) //标志位,如果标志位为1,则说明有按键被按下

{

temp=0; //将标识位归零

song3[t1++]=num; //将数据存入song3[]数组

}

 

 

/* 天空之城按键播音 */

     if(playSongKey==0||count==0)        //如果播放音乐按键被按下

   {

     delayms(10);

     if(playSongKey==0||count==0)

     {

       i=0;

     

       while((i<1000))

            {

    while(flag);   //暂停播放键

if(count==1)break;

t=MUSIC[i];         

            k=MUSIC[i]+7*MUSIC[i+1]-1;//去音符振荡频率所需数据

            High=FREQH[k];

            Low=FREQL[k];

            Time=MUSIC[i+2];          //节拍时长

            i=i+3;

            if(P0!=0xff)//长按任意8音键退出播放

            {

               delayms(10);

               if(P0!=0xff)

                i=1000;                 

            }            

            PlaySong();  

            }

                 

   TR0=0;

              }

   }

/* 世上只有妈妈好按键播音 */    

    if(playSongKey1==0||count==1)        //如果播放音乐按键被按下

   {

     delayms(10);

     if(playSongKey1==0||count==1)

     {

       i=0;

     

       while((i<1000))

            {

                   while(flag);   //暂停播放键

   if(count==2)break;

t=MUSIC1[i];         

            k=MUSIC1[i]+7*MUSIC1[i+1]-1;//去音符振荡频率所需数据

            High=FREQH[k];

            Low=FREQL[k];

            Time=MUSIC1[i+2];          //节拍时长

            i=i+3;

            if(P0!=0xff)//长按任意8音键退出播放

            {

               delayms(10);

               if(P0!=0xff)

                i=1000;                 

            }            

            PlaySong();  

            }

                 

   TR0=0;

              }

   }

 

/* 中华人民共和国国歌按键播音 */

if(playSongKey2==0||count==2)        //如果播放音乐按键被按下

   {

     delayms(10);

     if(playSongKey2==0||count==2)

     {

       i=0;

     

       while((i<1000))

            {

                  while(flag);   //暂停播放键

  if(count==3)break;

t=MUSIC2[i];         

            k=MUSIC2[i]+7*MUSIC2[i+1]-1;//去音符振荡频率所需数据

            High=FREQH[k];

            Low=FREQL[k];

            Time=MUSIC2[i+2];          //节拍时长

            i=i+3;

            if(P0!=0xff)//长按任意8音键退出播放

            {

               delayms(10);

               if(P0!=0xff)

                i=1000;                 

            }            

            PlaySong();  

            }

                 

   TR0=0;

              }

   }

/* 回放键 */

   if(keybofang==0) //回放键

{

    

delayms(10);

while(!keybofang); //检测回放键是否被按下

song3[t1++]=30;

    t1=0;

while(song3[i]!=30) //进入while循环。

{

 

                   High=freq[song3[i]-1][1];

                   Low =freq[song3[i]-1][0];

                   TR0=1;

   delayms(220);

   i++;

   TR0=0;

   delayms(220);

            }    

  

}

 }

 }

void E0()interrupt 0  //外部中断0作为暂停/播放键

{

   

if(tingzhi==0);

{

delayms(5);

if(tingzhi==0)

{

   flag=~flag;

  

}

}

 

}

 

void E1()interrupt 2  //外部中断1作为切换键

{

   

if(qiehuan==0);

{

delayms(5);

if(qiehuan==0)

{

   count++;

   if(count==5)count=0;

  

}

}

 

}

 

 

 

 


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

返回顶部