单片机电子琴制作16按键.doc
Four short words sum up what has lifted most successful individuals above the crowd: a little bit more.-author-date单片机电子琴制作16按键目录 单片机原理 课程设计说 明 书专业名称: 电气工程及其自动化 班 级: 11-2 学 号: 姓 名: 指导教师: 日期: 2013.6.21 -单片机原理课程设计评阅书题目电子琴 学生姓名学号20110202052指导教师评语及成绩指导教师签名: 年 月 日答辩评语及成绩答辩教师签名: 年 月 日教研室意见总成绩: 室主任签名: 年 月 日摘 要本文设计了一种基于STC12C5A32S2单片机的电子琴电路。该方案利用单片机定时器产生固定频率的方波信号以驱动蜂鸣器发出一定的旋律,通过矩阵键盘中的相应的按键来输入使蜂鸣器发出相对音阶的单音。同时设计还有自动存储所输入的单音,之后再一起自动演奏出来的功能。本设计通过控制单片机定时器的定时时间产生不同频率的音频脉冲,经三极管放大信号后驱动蜂鸣器发出不同音节的声音。要实现7个音符的各自的高、中、低音,需要建立三个表,分别存储高音、中音和低音的频率值;默认为中音输出,当二个按键开关中某一个按下,通过软件选择相应的音频。按下弹奏键就可弹奏出不同的声音。另外用软件延时来控制发音时间的长短,来控制节拍。通过把乐谱中的音符和相应的节拍变换为定时常数和延时常数,作为数据表格存放在存储器中。由程序查表得到定时常数和延时常数,分别用来控制定时器产生的脉冲频率和发出该音频脉冲的持续时间,这样就可以实现乐曲的演奏。本设计为实物电路板设计开发,报告中详细的阐述了电子琴设计的方法和过程。并经过软硬件的调试,该音乐发生器不但能通过键盘弹奏出很好的音调,而且还可以通过键盘选择播放不同的音乐。本系统运行稳定,其优点是硬件电路简单,软件功能完善,控制系统可靠,性价比较高等,具有一定的实用和参考价值。关键词:STC12C5A32S2 单片机 定时器 电子琴目 录摘要I第一章 引言1第二章 电子琴电路硬件电路设计32.1单片机的介绍与组成52.2单片机主控电路52.3 4×4矩阵键盘电路42.4 蜂鸣器电路4第三章 电子琴电路软件设计73.1 程序设计流程图83.2音乐播放部分43.3电子琴弹奏部分43.4发音原理4第四章 程序17心得体会17参考文献18附件19第一章 引言随着计算机在社会各领域的渗透,单片机的应用正在不断地走向深入,同时带动着工业、农业、商业、家电以及玩具的日新月异更新,极大地提高了电子电路及系统设计质量和效率。单片机是指一个集成在一块芯片上的完整计算机系统。尽管他的大部分功能集成在一块小芯片上,但是它具有一个完整计算机所需要的大部分部件:CPU、内存、内部和外部总线系统,目前大部分还会具有外存。同时集成诸如通讯接口、定时器,实时时钟等外围设备。而现在最强大的单片机系统甚至可以将声音、图像、网络、复杂的输入输出系统集成在一块芯片上。单片机也被称为微控制器(Microcontroler),是因为它最早被用在工业控制领域。单片机由芯片内仅有CPU的专用处理器发展而来。最早的设计理念是通过将大量外围设备和CPU集成在一个芯片中,使计算机系统更小,更容易集成进复杂的而对提及要求严格的控制设备当中。STC单片机是一款增强型51单片机,完全兼容MCS-51。STC12C5A32S2可以代替AT89C51,而且功能更强,速度更快,寿命更长,价格更低。该单片机具有40个引脚,采用双列直插式封装。可以完成ISP在线编程功能。本设计是以主控芯片STC12C5A32S2为中心器件,辅以小键盘、发光二极管、和蜂鸣器电路来设计电子琴系统,同时详细论述了该系统的设计过程及关键技术。 第二章电子琴硬件电路设计2.1 51单片机的介绍与组成51单片机是对所有兼容Intel 8031指令系统的单片机的统称。该系列单片机的始祖是Intel的8031单片机,后来随着Flash rom技术的发展,8031单片机取得了长足的进展,成为应用最广泛的8位单片机之一,其代表型号是ATMEL公司的AT89系列,它广泛应用于工业测控系统之中。很多公司都有51系列的兼容机型推出,今后很长的一段时间内将占有大量市场。51单片机是基础入门的一个单片机,还是应用最广泛的一种。需要注意的是52系列的单片机一般不具备自编程能力。组成: 8位CPU·4kbytes程序存储器(ROM) (52为8K)·128bytes的数据存储器(RAM) (52有256bytes的RAM)·32条I/O口线·111条指令,大部分为单字节指令·21个专用寄存器·2个可编程定时/计数器·5个中断源,2个优先级(52有6个)·一个全双工串行通信口·外部数据存储器寻址空间为64kB·外部程序存储器寻址空间为64kB·逻辑操作位寻址功能·双列直插40PinDIP封装·单一+5V电源供电CPU:由运算和控制逻辑组成,同时还包括中断系统和部分外部特殊功能寄存器;RAM:用以存放可以读写的数据,如运算的中间结果、最终结果以及欲显示的数据;ROM:用以存放程序、一些原始数据和表格;I/O口:四个8位并行I/O口,既可用作输入,也可用作输出;T/C:两个定时/记数器,既可以工作在定时模式,也可以工作在记数模式;五个中断源的中断控制系统;一个全双工UART(通用异步接收发送器)的串行I/O口,用于实现单片机之间或单片机与微机之间的串行通信;片内振荡器和时钟产生电路,石英晶体和微调电容需要外接。最高振荡频率为12M2.2 单片机主控电路 图5 单片机主控电路图6 单片机复位电路该电路采用的是STC12C系列的单片机,此系列单片机是宏晶科技生产的单时钟/机器周期单片机,是高速/低功耗/超强抗干扰的新一代8051单片机,指令代码完全兼容传统8051,但速度快8-12倍。资源丰富。复位电路采用的是按键手动复位。时钟电路采用的是12M晶振,用内部振荡器。2.3 4×4矩阵键盘电路图3 矩阵键盘电路矩阵键盘共有16个按键,其中s1-s7分别是中音的do-ti控制键,s8-s14分别是高音的do-ti的控制键,而s15和s16则是音乐的播放和控制键。占用单片机的P1口。2.3 蜂鸣器电路图4 蜂鸣器电路蜂鸣器电路主要是系统的发音电路。用PNP三极管8550来驱动蜂鸣器发声。第三章电子琴电路软件设计 3.1程序流程图开始行列式键盘按键按下成功否?识别按键功能根据按键功能,装入音符T值到T0中启动T0工作行列式键盘按键释放成功否?停止T0工作T0初始化并开中断允放T0中断T0中断入口重装TH0,TL0初值P1.0取反中断返回3.2 音乐播放部分音乐实际上是固定周期的信号。本系统是用AT89S52 的定时器控制,在P3.6脚上输出方波周期信号,产生音乐。乐曲中,每一音符对应着确定的频率,我们将每一音符的时间常数和其相应的节拍常数作为一组,按顺序将乐曲中的所有常数排列成一个表,然后由查表程序依次取出,产生音符并控制节奏,就可以实现演奏效果。在输出中我们用蜂鸣器及其驱动电路实现发声。3.3电子琴弹奏部分本系统设置了16个按键,其中三个按键为高音、中音、低音的选择按键,其余为发音按键,按下不同的按键产生不同的音符,通过按键时间的长短控制发音的长短,这样弹奏人员可以随心所欲的弹奏自己所喜爱的乐曲。电子琴弹奏实际上就是把每个按键所对应的值经过处理后发给单片机,再在单片机内把数字当作指针指向所对应的音符。我们运用单片机的最小系统,用P2口的低三位作高音、中音、低音的选择按键的接口,用P1口的低七位作发音按键的接口。 3.4 具体发音原理一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器T0来产生这样方波频率信号,因此,我们只要把各个音阶对应频率关系弄正确即可。若要产生音频脉冲,只要算出某一音频的周期(1/频率),再将此周期除以2,即为半周期的时间。利用定时器计时半周期时间,每当计时终止后就将蜂鸣器端口反相,然后重复计时再反相。就可在该引脚上得到此频率的脉冲实现发音。利用AT89S52的内部定时器使其工作计数器模式(MODE1)下,改变计数初值TH0及TL0以产生不同频率的方法产生不同音阶,例如,频率为523Hz,其周期T1/5231912s,因此只要令计数器计时956s/1s956,每计数956次时将I/O反相,就可得到中音DO(523Hz)。计数脉冲值与频率的关系式是:Nfi÷2÷fr 式中,N是计数值;fi是机器频率(晶体振荡器为12MHz时,其频率为1MHz);fr是想要产生的频率。其计数初值T的求法如下:T65536N65536fi÷2÷fr例如:设K65536,fi1MHz,求低音DO(261Hz)、中音DO(523Hz)、高音DO(1046Hz)的计数值。T65536N65536fi÷2÷fr655361000000÷2÷fr65536500000/fr低音DO的T6553650000/26263628中音DO的T6553650000/52364580高音DO的T6553650000/104665058因此,可以通过计算求得各音阶的简谱码T值如下:1 Do的T6553650000/262.1636282 Re的T6553650000/293.7638363 Mi的T6553650000/329.6640214 Fa的T6553650000/349.2641045 So的T6553650000/392.0642616 La的T6553650000/440.0644007 Si的T6553650000/493.964524相应求得在要发出不同音符时先给定时器T0装入的初值如下表:音阶1 Do2 Re3 Mi4 Fa5 So6 La7 Si频率(HZ)261.1293.7329.6349.2392.0440.0493.9 初值 63628638366402164104642616440064524 第四章 程序#include <REG52.H>#define SYSTEM_OSC 24000000/定义晶振频率12000000HZ#define SOUND_SPACE 4/5 /定义普通音符演奏的长度分率,/每4分音符间隔sbit BeepIO=P37;/定义输出管脚#define uchar unsigned char uchar code a4=0xfe,0xfc,0xfb,0xf7;#define uint unsigned int uchar code b4=0xef,0xdf,0xbf,0x7f;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 ;unsigned char Sound_Temp_TH0,Sound_Temp_TL0;/音符定时器初值暂存 unsigned char Sound_Temp_TH1,Sound_Temp_TL1;/音长定时器初值暂存void InitialSound(void)BeepIO = 0;Sound_Temp_TH1 = (65535-(1/2400)*SYSTEM_OSC)/256;/ 计算TL1应装入的初值 (10ms的初装值)Sound_Temp_TL1 = (65535-(1/2400)*SYSTEM_OSC)%256;/ 计算TH1应装入的初值 TH1 = Sound_Temp_TH1;TL1 = Sound_Temp_TL1;TMOD |= 0x11;ET0 = 1;ET1 = 0;TR0 = 0;TR1 = 0;EA = 1;char num;void BeepTimer0(void) interrupt 1/音符发生中断BeepIO = !BeepIO;TH0 = Sound_Temp_TH0; TL0 = Sound_Temp_TL0;void delay(uint z) uint x,y; for(x=z;x>0;x-) for(y=110;y>0;y-);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,CurrentFre,Temp_T,SoundLength;unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD;for(i=0;i<12;i+) / 根据调号及升降八度来生成新的频率表 j = i + Signature;if(j > 11)j = j-12;NewFreTabi = FreTabj*2;elseNewFreTabi = FreTabj;if(Octachord = 1)NewFreTabi>>=2;else if(Octachord = 3)NewFreTabi<<=2;SoundLength = 0;while(SoundSoundLength != 0x00)/计算歌曲长度SoundLength+=2;Point = 0;Tone = SoundPoint;Length = SoundPoint+1; / 读出第一个音符和它时时值LDiv0 = 24000/Speed;/ 算出1分音符的长度(几个10ms) LDiv4 = LDiv0/4; / 算出4分音符的长度 LDiv4 = LDiv4-LDiv4*SOUND_SPACE; / 普通音最长间隔标准 TR0 = 0;TR1 = 1;while(Point < SoundLength)SL=Tone%10; /计算出音符 SM=Tone/10%10; /计算出高低音 SH=Tone/100; /计算出是否升半 CurrentFre = NewFreTabSignTabSL-1+SH; /查出对应音符的频率 if(SL!=0)if (SM=1) CurrentFre >>= 2; /低音 if (SM=3) CurrentFre <<= 2; /高音Temp_T = 65536-(50000/CurrentFre)*10/(24000000/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; /算出是几分音符XG=Length/10%10; /算出音符类型(0普通1连音2顿音) FD=Length/100;LDiv=LDiv0/SLen; /算出连音音符演奏的长度(多少个10ms)if (FD=1) LDiv=LDiv+LDiv/2;if(XG!=1)if(XG=0) /算出普通音符的演奏长度 if (SLen<=4)LDiv1=LDiv-LDiv4;elseLDiv1=LDiv*SOUND_SPACE; else LDiv1=LDiv/2; /算出顿音的演奏长度 else LDiv1=LDiv;if(SL=0) LDiv1=0;LDiv2=LDiv-LDiv1; /算出不发音的长度 if (SL!=0)TR0=1;for(i=LDiv1;i>0;i-) /发规定长度的音 while(TF1=0);TH1 = Sound_Temp_TH1;TL1 = Sound_Temp_TL1;TF1=0;if(LDiv2!=0)TR0=0; BeepIO=0;for(i=LDiv2;i>0;i-) /音符间的间隔while(TF1=0);TH1 = Sound_Temp_TH1;TL1 = Sound_Temp_TL1;TF1=0;Point+=2; Tone=SoundPoint;Length=SoundPoint+1;BeepIO = 0;void Delay1ms(unsigned int count) unsigned int i,j;for(i=0;i<count;i+)for(j=0;j<240;j+); void scan() uchar i,j,c,temp;i=j=0; while(i<4) P2=ai;temp=P2;if(temp!=ai)delay(10);temp=P2; if(temp!=ai) while(j<4) c=bj&ai; if(P2=c) num=4*i+j+1; j+; i+; unsigned char code Music_Girl=0x17,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03, 0x17,0x03, 0x16,0x03, 0x17,0x02, 0x16,0x03, 0x15,0x03, 0x10,0x03, 0x15,0x03, 0x17,0x03, 0x16,0x66, 0x16,0x03, 0x15,0x03, 0x10,0x03, 0x15,0x03, 0x16,0x03, 0x17,0x03, 0x19,0x0D, 0x16,0x03, 0x17,0x03, 0x1A,0x03, 0x19,0x03, 0x10,0x03,0x16,0x03, 0x15,0x66, 0x16,0x03, 0x15,0x03, 0x10,0x03, 0x15,0x03, 0x17,0x03, 0x1A,0x03, 0x19,0x0D, 0x17,0x03, 0x17,0x03, 0x1A,0x03, 0x19,0x03, 0x1A,0x03, 0x19,0x0D, 0x17,0x66, 0x16,0x03, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x19,0x03, 0x1A,0x03, 0x19,0x0D, 0x17,0x03, 0x10,0x03, 0x17,0x03, 0x17,0x17, 0x16,0x17, 0x17,0x02, 0x17,0x02, 0x19,0x02, 0x1F,0x03, 0x19,0x03, 0x1A,0x16, 0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x17,0x03, 0x19,0x03, 0x19,0x02, 0x19,0x02, 0x17,0x03, 0x19,0x03, 0x1A,0x03, 0x1F,0x03, 0x20,0x03, 0x1F,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03, 0x19,0x0D, 0x19,0x66, 0x17,0x0D, 0x17,0x7A, 0x17,0x03, 0x19,0x03, 0x1F,0x03, 0x19,0x03, 0x1A,0x15, 0x1F,0x03, 0x20,0x03, 0x1F,0x03, 0x19,0x04, 0x17,0x04, 0x19,0x04, 0x1F,0x03, 0x1A,0x15, 0x17,0x04, 0x16,0x04, 0x17,0x04, 0x19,0x04, 0x21,0x04, 0x20,0x0C, 0x20,0x02, 0x1F,0x03, 0x1F,0x0D, 0x1F,0x15, 0x17,0x04, 0x16,0x04, 0x17,0x04, 0x19,0x03, 0x21,0x03, 0x20,0x02, 0x20,0x02, 0x1F,0x02, 0x1F,0x02, 0x1F,0x16, 0x17,0x04, 0x16,0x04, 0x17,0x04, 0x19,0x03, 0x21,0x03, 0x20,0x03, 0x20,0x01, 0x20,0x01,; unsigned char code Music_a1= 0x15,0x02, 0x00,0x00 ; unsigned char code Music_a2= 0x16,0x02, 0x00,0x00 ; unsigned char code Music_a3= 0x17,0x02, 0x00,0x00 ; unsigned char code Music_a4= 0x18,0x02, 0x00,0x00 ; unsigned char code Music_a5= 0x19,0x02, 0x00,0x00 ; unsigned char code Music_a6= 0x1A,0x02, 0x00,0x00 ; unsigned char code Music_a7= 0x1B,0x02, 0x00,0x00 ; unsigned char code Music_b1= 0x0b,0x02, 0x00,0x00 ; unsigned char code Music_b2= 0x0c,0x02, 0x00,0x00 ; unsigned char code Music_b3= 0x0d,0x02, 0x00,0x00 ; unsigned char code Music_b4= 0x0e,0x02, 0x00,0x00 ; unsigned char code Music_b5= 0x0f,0x02, 0x00,0x00 ; unsigned char code Music_b6= 0x10,0x02, 0x00,0x00 ; unsigned char code Music_b7= 0x11,0x02, 0x00,0x00 ; main() uchar k=1;InitialSound();while(1) scan();if(!k)Play(Music_Girl,0,3,360);if(k)if(num=1)Play(Music_a1,0,3,360);if(num=2)Play(Music_a2,0,3,360);if(num=3)Play(Music_a3,0,3,360);if(num=4)Play(Music_a4,0,3,360);if(num=5)Play(Music_a5,0,3,360);if(num=6)Play(Music_a6,0,3,360);if(num=7)Play(Music_a7,0,3,360);if(num=9)Play(Music_b1,0,3,360);if(num=10)Play(Music_b2,0,3,360);if(num=11)Play(Music_b3,0,3,360);if(num=12)Play(Music_b4,0,3,360);if(num=13)Play(Music_b5,0,3,360);if(num=14)Play(Music_b6,0,3,360);if(num=15)Play(Music_b7,0,3,360);if(num=16)if(k=1)k=0;else k=1; num=0; 心得体会经过一个星期的课程设计,过程曲折可谓一语难尽,感想颇多。在此期间我们也失落过,也曾一度热情高涨。从开始时满富盛激情到最后汗水背后的复杂心情,点点滴滴无不令我回味无长。设计确实有些辛苦,但苦中也有乐,在如今单一的理论学习中,很少有机会能有实践的机会,但我们可以,而且设计也是一个团队的任务,一起的工作可以让我们有说有笑,相互帮助,配合默契,多少人间欢乐在这里洒下,经过这几天的合作,我感觉我和同学们之间的距离更加近了;我想说,确实很累,但当我们看到自己所做的成果时,心中也不免产生兴奋。同时我认为我们的工作是一个团队的工作,团队需要个人,个人也离不开团队,必须发扬团结协作的精神。团结协作是我们实习成功的一项非常重要的保证。而这次实习也正好锻炼我们这一点,这也是非常宝贵的。对我们而言,知识上的收获重要,精神上的丰收更加可喜。挫折是一份财富,经历是一份拥有。这次实习必将成为我人生旅途上一个非常美好的回忆!通过这次课程设计,加强了我们动手、思考和解决问题的能力。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。这次课程设计终于顺利完成了,在设计中遇到了很多专业知识问题,最后在老师的辛勤指导下,终于迎刃而解,我们学也到很多实用的知识,学到了很多课内学不到的东西,比如独立思考解决问题,出现差错的随机应变,和与人合作共同提高,都受益非浅。在此,感谢老师的细心指导!参考文献1 万福君,单片机微机原理系统设计与应用M.中国科学技术大学出20042 陈明荧,8051单片机课程设计实训教材M.清华大学出版社,20043 何立民,单片机应用技术选编M,北京航空航天大学出版社,20044 涂时亮,单片机软件设计技术,重庆科技文献出版社,19875. 做而论道.基于51单片机的4*4矩阵键盘电子琴.