电子琴课程设计报告

上传人:无*** 文档编号:91921659 上传时间:2022-05-17 格式:DOC 页数:17 大小:146KB
收藏 版权申诉 举报 下载
电子琴课程设计报告_第1页
第1页 / 共17页
电子琴课程设计报告_第2页
第2页 / 共17页
电子琴课程设计报告_第3页
第3页 / 共17页
资源描述:

《电子琴课程设计报告》由会员分享,可在线阅读,更多相关《电子琴课程设计报告(17页珍藏版)》请在装配图网上搜索。

1、-河南理工大学单片机应用与仿真训练设计报告模拟电子琴发声控制系统姓 名: 周 鹏 邓 旭学 号:0 0专业班级: 电信0803班指导老师:高如新 珊 所在学院: 电气工程与自动化学院2011年11月 26 日摘要本设计是基于AT89S52单片机的电子琴的电路设计方法而制作。该方法利用单片机定时器来产生固定频率的方波信号以推动喇叭发出旋律。并使用LED显示器来显示音阶输入的相关消息,然后通过按下键盘组中的相对按键使喇叭发出相对音阶单音,并自动存储所输入的单音,之后再一起自动演奏出来,从而实现具有存储功能的电子琴系统。本设计实现的功能是利用蜂鸣器作为发声部件,两个数码管作为显示部件,设置11个按键

2、,实现高音、中音、低音的1、2、3、4、5、6、7的发音,并存储一首歌的内容,可以实现自动播放。它具有7个音阶的键盘,分别为DO、RE、MI、FA、SO、LA、SI。每个音阶都对应着不同的频率,这样,我们就可以利用不同的频率组合构成我们想要的音乐。对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器T0来产生这样的方波频率信号,因此,我们只要把一首歌曲的音阶对应频率关系弄正确即可。用户可以根据乐谱在键盘上进行演奏,音乐发生器会根据用户的弹奏,通过扬声器将音乐播放出来。介绍了一种基于AT89S52单片机的电子琴的电路设计方法。该方法利用单片机定时器来产生固定频率的方波信号以推动喇

3、叭发出旋律。然后通过按下键盘组中的相对按键使喇叭发出相对音阶单音,并自动存储所输入的单音,之后再一起自动演奏出来,从而实现具有存储功能的电子琴系统。关键词:单片机、电子琴、音阶、频率目录摘要21、概述41.1电子琴概述41.2电子琴系统原理41.3设计任务及要求42、系统总体方案及硬件设计52.1 系统硬件组成52.11 AT89S52简介52.12 音乐播放部分82.13电子琴弹奏部分82.2 具体发音原理82.3 各部分电路图102.31 晶振102.32 复位电路102.33 按键112.34 发音113、软件设计123.1流程图123.2 主程序代码134、Proteus软件仿真135

4、、课程设计体会13参考文献14附录1 源程序代码15附录2 仿真图231 概述1.1 电子琴概述电子琴又称作电子键盘,属于电子乐器(区别于电声乐器),发音音量可以自由调节。音域较宽,和声丰富,甚至可以演奏出一个管弦乐队的效果,表现力极其丰富。它还可模仿多种音色,甚至可以奏出常规乐器所无法发出的声音(如合唱声,风雨声,宇宙声等)。另外,电子琴在独奏时,还可随意配上类似打击乐音响的节拍伴奏,适合于演奏节奏性较强的现代音乐。AT89S52是一种低功耗、高性能CMOS 8位微控制器,具有8K 在系统可编程Flash 存储器。使用Atmel 公司高密度非易失性存储器技术制造,与工业80C51 产品指令和

5、引脚完全兼容。片上Flash允许程序存储器在系统可编程,亦适于常规编程器。在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得AT89S52在众多嵌入式控制应用系统中得到广泛应用。本文利用AT89C51 单片机的强大功能,通过软件产生不同频率的声音信号,经相应的放大电路后,在扬声器中发出8个音节。可以弹奏出不同的曲子。1.2 电子琴系统原理由于一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器T0来产生这样方波频率信号,因此,我们只要把

6、一首歌曲的音阶对应频率关系弄正确即可。只要向若将不同的音节与一定的节拍组合在一起形成一定的曲调,因此只要一单片机I0口,通过软件,控制其输出不同频率的信号,就可以产生8个基本音节。将音节以一定的节拍进行组合,便可以产生歌曲。乐曲中每一音符对应着确定的频率。如果单片机*个口线输出“高低”电平的频率和*个音符的频率一样,则将此口线接上喇叭就可以发出此音。1.3 设计任务及要求本系统分为两个部分,一个是音乐播放,另一个就是电子琴弹奏。通过开 控制播放音乐或者进行电子琴弹奏。本系统利用蜂鸣器作为发声部件,当播放音乐时,弹奏按键无效;当进行弹奏时,设置10个按键,实现高音、中音、低音的1、2、3、4、5

7、、6、7的发音,两个数码管作为显示部件,显示输入的信息。2 系统总体方案及硬件设计2.1硬件组成2.11 AT89S52简介1.概述 AT89S52是一种低功耗、高性能CMOS 8位微控制器,具有8K 在系统可编程Flash 存储器。使用Atmel 公司高密度非易失性存储器技术制造,与工业80C51 产品指令和引脚完全兼容。片上Flash允许程序存储器在系统可编程,亦适于常规编程器。在单芯片上, 图2-2 AT89S52单片机 拥有灵巧的8 位CPU和在系统可编程Flash,使得AT89S52在众多嵌入式控制应用系统中得到广泛应用。2.主要性能与MCS-51单片机产品兼容; 8K字节在系统可编

8、程Flash存储器; 1000次擦写周期; 全静态操作:0Hz-33MHz; 三级加密程序存储器; 32个可编程I/O口线; 三个16位定时器/计数器; 六个中断源; 全双工UART串行通道; 低功耗空闲和掉电模式; 掉电后中断可唤醒; 看门狗定时器; 双数据指针; 掉电标识符 。3.管脚说明P0 口:P0口是一个8位漏极开路的双向I/O口。作为输出口,每位能驱动8个TTL逻 辑电平。对P0端口写“1”时,引脚用作高阻抗输入。 当访问外部程序和数据存储器时,P0口也被作为低8位地址/数据复用。在这种模式下, P0不具有内部上拉电阻。 在flash编程时,P0口也用来接收指令字节;在程序校验时,

9、输出指令字节。程序校验 时,需要外部上拉电阻。 P1 口:P1 口是一个具有内部上拉电阻的8 位双向I/O 口,p1 输出缓冲器能驱动4 个 TTL 逻辑电平。对P1 端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入 口使用。作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。 此外,P1.0和P1.1分别作定时器/计数器2的外部计数输入(P1.0/T2)和定时器/计数器2 的触发输入(P1.1/T2E*)。 在flash编程和校验时,P1口接收低8位地址字节。 引脚号第二功能: P1.0 T2(定时器/计数器T2的外部计数输入),时钟输出 P1.1 T2E*(定

10、时器/计数器T2的捕捉/重载触发信号和方向控制) P1.5 MOSI(在系统编程用) P1.6 MISO(在系统编程用) P1.7 SCK(在系统编程用) P2 口:P2 口是一个具有内部上拉电阻的8 位双向I/O 口,P2 输出缓冲器能驱动 。4 个 TTL 逻辑电平。对P2 端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入 口使用。作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。 在访问外部程序存储器或用16位地址读取外部数据存储器(例如执行MOV* DPTR) 时,P2 口送出高八位地址。在这种应用中,P2 口使用很强的内部上拉发送1。在使用 8位地址(

11、如MOV* RI)访问外部数据存储器时,P2口输出P2锁存器的内容。 在flash编程和校验时,P2口也接收高8位地址字节和一些控制信号。 P3 口:P3 口是一个具有内部上拉电阻的8 位双向I/O 口,p3 输出缓冲器能驱动4 个 TTL 逻辑电平。对P3 端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入 口使用。作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。 P3口亦作为AT89S52特殊功能(第二功能)使用,如下表所示。 在flash编程和校验时,P3口也接收一些控制信号。 端口引脚 第二功能: P3.0 R*D(串行输入口) P3.1 T*D(串行输

12、出口) P3.2 INTO(外中断0) P3.3 INT1(外中断1) P3.4 TO(定时/计数器0) P3.5 T1(定时/计数器1) P3.6 WR(外部数据存储器写选通) P3.7 RD(外部数据存储器读选通) 此外,P3口还接收一些用于FLASH闪存编程和程序校验的控制信号。 RST:复位输入。当振荡器工作时,RST引脚出现两个机器周期以上高电平将是单片机复位。 ALE/PROG:当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。一般情况下,ALE仍以时钟振荡频率的1/6输出固定的脉冲信号,因此它可对外输出时钟或用于定时目的。要注意的是:每当

13、访问外部数据存储器时将跳过一个ALE脉冲。对FLASH存储器编程期间,该引脚还用于输入编程脉冲(PROG)。如有必要,可通过对特殊功能寄存器(SFR)区中的8EH单元的D0位置位,可禁止ALE操作。该位置位后,只有一条MOV*和MOVC指令才能将ALE激活。此外,该引脚会被微弱拉高,单片机执行外部程序时,应设置ALE禁止位无效。 PSEN:程序储存允许(PSEN)输出是外部程序存储器的读选通信号,当AT89S52由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN有效,即输出两个脉冲,在此期间,当访问外部数据存储器,将跳过两次PSEN信号。 EA/VPP:外部访问允许,欲使CPU仅访问

14、外部程序存储器(地址为0000H-FFFFH),EA端必须保持低电平(接地)。需注意的是:如果加密位LB1被编程,复位时内部会锁存EA端状态。如EA端为高电平(接Vcc端),CPU则执行内部程序存储器的指令。FLASH存储器编程时,该引脚加上+12V的编程允许电源Vpp,当然这必须是该器件是使用12V编程电压Vpp。 *TAL1:振荡器反相放大器和内部时钟发生电路的输入端。 *TAL2:振荡器反相放大器的输出端。2.12 音乐播放部分乐音实际上是固定周期的信号。本系统是用AT89s52 的定时器控制,在P3.6脚上输出方波周期信号,产生音乐。乐曲中,每一音符对应着确定的频率,我们将每一音符的时

15、间常数和其相应的节拍常数作为一组,按顺序将乐曲中的所有常数排列成一个表,然后由查表程序依次取出,产生音符并控制节奏,就可以实现演奏效果。在输出中我们用蜂鸣器及其驱动电路实现发声。2.13电子琴弹奏部分本系统设置了10个按键,其中三个按键为高音、中音、低音的选择按键,其余为发音按键,按下不同的按键产生不同的音符,通过按键时间的长短控制发音的长短,这样弹奏人员可以随心所欲的弹奏自己所喜爱的乐曲。电子琴弹奏实际上就是把每个按键所对应的值经过处理后发给单片机,再在单片机内把数字当作指针指向所对应的音符。我们运用单片机的最小系统,用P2口的低三位作高音、中音、低音的选择按键的接口,用P1口的低七位作发音

16、按键的接口。 2.2 具体发音原理一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器T0来产生这样方波频率信号,因此,我们只要把各个音阶对应频率关系弄正确即可。若要产生音频脉冲,只要算出*一音频的周期(1/频率),再将此周期除以2,即为半周期的时间。利用定时器计时半周期时间,每当计时终止后就将蜂鸣器端口反相,然后重复计时再反相。就可在该引脚上得到此频率的脉冲实现发音。利用AT89S52的内部定时器使其工作计数器模式(MODE1)下,改变计数初值TH0

17、及TL0以产生不同频率的方法产生不同音阶,例如,频率为523Hz,其周期T1/5231912s,因此只要令计数器计时956s/1s956,每计数956次时将I/O反相,就可得到中音DO(523Hz)。计数脉冲值与频率的关系式是:Nfi2fr 式中,N是计数值;fi是机器频率(晶体振荡器为12MHz时,其频率为1MHz);fr是想要产生的频率。其计数初值T的求法如下:T65536N65536fi2fr例如:设K65536,fi1MHz,求低音DO(261Hz)、中音DO(523Hz)、高音DO(1046Hz)的计数值。T65536N65536fi2fr6553610000002fr6553650

18、0000/fr低音DO的T65536500000/26263628中音DO的T65536500000/52364580高音DO的T65536500000/104665058当播放音乐时,除了考虑音频外,还要考虑到音乐的音拍。本系统中,用软件延时来控制发音时间的长短,控制节拍。下表是各调1/4节拍的时间表。节拍表曲调值DELAY调4/4125ms调3/4187ms调2/4250ms2.3各部分电路2.31晶振2.32 复位电路2.33按键2.34 发音3 软件设计3.1流程图3.2 主程序代码见附录一 源程序代码4、Proteus软件仿真见附录2 仿真图5 课程设计体会通过此次课程设计,使我更加

19、扎实的掌握了有关单片机方面的知识,在设计过程中虽然遇到了一些问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了原因所在,也暴露出了前期我在这方面的知识欠缺和经验不足。实践出真知,通过亲自动手制作,使我们掌握的知识不再是纸上谈兵。过而能改,善莫大焉。在课程设计过程中,我们不断发现错误,不断改正,不断领悟,不断获取。最终的检测调试环节,本身就是在践行“过而能改,善莫大焉”的知行观。这次课程设计终于顺利完成了,在设计中遇到了很多问题,最后在老师的指导下,终于游逆而解。在今后社会的发展和学习实践过程中,一定要不懈努力,不能遇到问题就想到要退缩,一定要不厌其烦的发现问题所在,然后一一进行解决,只有

20、这样,才能成功的做成想做的事,才能在今后的道路上劈荆斩棘,而不是知难而退,那样永远不可能收获成功,收获喜悦,也永远不可能得到社会及他人对你的认可!课程设计诚然是一门专业课,给我很多专业知识以及专业技能上的提升,同时又是一门讲道课,一门辩思课,给了我许多道,给了我很多思,给了我莫大的空间。同时,设计让我感触很深。使我对抽象的理论有了具体的认识。通过这次课程设计,我掌握了PROTUES、WAVE6000等软件,用WAVE6000进行程序的编译,用PROTUES进行软硬件系统的仿真。回顾起此课程设计,至今我仍感慨颇多,从理论到实践,在这段日子里,可以说得是苦多于甜,但是可以学到很多很多的东西,同时不

21、仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,可以说得是困难重重,但可喜的是最终都得到了解决。参考文献1 余发山,王福忠单片机原理及应用技术:中国矿业大学出版社,2008年2 韩志军等.单片机应用系统设计.:机械工业出版社,2004.75-833 王守中51单片机开发入门与典型实例:人民邮电出版社,2007.139-1494 周润景等. Prote

22、us在MCS-51&ARM7系统中的应用百例.:电子工业出版社,2006.132-1395 王为青,邱文勋51单片机应用开发案例精选:人民邮电出版社,2007.61-65附录1 源程序代码*include *include *define SYSTEM_OSC 12000000/定义晶振频率12000000HZ*define SOUND_SPACE 4/5 /定义普通音符演奏的长度分率,/每4分音符间隔*define uchar unsigned char*define uint unsigned int*define P_key P1sbit beep=P36;/蜂鸣器控制端口P10!Uns

23、igned int code sy21=194,173,154,145,129,115,102,390,347,309,291,260,231,205,96, 86, 76, 72, 64, 56, 50;unsigned int code FreTab12= 262,277,294,311,330,349,369,392,415,440,466,494 ; /原始频率表unsigned char code SignTab7 = 0,2,4,5,7,9,11 ; /17在频率表中的位置unsigned char code LengthTab7= 1,2,4,8,16,32,64 ; unsig

24、ned char Sound_Temp_TH0,Sound_Temp_TL0;/音符定时器初值暂存 unsigned char Sound_Temp_TH1,Sound_Temp_TL1;/音长定时器初值暂存/曲谱存贮格式 unsigned char code MusicName音高,音长,音高,音长., 0,0;末尾:0,0 表示结束(Important)unsigned char code Music_Girl= 25,3,25,14,26,4,31,103,27,4,26,3,23,14,22,4,21,2,23,3,32,3,32,14,27,4,26,14,23,4,25,12,25

25、,2,25,3,25,14,26,4,31,103,27,4,26,3,25,14,26,4,23,2,16,3,26,3,26,14,25,4,25,14,23,4,22,12,22,2,23,3,23,14,22,4,25,3,25,4,23,4,22,3,23,14,22,4,21,103,22,4,23,103,25,4,27,14,26,4,25,3,26,12,26,2,31,3,31,14,26,4,31,103,31,4,26,13,25,14,23,4,22,2,16,3,26,3,25,14,23,4,23,14,22,4,21,102,31,14,32,4,33,4,33

26、,3,33,4,32,3,33,14,32,4,31,102,26,14,31,4,32,4,32,3,33,4,32,14,27,4,26,15,27,15,26,5,25,12,25,2,26,14,31,4,26,4,31,3,31,4,26,4,25,3,26,14,25,4,23,2,26,103,31,4,33,14,32,4,31,3,32,102,31,14,32,4,33,4,33,3,33,4,32,3,33,14,32,4,31,102,26,14,31,4,32,103,33,4,32,14,27,4,26,15,27,15,26,5,25,12,25,2,26,14,

27、31,4,31,4,26,4,31,3,31,4,26,4,25,3,26,14,25,4,23,2,26,13,33,3,32,14,31,14,26,3,31,12,31,2,26,13,33,3,32,14,31,14,26,3,31,102,31,14,32,4,26,13,33,3,32,14,31,14,36,3,31,12,31,2,0,0 ;void delay_us(uint i);/us级延时程序延时y(us) = 9.75*i + 17.44!void delay_ms(uint t);/毫秒级延时函数!void didi(uint k,uint t1,uint t2);

28、/蜂鸣器进行响t1静t2的k次动作!void keyscan(void);/按键扫描动作!void yindiao(uint i);/产生不同频率声音的函数!void music(uchar diao);/按键音优化!void InitialSound(void);/自动播放需要的定时器设置等!void Play(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed);void BeepTimer0(void);/音符发生中断/自动播放函数!void main()didi(2,100

29、,40);/两声提示!keyscan();void delay_us(uint i) while(i-);/us级延时程序延时y(us) = 9.75*i + 17.44!void delay_ms(uint t)/毫秒级延时函数!uint i,j;for(j=0;jt;j+)for(i=0;i110;i+);void didi(uint k,uint t1,uint t2)/蜂鸣器进行响t1静t2的k次动作!uint i;for(i=0;ik;i+)beep=0;delay_ms(t1);beep=1;delay_ms(t2);void keyscan(void)/按键扫描动作!uchar

30、tiaozheng=0;while(1)if(P2&0*01)=0*00)InitialSound();didi(2,80,40);InitialSound(); Play(Music_Girl,0,3,200);/Play(乐曲名,调号,升降八度,演奏速度);else if(P_key&0*ff)!=0*ff)/此处内部括号不能少,否则不能进入下面。if(P2&0*04)=0)/0100 0000当前H也按下了!tiaozheng=14;/进入高音区!if(P_key=0*fd)music(tiaozheng+0); /1111 1101if(P_key=0*fb)music(tiaozhe

31、ng+1); /1111 1011if(P_key=0*f7)music(tiaozheng+2);if(P_key=0*ef)music(tiaozheng+3);if(P_key=0*df)music(tiaozheng+4);if(P_key=0*bf)music(tiaozheng+5);if(P_key=0*7f)music(tiaozheng+6);else if(P2&0*02)=0)/1000 0000当前L也按下了!tiaozheng=7;/进入低音区!if(P_key=0*fd)music(tiaozheng+0);if(P_key=0*fb)music(tiaozheng

32、+1);if(P_key=0*f7)music(tiaozheng+2);if(P_key=0*ef)music(tiaozheng+3);if(P_key=0*df)music(tiaozheng+4);if(P_key=0*bf)music(tiaozheng+5);if(P_key=0*7f)music(tiaozheng+6); else/是默认的中音!tiaozheng=0;if(P_key=0*fd)music(tiaozheng+0);if(P_key=0*fb)music(tiaozheng+1);if(P_key=0*f7)music(tiaozheng+2);if(P_ke

33、y=0*ef)music(tiaozheng+3);if(P_key=0*df)music(tiaozheng+4);if(P_key=0*bf)music(tiaozheng+5);if(P_key=0*7f)music(tiaozheng+6);void yindiao(uint i)/产生不同频率声音的函数beep=0;delay_us(i);beep=1;delay_us(i);void music(uchar diao)/按键音优化!uint i=0,jizhun=20;switch(diao) case 0:for(i=0;i(jizhun+(5*diao);i+)yindiao(

34、sydiao);break; case 1:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);break; case 2:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);break; case 3:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);break; case 4:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);break; case 5:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydia

35、o);break; case 6:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);break; case 7:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);break; case 8:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);break; case 9:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);break; case 10:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);b

36、reak; case 11:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);break; case 12:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);break; case 13:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);break; case 14:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);break; case 15:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);b

37、reak; case 16:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);break; case 17:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);break; case 18:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);break; case 19:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);break; case 20:for(i=0;i(jizhun+(5*diao);i+)yindiao(sydiao);b

38、reak;default:break;void InitialSound(void)/自动播放需要的定时器设置等!beep = 1;Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256;/ 计算TL1应装入的初值 (10ms的初装值)Sound_Temp_TL1 = (65535-(1/1200)*SYSTEM_OSC)%256;/ 计算TH1应装入的初值 TH1 = Sound_Temp_TH1;TL1 = Sound_Temp_TL1;TMOD |= 0*11;/定时器0和定时器1都是方式1 16位计数。ET0 = 1;ET1 = 0;TR0 =

39、 0;TR1 = 0;IT0=0;E*0=1;EA = 1;/曲谱存贮格式 unsigned char code MusicName音高,音长,音高,音长., 0,0;末尾:0,0 表示结束(Important)void Play(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed)unsigned int NewFreTab12;/新的频率表unsigned char i,j;unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,Curr

40、entFre,Temp_T,SoundLength;unsigned char Tone,Length,SL,SH,SM,SLen,*G,FD;for(i=0;i 11)/进入高音音域!j = j-12;NewFreTabi = FreTabj*2;elseNewFreTabi = FreTabj;if(Octachord = 1)/需要降八度!NewFreTabi=2;else if(Octachord = 3)/需要升八度!NewFreTabi=2; /否则不用改!SoundLength = 0;while(SoundSoundLength != 0*00)/计算歌曲长度SoundLeng

41、th+=2;Point = 0;Tone = SoundPoint; /读出音调!Length = SoundPoint+1; / 读出第一个音符和它时时值!LDiv0 = 12000/Speed;/ 算出1分音符的长度(几个10ms) LDiv4 = LDiv0/4; / 算出4分音符的长度 LDiv4 = LDiv4-LDiv4*SOUND_SPACE; / 普通音最长间隔标准 TR0 = 0;TR1 = 1;while(Point = 2; /低音 if (SM=3) CurrentFre = 2; /高音Temp_T = 65536-(50000/CurrentFre)*10/(120

42、00000/SYSTEM_OSC);/计算计数器初值Sound_Temp_TH0 = Temp_T/256; Sound_Temp_TL0 = Temp_T%256; TH0 = Sound_Temp_TH0; TL0 = Sound_Temp_TL0 + 12; /加12是对中断延时的补偿 SLen=LengthTabLength%10; /算出是几分音符*G=Length/10%10; /算出音符类型(0普通1连音2顿音) FD=Length/100;LDiv=LDiv0/SLen; /算出连音音符演奏的长度(多少个10ms)if (FD=1) /有浮点,加半个时值!LDiv=LDiv+L

43、Div/2;if(*G!=1)if(*G=0) /算出普通音符的演奏长度 if (SLen0;i-) /发规定长度的音 while(TF1=0);TH1 = Sound_Temp_TH1;TL1 = Sound_Temp_TL1;TF1=0;if(LDiv2!=0) TR0=0; beep=1;for(i=LDiv2;i0;i-) /音符间的间隔 while(TF1=0);TH1 = Sound_Temp_TH1;TL1 = Sound_Temp_TL1;TF1=0;if(P1&0*ff)!=0*ff)break;Point+=2; Tone=SoundPoint;Length=SoundPoint+1;beep = 1;void BeepTimer0(void) interrupt 1/音符发生中断beep = !beep;TH0 = Sound_Temp_TH0; TL0 = Sound_Temp_TL0;附录2 仿真图. z.

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!