课程设计任务书本课题是设计一个基于MCS-51系列单片机的音乐喷泉,随着音乐音调节拍的变化,彩灯也随之变化。
先用Keil软件调试编写的程序再用Proteus软件仿真,在Proteus软件商是用两个软件,一个来切换演奏出不同的乐曲,利用定时器0发出不同频率的方波从P3.7输出,使蜂鸣器发出不同的音调,然后延时控制音调的节拍,与之相对应的LED灯亮起;另一个用来切换八路LED的变化的花样并且喇叭发出声音。
关键词:AT89c0251单片机;音乐;LED灯1.绪论 (4)2.设计内容 (4)3.软件设计 (4)3.1 程序设计分析 (4)3.2 歌曲简谱的编码规则 (5)3.3程序流程图 (6)3.4 软件源程序 (8)4.硬件设计 (15)4.1 AT89c2051单片机 (15)4.2电路原理 (17)5.仿真 (18)5.1 ISIS介绍 (18)5.2 Keil介绍 (19)5.3 仿真结果图 (20)6.心得体会 (22)参考文献 (22)1.绪论德国发明家奥图皮士特先生在1930年提出喷泉的相关理论,随后他在百货商店和餐馆前建造小型的喷泉。
经过多年来的发展,音乐喷泉的设计变的多样化,构造变得复杂化。
在1952年的夏天,在西柏林的工业展览中,一个美国人看到了奥图皮士特先生音乐喷泉的表演,并把它带回纽约。
1953年1月15日音乐喷泉在美国首次表演,表演期间超过150万人观看。
在音乐喷泉走向全世界的同时,各种新技术也不断地运用在音乐喷泉上,使其表演变得复杂和美丽,给人们带来无限的乐趣,提高了人们的生活质量。
为了使控制简单可靠,活用现代社会的市场需求,各种形式的喷泉层出不穷,并逐步转向小型和营业性较强的方向发展。
其音乐喷泉的控制也变得灵活多样,如单片机、PLC、DSP等都在音乐喷泉中有所运用,当然也具有优缺点。
本课题选用单片机作为此次音乐喷泉控制系统设计的控制核心,主要是为了实现单片机的放音,并控制多个彩灯随着音乐的音调节奏变化而随之变换。
2.设计内容⑴电路有两种工作模式:演奏音乐模式和花样灯模式。
演奏音乐模式:演奏完整的一首的歌曲,八路LED随着音乐变化。
花样灯模式:八路LED变化出各种花样,蜂鸣器随着发出“嘀嘀”声。
⑵按下按键1进入演奏音乐模式,再按切换歌曲,共两首歌曲。
⑶按下按键2进入花样灯模式,再按切换LED花样,共四种花样。
3.软件设计3.1 程序设计分析程序利用了R6和R7两个寄存器分别作为花样和音乐的标志,都初始化为0.用到了两个外部中断和一个定时器,两个按键接两个外部中断,按键1使得R7在1和2之间切换,当按下按键1时产生外部中断1,中断程序使得R7加1当R7为2时使之为0,用程序检测R7的值,R7等于1时播放第一首歌曲,等于2时播放第二首歌;按键2使得R6在0~4之间切换,当按下按键2时产生外部中断0,中断程序使得R6加1,当R6为4时使之为0,根据R6的值来切换LED的花样。
R6和R7的值是互斥的,设置R7等于1、2时,R6同时设置为0;设置R6等于1~4时,R7也同时设置为0。
歌曲播放的设计:利用定时器0发出不同频率的方波从P3.7输出,使蜂鸣器发出不同的音调,然后延时控制音调的节拍。
当程序检测到R7不为0时调用音乐子程序,先将歌曲的简谱进行编码,储存在一个编码表中。
在子程序中从对应的编码表中取出一个数,然后分离出高4位得到音调,接着找出程序相应的值赋给定时器0,使之定时操作喇叭,得出相应的音调,同时从P1口输出相应的值使得八路LED灯随着音乐变化而发生相应的变化;接着分离出该数的低4位,得到延时时间,接着调用软件延时。
花样灯的设计:一共设计了四种花样,即花样一是一半灯循环移动、花样二是八个灯循环闪烁,花样三是高低四位轮流亮,花样四是有八个灯循环被点亮和熄灭。
R6的值为1~4一次对应花样的1~4,当程序检测到R6的值不为0时就调用与其值相对应的花样的子程序。
3.2 歌曲简谱的编码规则do re mi fa so la si分别编码为1~7,重音do编为8,重音re编为9,停顿编为0.播放长度一十六分音符为单位(在本程序中为165ms),一拍即四分音符等于4个十六分音符,编为4,其他的播放时间以此类推。
音调作为编码的高4位,二播放时间作为低4位,如此音调和节拍就构成了一个编码。
以ffH为曲谱的结束标志。
举例1:音调do,发音长度为两拍,集二分音符,将其编码为18H。
举例2:音调re,发音长度为半拍,集八分音符,将其编码为22H。
确定定时器0对应于音调的初值:假设要得到500HZ的声音。
500HZ的声音信号每个周期为2ms,即2000us。
假设单片机采用12MHZ的晶振,每个机器周期的时间为12/12M=1us。
故单片机操作(对与蜂鸣器相连的I/O口取反)一次蜂鸣器的时间间隔为2000us/1us/2=1000个机器周期,故给工作在方式1的定时器0赋初值C=[t/MC]补=模-[t/MC],C=(3E8H)补=10000H-[3E8H]=FC18H,TH0=#FCH,TL0=#18H。
下面给出定时器0工作在方式1对应各音调的初值,假定使用的晶振是12MHZ:3.3程序流程图主程序流程图播放音乐子程序流程图3.4 软件源程序#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit duan=P2^6;sbit key1=P3^2;//按key1可切换花样sbit key2=P3^3;//按key2可切换歌曲sbit fm=P3^7;//蜂鸣器连续的IO口sbit P34=P3^4;//矩阵键盘的一列uchar code huayang1[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf};//花样1uchar code huayang2[]={0x7f,0xfe,0xbf,0xfd,0xdf,0xfb,0xef,0xf7,0xef,0xfb,0xdf,0xfd,0xbf,0xfe};//花样2uchar code huayang3[]={0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};char code huayang4[]={ 0x55,0xaa,0xcc,0x33,0x99,0x66,0x0f,0xf0};uchar count1;//花样标志uchar count2;//歌曲标志uchar timeh,timel,i;//================简谱====================//编程规则:字节高位是简谱,低位是持续时间,//代表多少个十六分音符//1-7代表中央C调,8-E代表高八度,0代表停顿//最后的0是结束标志uchar code qnzl[]={ //千年之恋0x12,0x22,0x34,0x84,0x74,0x54,0x38,0x42,0x32,0x22,0x42,0x34,0x84,0x72,0x82,0x94 ,0xA8,0x08,//前奏0x32,0x31,0x21,0x32,0x52,0x32,0x31,0x21,0x32,0x62,//竹林的灯火到过的沙漠0x32,0x31,0x21,0x32,0x82,0x71,0x81,0x71,0x51,0x32,0x22,//七色的国度不断飘逸风中0x32,0x31,0x21,0x32,0x52,0x32,0x31,0x21,0x32,0x62,//有一种神秘灰色的旋涡0x32,0x31,0x21,0x32,0x83,0x82,0x71,0x72,0x02,//将我卷入了迷雾中0x63,0xA1,0xA2,0x62,0x92,0x82,0x52,//看不清的双手0x31,0x51,0x63,0x51,0x63,0x51,0x63,0x51,0x62,0x82,0x7C,0x02,//一朵花传来谁经过的温柔0x61,0x71,0x82,0x71,0x62,0xA2,0x71,0x76,//穿越千年的伤痛0x61,0x71,0x82,0x71,0x62,0x52,0x31,0x36,//只为求一个结果0x61,0x71,0x82,0x71,0x62,0xA3,0x73,0x62,0x53,//你留下的轮廓指引我0x42,0x63,0x83,0x83,0x91,0x91,//黑夜中不寂寞0x61,0x71,0x82,0x71,0x62,0x0A2,0x71,0x76,//穿越千年的哀愁0x61,0x71,0x82,0x71,0x62,0x52,0x31,0x36,//是你在尽头等我0x61,0x71,0x82,0x71,0x62,0xA3,0x73,0x62,0x53,//最美丽的感动会值得0x42,0x82,0x88,0x02,0x74,0x93,0x89,0xff//结束标志//用一生守候};uchar code jmszl[]={ //寂寞沙洲冷0x12,0x12,0x22,0x32,0x31,0x22,0x21,0x22,//自你走后心憔悴0x21,0x31,0x51,0x52,0x31,0x52,0x61,0x15,0x14,//白色油桐风中纷飞0x51,0x52,0x31,0x52,0x62,0x13,0x11,0x13,0x32,0x28,0x08,0x28,//落花似人有情这个季节0x31,0x32,0x31,0x32,0x11,0x21,0x51,0x52,0x51,0x52,//河畔的风放肆拼命地吹0x51,0x51,0x31,0x32,0x31,0x32,0x81,0x72,0x63,//不断拨弄离人的眼泪0x62,0x71,0x81,0x72,0x61,0x61,0x52,0x31,0x21,0x32,0x51,0x54,//那样浓烈的爱再也无法给0x22,0x12,0x11,0x12,0x11,0x12,0x12,0x14,0x26,0x32,0x26,//伤感一夜一夜0x32,0x61,0x51,0x51,0x31,0x31,0x21,0x31,0x51,0x61,0x51,0x31,0x51,//当记忆的线缠绕过往支离破碎0x02,0x32,0x81,0x81,0x81,0x81,0x62,0x52,0x34,//是慌乱占据了心扉0x31,0x81,0x81,0x81,0x61,0x91,0x82,//有花儿伴着蝴蝶0x51,0x51,0x51,0x51,0x31,0x61,0x53,//孤雁可以双飞0x21,0x11,0x21,0x11,0x22,0x11,0x21,0x26,//夜深人静独徘徊0x32,0x61,0x51,0x51,0x31,0x31,0x21,0x31,0x51,0x61,0x51,0x31,0x51,0x52,//当幸福恋人寄来红色分享喜悦0x31,0x31,0x81,0x81,0x81,0x61,0x91,0x81,0x61,0x31,0x56,//闭上双眼难过头也不敢回0x32,0x32,0x81,0x81,0x81,0x81,0x91,0x81,0x61,0x81,0x61,0x51,0x31,0x51,0x34, //仍然捡尽寒枝不肯安歇微带着后悔0x21,0x31,0x51,0x31,0x21,0x11,0x61,0x21,0x16,//寂寞沙洲我该思念谁0xff};//==============简谱音调对应的定时器初值=======//适合11.0592M的晶振uchar code cuzhi[]={0xff,0xff,//占位0xFC,0x8E,//中央C调1-70xFC,0xED,0xFD,0x43,0xFD,0x6A,0xFD,0xB3,0xFD,0xF3,0xFE,0x2D,0xFE,0x47, //高八度1-70xFE,0x76,0xFE,0xA1,0xFE,0xC7,0xFE,0xD9,0xFE,0xF9,0xFF,0x16};uchar yinyue[]={0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0x0,0x0}; //将音调转化为对应的LED样式void delay1(uint z); //延时1MSvoid delay(uint z); //延时165MS,即十六分音符void song();void beep();//蜂鸣器叫一声main(){ uchar x;count1=0;//流水灯无花样count2=1;//唱第一首歌P34=0;//选取矩阵键盘的一列EA=1;//开总中断EX0=1;//开外部中断0IT0=1;//外部中断0下降沿触发方式EX1=1;//开外部中断1IT1=1;//外部中断1下降沿触发方式TMOD=0x01;//定时器0工作在方式1TH0=0;TL0=0;ET0=1;while(1){if(count1!=0){switch(count1){case 1:for(x=0;x<14;x++){duan=1;P1=huayang1[x];beep();delay1(300);duan=0;if(count1!=1)break;}break;case 2:for(x=0;x<14;x++){duan=1;P1=huayang2[x];beep();delay1(300);duan=0;if(count1!=2)break;}break;case 3:for(x=0;x<16;x++){duan=1;P1=huayang3[x];beep();delay1(300);duan=0;if(count1!=3)break;}break;case 4:for(x=0;x<8;x++){duan=1;P1=huayang4[x];beep();delay1(300);duan=0;if(count1!=4)break;}break;}}else{song();delay1(1000);}}}void int0() interrupt 0{EA=0;//关总中断delay1(1);//去抖if(key1==0){count2=0;//不让蜂鸣器唱歌TR0=0;count1++;if(count1==5)count1=1;}EA=1;//开总中断}void int1() interrupt 2{EA=0;//关总中断delay1(1);//去抖if(key2==0){count1=0;//流水灯无花样TR0=1;i=0;//从头开始唱count2++;if(count2==3)count2=1;}EA=1;//开总中断}void timer0() interrupt 1 //用于产生各种音调{TH0=timeh;TL0=timel;fm=~fm;}void song(){uint temp;uchar jp;//jp是简谱i=0;while(1){ if(count2==0){break;}if(count2==1) //选曲temp=qnzl[i];if(count2==2)temp=jmszl[i];if(temp==0xff)break;jp=temp/16; //取数的高4位duan=1;P1=yinyue[jp];duan=0;if(jp!=0){timeh=cuzhi[jp*2];timel=cuzhi[jp*2+1];}else{TR0=0;fm=1;//关蜂鸣器}delay(temp%16); //取数的低4位TR0=0; //唱完一个音停10MSfm=1;delay1(10);TR0=1;i++;}TR0=0;fm=1;}void delay(uint z) //延时165MS,即十六分音符{ uint x,y;for(x=z;x>0;x--)for(y=19000;y>0;y--);}void delay1(uint z) //延时1MS{ uint x,y;for(x=z;x>0;x--)for(y=112;y>0;y--);}void beep() //蜂鸣器叫一声{ uchar i;for(i=0;i<50;i++){ fm=~fm;delay1(1);}fm=1;}4.硬件设计4.1 AT89c2051单片机AT89c2051是美国ATMEL公司生产的低电平、高性能CMOS8位单片机,片内含2K bytes的可反复擦写的只读程序存储器(PEROM)和128bytes的随机数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,AT89C2051单片机在电子类产品中有广泛的应用。