基于51单片机的电子琴设计.docx
《基于51单片机的电子琴设计.docx》由会员分享,可在线阅读,更多相关《基于51单片机的电子琴设计.docx(21页珍藏版)》请在冰豆网上搜索。
基于51单片机的电子琴设计
摘要
本设计是基于AT89S52单片机的简易电子琴设计。
主要组成是以51单片机最小系统为核心,通过键盘获取按键信息,通过运用单片机定时器等部件实现蜂鸣器发声同时用数码管同步显示。
本系统具有播放歌曲及选取按键输入高、中、低音的功能。
本设计的特点是:
大部分功能通过软件实现,使电路简单明了,系统稳定性好。
电子琴是电子科技与音乐结合的产物是一种新型的键盘乐器。
一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器T0来产生这样方波频率信号,因此,我们只要把一首歌曲的音阶对应频率关系弄正确即可。
关键字:
AT89S52,按键,数码管,蜂鸣器,音阶。
(要求宋体、小四号,行间距为固定值22磅。
字数500字以上。
介绍你所作设计的主要内容及主要方法和取得的结果,是整个报告的概括性内容,不要超过一页面)
目录(小三号居中,加粗)
1概述………………………………………………………………………………
1.151系列单片机简介
89系列单片机是ATMEL公司的8位FLASH单片机系列。
89系列单片机是以8031为核心构成的,它和8051系列单片机外部端子是一样的、兼容的,其最大特点是片内含有FLASH存储器。
AT89S52单片机是一种低功耗、高性能、内含4KB的闪速存储器(FlashMemory)的8位微控制器。
片内闪速存储器的程序代码或数据可在线写入,也可通过常规的编程器编程。
(宋体、小四,行间距固定值18磅。
以下相同要求)……………………
1.2电子琴简介
电子琴为键盘乐器,采用半导体集成电路,对乐音信号进行放大,通过扬声器产生音响。
电子琴有多种类型,为业余型和专业型。
使用五线谱,多为高低音双行记谱。
有时也用中音谱。
电子琴又称作电子键盘,属于电子乐器,发音音量可以自由调节。
音域较宽,和声丰富,甚至可以演奏出一个管弦乐队的效果,表现力极其丰富。
它还可模仿多种音色,甚至可以奏出常规乐器所无法发出的声音(如合唱声,风雨声,宇宙声等)。
另外,电子琴在独奏时,还可随意配上类似打击乐音响的节拍伴奏,适合于演奏节奏性较强的现代音乐。
另外,电子琴还安装有效果器,如混响、回声、延音,震音轮和调制轮等多项功能装置,表达各种情绪时运用自如。
电子琴是电声乐队的中坚力量,常用于独奏主旋律并伴以丰富的和声。
还常作为独奏乐器出现,具有鲜明时代特色。
但电子琴的局限性也十分明显:
旋律与和声缺乏音量变化,过于协和、单一;在模仿各类管、弦乐器时,技法略显单调。
1.3
2系统总体方案及硬件设计(宋体、小四,加粗,固定值18磅。
以下相同要求)
2.1设计任务的分析
本次课程设计的课题是基于51单片机的电子琴的设计,所要达到的要求如下:
1、利用蜂鸣器作为发声部件。
2、两个数码管作为显示部件。
3、设置10个按键,实现高音、中音、低音的1、2、3、4、5、6、7的发音。
4、存储一首歌曲的内容,可以实现自动播放。
本次设计主要是要通过软硬件的配合实现电子琴的上述功能,操作人员可以通过按下键盘上任意一个键来发出相应的音符。
AT89S52具有高速度、低电压、低功耗、且可靠性和成本都比较低的特点。
因此本次毕业设计采用AT89S52单片机作为整个电路核心控制器件。
对于本交通控制系统使用一片AT89S52系列的单片机,不需要外扩展存储器,就能实现显示、预制状态、动态调节的功能,因而整体结构简单。
设计电路时运用89S52系列单片机的接口来实现各种输入、输出功能。
P1.待定部分0口用来作输出口,向发声电路输出信号;P2口和P0口共同实现一个矩阵键盘的功能。
同时设计了一个直流稳压电路增加电路的适应性,增加了电路的适用性,使整个系统更加紧凑,工作十分稳定
2.2系统的硬件设计
2.2.1AT89S52单片机最小系统
最小系统包括晶体振荡电路、复位开关和电源部分。
图为AT89S52的最小系统电路图。
晶振电路89S52系列单片机片内有一个高增益的反向放大器其输入引脚为XTAL1输出引脚为XTAL2用于外接石英振荡器和微调电容,构成自激振荡器。
如图所示。
复位是通过给RST引脚持续?
?
?
?
?
?
周期的低电平实现的。
一般为上电复位和手动复位。
上电自动复位是通过外部复位电路的电容充电来实现的。
一般选取晶振为12MHZ时选取电容为20PF。
手动复位通过手动持续按复位按键?
?
?
个周期来实现的。
2.2.2显示单元设计
由于设计要求有音阶及按键的显示,比较LCD与数码管显示,采用8段数码管的动态显示。
按发光二极管单元连接方式分为共阳极数码管和共阴极数码管。
共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管。
共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮。
当某一字段的阴极为高电平时,相应字段就不亮。
。
共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管。
共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮。
当某一字段的阳极为低电平时,相应字段就不亮。
本设计为了增加显示效果,采用共阴极数码管。
数码管动态显示接口是单片机中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔划"a,b,c,d,e,f,g,dp"的同名端连在一起,另外为每个数码管的公共极COM增加位选通控制电路,位选通由各自独立的I/O线控制,当单片机输出字形码时,所有数码管都接收到相同的字形码,但究竟是那个数码管会显示出字形,取决于单片机对位选通COM端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,该位就显示出字形,没有选通的数码管就不会亮。
通过分时轮流控制各个数码管的的COM端,就使各个数码管轮流受控显示,这就是动态驱动。
在轮流显示过程中,每位数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O端口,而且功耗更低。
2.2.3蜂鸣器电路
当驱动蜂鸣器的P2.2口有一定频率的脉冲输出时,蜂鸣器就能发出声音。
通过控制P2.2发出脉冲的频率能够控制蜂鸣器发出声音的音调,进而能发出美妙的音乐。
蜂鸣器直接使用P2.2口驱动。
2.2.4键盘电路
键盘电路作为电子琴系统中最重要的输入设备,在系统中承担着把操作人员想要输入的信号输入单片机的重要作用。
键盘有独立键盘和矩阵键盘。
由于设计要求简单和编程方便,本设计采用独立按键。
根据设计要求,本设计使用11个独立按键,电路功能分配与下:
P3.5———高音阶切换键
P3.4———中音阶切换键
P3.3———低音阶切换键
P1.0———do音输入键
P1.1————re音输入键
P1.2————mi音输入键
P1.3————fa音输入键
P1.4————so音输入键
P1.5————la音输入键
P1.6————ti音输入键
电路图与图?
?
?
3软件设计
3.1软件设计流程
软件的结构图如下
程序流程图如下:
软件
3.2软件设计模块化
3.2.1初始化程序
初始化程序的主要作用是定义一些变量的初值以及对中断、定时器的初始化。
在初始化程序中对变量赋初值,并要对中断进行设置,也要对定时器进行设置。
根据这个思路,初始化程序如下
//*******初始化数据*****//
voidinit(void)
{
speaker=0;//关蜂鸣器
LED1=1;//
LED2=0;
EA=1;//开总中断
TCON=0x01;//外部中断0设置为边沿触发
EX0=1;//开外部中断0
ET0=1;//开定时器0中断
ET1=1;//开定时器1中断
TMOD=0x11;//定时器0,1工作在定时状态,均为方式1
}
3.2.3键盘扫描
键盘是人与单片机通信的重要接口。
合适的键盘扫描程序能使单片机准确的运行。
3.2.5显示程序
本设计采用的共阴极数码管作为数据显示。
采用的数码管动态显示,可以节约单片机的I/O口,为以后的扩展做准备。
3.2.6发声程序
在完成了键盘服务子程序后,我们就知道了具体是哪一个键被按下了,下一步就是要让喇叭发出这个按键所特有的音符。
我们知道,每个音符之所以不同是因为它们都有各自不同的频率,而我们正好可以利用89S52中的定时器来产生不同的频率以达到这个目的。
我们只要对定时器T1的初值进行合理的设置就可完成这个工作,我们根据电子琴的音符频率表来为定时器赋初值。
主要是根据一张频率表,表如下所示:
表3-1电子琴音符频率表
音符
频率(HZ)
简谱码(T值)
音符
频率(HZ)
简谱码(T值)
低1 DO
262
63628
#4FA#
740
64860
#1 DO#
277
63731
中5SO
784
64898
低2 RE
294
63835
#5SO#
831
64934
#2RE#
311
63928
中6LA
880
64968
低3M
330
64021
#6
932
64994
低4FA
349
64103
中7SI
988
65030
#4FA#
370
64185
高1DO
1046
65058
低5SO
392
64260
#1DO#
1109
65085
#5SO#
415
64331
高2RE
1175
65110
低6LA
440
64400
#2RE#
1245
65134
#6
466
64463
高3M
1318
65157
低7SI
494
64524
高4FA
1397
65178
中1DO
523
64580
#4FA#
1480
65198
#1DO#
554
64633
高5SO
1568
65217
中2RE
587
64684
#5SO#
1661
65235
#2RE#
622
64732
高6LA
1760
65252
中3M
659
64777
#6
1865
65268
中4FA
698
64820
高7SI
1967
65283
有了这张表,我们就可以顺利地完成发声程序的编写了。
根据以上的思路以及频率表可以写出发声程序如下:
codeunsignedcharFH[]={0xFC,0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,//中音
0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,//低音的高8位
0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,
};
//音阶频率表低八位
codeunsignedcharFL[]={0x8E,0xED,0x44,0x6B,0xB4,0xF4,0x2D,//中音
0x21,0xDB,0x87,0xD7,0x68,0xE8,0x5B,//低音的低8位
0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,
};
voidtimer1()interrupt3
{TR1=0;
TH1=FH[7*m+n];
TL1=FL[7*m+n];//对T1的赋值
speaker=~speaker;//产生脉冲
TR1=1;
}
3.3软件调试
4Proteus软件仿真
5课程设计体会
参考文献
附1:
源程序代码
附2:
系统原理图
1概述
(宋体、小三,加粗,居中,固定值22磅。
以下标题相同要求)
1.1二级标题(宋体、小四,固定值22磅。
以下相同要求)
本文………..
大家注意:
此部分为正文,要求大的章节内容不能出现在同一页面内,比如:
“1概述”中的内容如果最后一页面还没有写完,就不要接着写“2系统总体方案及硬件设计”的内容,要另起一页;
参考文献可以直接接第五部分写;
附录要另起一页,不能和参考文献在同一页内;
(具体文献中,中文用宋体、英文为TimeNewRoman、五号行间距固定值18磅。
)
参考文献
书、专著:
如:
[1]贾宗璞,许合利.C语言程序设计.江苏:
中国矿业大学出版社,2007.109-119
[2]余发山,王福忠.单片机原理及应用技术.江苏:
中国矿业大学出版社,2008.241-247
期刊论文:
[序号]主要责任者.文献题名.刊名,年,卷(期):
起止页码
如:
[1]金显贺,王昌长,王忠东,等.一种用于在线检测局部放电的数字滤波技术.清华大学学报(自然科学版),1993,33(4):
62-67
书、专著:
[序号]主要责任者.文献题名.出版地:
出版社,出版年.起止页码
如:
[1]刘国钧,陈绍业,王凤翥.图书馆目录.北京:
高等教育出版社,1957.15-18
电子文献:
[序号]主要责任者.电子文献题名.电子文献的出处或可获得地址,发表或更新日期/引用日期
如:
[1]王明亮.关于中国学术期刊标准化数据库系统工程的进展.
http:
//www./1998-08-16/1998-10-04
(程序代码中的中文用宋体、英文为TimeNewRoman、五号,固定值18磅。
要求符合程序书写规范,程序中要有注释)
附1源程序代码
#include
#defineuintunsignedint
#defineucharunsignedchar
sbitP1_0=P1^0;
sbitP1_1=P1^1;
sbitP1_2=P1^2;
sbitP1_3=P1^3;
sbitP1_4=P1^4;
sbitP1_5=P1^5;
sbitP1_6=P1^6;
sbitP1_7=P1^7;
sbitLED1=P2^6;
sbitLED2=P2^7;
sbitchange=P3^2;
sbithigh=P3^5;
sbitnormal=P3^4;
sbitlow=P3^3;
sbitP2_0=P2^0;
sbitP2_1=P2^1;
sbitspeaker=P2^2;
unsignedchari;
unsignedcharkey,yin=0;
ucharm,n;
bita=0;//a为change键的键值
ucharseg[]={0x3F,/*0*/
0x06,/*1*/
0x5B,/*2*/
0x4F,/*3*/
0x66,/*4*/
0x6D,/*5*/
0x7D,/*6*/
0x07,/*7*/
0x7F,/*8*/
0x6F,/*9*/
0x37,/*N*///中音
0x38,/*L*///低音
0x76,/*H*///高音
0x79/*E*/};//共阴极数码管
codeunsignedcharFH[]={0xFC,0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,//中音
0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,//低音的高8位
0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,
};
//音阶频率表低八位
codeunsignedcharFL[]={0x8E,0xED,0x44,0x6B,0xB4,0xF4,0x2D,//中音
0x21,0xDB,0x87,0xD7,0x68,0xE8,0x5B,//低音的低8位
0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,
};
codeucharstar[]={1,2,3,1,1,2,3,1,3,4,5,3,4,5,5,6,5,4,3,1,5,6,5,4,3,1,1,12/*低音5*/,1,1,12,1};
codeucharshijian[]={4,4,4,4,4,4,4,4,4,4,8,4,4,8,2,1,2,1,4,4,2,1,2,1,4,4,4,4,6,4,4,6};
voidinit(void);
voidmusic();
voidplay();
voidseg1();
voidyinjie();
/*********主程序*****////
voidmain()
{
init();
while
(1)
{
if(a==0)
music();
else
play();
}
}
//*******1ms延迟********//
voiddelay(uintx)
{
uinti,j;
for(i=x;i>0;i--)
for(j=340;j>0;j--);
}
//*******初始化数据*****//
voidinit(void)
{
speaker=0;
LED1=1;
LED2=0;
EA=1;//开总中断
TCON=0x01;//外部中断0设置为边沿触发
EX0=1;//开外部中断0
ET0=1;
ET1=1;
TMOD=0x11;//定时器0,1工作在定时状态,均为方式1
}
///******数码管动态显示*******/////
voidseg1()
{
P2_0=1;//关数码管1
P2_1=0;//开数码管2
P0=seg[n+1];//送数码管2的数据
delay(15);//延时15ms
P2_1=1;//关数码管2
P2_0=0;//开数码管1
P0=seg[yin];//yin为high,normal,low的判断结果送数码管1的数据
delay(15);//延时15ms
}
//********高低音的选择*******//////
voidyinjie()
{
if(normal==0)
{
delay(5);
if(normal==0)
{yin=10;
m=0;
//返回10为seg[10]显示C
}
}
if(low==0)
{
delay(5);
if(low==0)
{yin=11;
m=1;
//返回11为seg[11]显示L
}
}
if(high==0)
{
delay(5);
if(high==0)
{yin=12;
m=2;
//返回12为seg[12]显示H
}
}
if(yin==0)
{
yin=13;
}
}
//********外部中断0********//
voidinter0()interrupt0
{
if(change==0)
{
delay(5);
while(change==0);
a=~a;
LED1=~LED1;
LED2=~LED2;
}
}
/////*******播放音乐程序*****////
voidmusic()
{
TH0=FH[star[i]-1];
TL0=FL[star[i]-1];
while(a==0)
{
if(i<32)
{
TR0=1;
delay(57*shijian[i]);
i++;
}
if(i==32)
{
i=0;
}
}
}
////*******演奏模式*****//////
voidplay()
{
TR0=0;
TR1=0;
yinjie();
P2_1=1;//关数码管2
P2_0=0;//开数码管1
P0=seg[yin];
if(yin!
=13&&a==1)
{
if(P1_0==0)
{
TH1=FH[7*m+n];
TL1=FL[7*m+n];
TR1=1;
while(P1_0==0)
{n=0;
seg1();
}
}
if(P1_1==0)
{TH1=FH[7*m+n];
TL1=FL[7*m+n];
TR1=1;
while(P1_1==0)
{n=1;
seg1();
}
}
if(P1_2==0)
{TH1=FH[7*m+n];
TL1=FL[7*m+n];
TR1=1;
while(P1_2==0)
{n=2;
seg1();
}
}
if(P1_3==0)
{TH1=FH[7*m+n];
TL1=FL[7*m+n];
TR1=1;
while(P1_3==0)
{n=3;
seg1();
}
}
if(P1_4==0)
{TH1=FH[7*m+n];
TL1=FL[7*m+n];
TR1=1;
while(P1_4==0)
{n=4;
seg1();
}
}
if(P1_5==0)
{TH1=FH[7*m+n];
TL1=FL[7*m+n];
TR1=1;
while(P1_5==0)
{n=5;
seg1();
}
}
if(P1