当前位置:文档之家› 单片机电子琴制作16按键

单片机电子琴制作16按键

《单片机原理》课程设计说明书专业名称:电气工程及其自动化班级:11-2学号:姓名:指导教师:日期:2013.6.21《单片机原理课程设计》评阅书摘要本文设计了一种基于STC12C5A32S2单片机的电子琴电路。

该方案利用单片机定时器产生固定频率的方波信号以驱动蜂鸣器发出一定的旋律,通过矩阵键盘中的相应的按键来输入使蜂鸣器发出相对音阶的单音。

同时设计还有自动存储所输入的单音,之后再一起自动演奏出来的功能。

本设计通过控制单片机定时器的定时时间产生不同频率的音频脉冲,经三极管放大信号后驱动蜂鸣器发出不同音节的声音。

要实现7个音符的各自的高、中、低音,需要建立三个表,分别存储高音、中音和低音的频率值;默认为中音输出,当二个按键开关中某一个按下,通过软件选择相应的音频。

按下弹奏键就可弹奏出不同的声音。

另外用软件延时来控制发音时间的长短,来控制节拍。

通过把乐谱中的音符和相应的节拍变换为定时常数和延时常数,作为数据表格存放在存储器中。

由程序查表得到定时常数和延时常数,分别用来控制定时器产生的脉冲频率和发出该音频脉冲的持续时间,这样就可以实现乐曲的演奏。

本设计为实物电路板设计开发,报告中详细的阐述了电子琴设计的方法和过程。

并经过软硬件的调试,该音乐发生器不但能通过键盘弹奏出很好的音调,而且还可以通过键盘选择播放不同的音乐。

本系统运行稳定,其优点是硬件电路简单,软件功能完善,控制系统可靠,性价比较高等,具有一定的实用和参考价值。

关键词:STC12C5A32S2 单片机定时器电子琴目录摘要 ....................................... 错误!未定义书签。

第一章引言 . (2)第二章电子琴电路硬件电路设计 .............. 错误!未定义书签。

2.1单片机的介绍与组成 (4)2.2单片机主控电路 (4)2.3 4×4矩阵键盘电路 (5)2.4 蜂鸣器电路 (5)第三章电子琴电路软件设计 .................. 错误!未定义书签。

3.1 程序设计流程图...................... 错误!未定义书签。

3.2音乐播放部分 (5)3.3电子琴弹奏部分 (5)3.4发音原理 (5)第四章程序 ................................ 错误!未定义书签。

心得体会 ................................... 错误!未定义书签。

参考文献 (11)附件错误!未定义书签。

第一章引言随着计算机在社会各领域的渗透,单片机的应用正在不断地走向深入,同时带动着工业、农业、商业、家电以及玩具的日新月异更新,极大地提高了电子电路及系统设计质量和效率。

单片机是指一个集成在一块芯片上的完整计算机系统。

尽管他的大部分功能集成在一块小芯片上,但是它具有一个完整计算机所需要的大部分部件: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口,用于实现单片机之间或单片机与微机之间的串行通信;片内振荡器和时钟产生电路,石英晶体和微调电容需要外接。

最高振荡频率为12M《单片机原理课程设计》说明书2.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程序流程图3.2 音乐播放部分音乐实际上是固定周期的信号。

本系统是用AT89S52 的定时器控制,在P3.6脚上输出方波周期信号,产生音乐。

乐曲中,每一音符对应着确定的频率,我们将每一音符的时间常数和其相应的节拍常数作为一组,按顺序将乐曲中的所有常数排列成一个表,然后由查表程序依次取出,产生音符并控制节奏,就可以实现演奏效果。

在输出中我们用蜂鸣器及其驱动电路实现发声。

3.3电子琴弹奏部分本系统设置了16个按键,其中三个按键为高音、中音、低音的选择按键,其余为发音按键,按下不同的按键产生不同的音符,通过按键时间的长短控制发音的长短,这样弹奏人员可以随心所欲的弹奏自己所喜爱的乐曲。

电子琴弹奏实际上就是把每个按键所对应的值经过处理后发给单片机,再在单片机内把数字当作指针指向所对应的音符。

我们运用单片机的最小系统,用P2口的低三位作高音、中音、低音的选择按键的接口,用P1口的低七位作发音按键的接口。

3.4 具体发音原理一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器T0来产生这样方波频率信号,因此,我们只要把各个音阶对应频率关系弄正确即可。

若要产生音频脉冲,只要算出某一音频的周期(1/频率),再将此周期除以2,即为半周期的时间。

利用定时器计时半周期时间,每当计时终止后就将蜂鸣器端口反相,然后重复计时再反相。

就可在该引脚上得到此频率的脉冲实现发音。

利用AT89S52的内部定时器使其工作计数器模式(MODE1)下,改变计数初值TH0及TL0以产生不同频率的方法产生不同音阶,例如,频率为523Hz,其周期T=1/523=1912μs,因此只要令计数器计时956μs/1μs=956,每计数956次时将I/O反相,就可得到中音DO(523Hz)。

计数脉冲值与频率的关系式是:N=fi÷2÷fr式中,N是计数值;fi是机器频率(晶体振荡器为12MHz时,其频率为1MHz);fr 是想要产生的频率。

其计数初值T的求法如下:T=65536-N=65536-fi÷2÷fr例如:设K=65536,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-50000/262=63628中音DO的T=65536-50000/523=64580高音DO的T=65536-50000/1046=65058因此,可以通过计算求得各音阶的简谱码T值如下:1 Do的T=65536-50000/262.1=636282 Re的T=65536-50000/293.7=638363 Mi的T=65536-50000/329.6=640214 Fa的T=65536-50000/349.2=641045 So的T=65536-50000/392.0=642616 La的T=65536-50000/440.0=644007 Si的T=65536-50000/493.9=64524相应求得在要发出不同音符时先给定时器T0装入的初值如下表:第四章程序#include <REG52.H>#define SYSTEM_OSC 24000000 //定义晶振频率12000000HZ#define SOUND_SPACE 4/5 //定义普通音符演奏的长度分率,//每4分音符间隔sbit BeepIO= P3^7; //定义输出管脚#define uchar unsigned charuchar code a[4]={0xfe,0xfc,0xfb,0xf7};#define uint unsigned intuchar code b[4]={0xef,0xdf,0xbf,0x7f};unsigned int code FreTab[12] = { 262,277,294,311,330,349,369,392,415,440, 466,494 }; //原始频率表unsigned char code SignTab[7] = { 0,2,4,5,7,9,11 }; //1~7在频率表中的位置unsigned char code LengthTab[7]= { 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,u nsigned int Speed){unsigned int NewFreTab[12]; //新的频率表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;NewFreTab[i] = FreTab[j]*2;}elseNewFreTab[i] = FreTab[j];if(Octachord == 1)NewFreTab[i]>>=2;else if(Octachord == 3)NewFreTab[i]<<=2;}SoundLength = 0;while(Sound[SoundLength] != 0x00) //计算歌曲长度{SoundLength+=2;}Point = 0;Tone = Sound[Point];Length = Sound[Point+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; //计算出是否升半C urrentFre = NewFreTab[SignTab[SL-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=LengthTab[Length%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;elseLDiv1=LDiv/2; //算出顿音的演奏长度 elseLDiv1=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=Sound[Point];Length=Sound[Point+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=a[i];temp=P2;if(temp!=a[i]){delay(10);temp=P2;if(temp!=a[i]){while(j<4){c=b[j]&a[i];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;}}心得体会经过一个星期的课程设计,过程曲折可谓一语难尽,感想颇多。

相关主题