基于51单片机音乐盒程序设计基于51单片机音乐盒程序设计一、功能设计说明1、电路设计实物图矩阵键盘部分电路图2、运行流程图程序开始播放小苹果歌曲否判断任意按键是否按下继续播放小苹果歌曲是否播放完成进入电子琴模式判断K16按键是否按下是3、电子琴模式按键对应发音设计按键发音按键发音低 1 中 2 K1 K9低 2 中 3 K2 K10低 3 中 4 K3 K11低 4 中 5 K4 K12低 5 中 6 K5 K13按键发音按键发音低 6 中 7 K6 K14低 7 高 1 K7 K15中 1 重新播放小苹果 K8 K16二、硬件电路说明1、程序下载电路音乐盒电路图ISP下载接口本设计采用的单片机为AT89S52单片机,需使用ISP下载器进行下载程序,程序下载电路图如图中ISP1接口.2、音乐发音电路IO口P10发出不同频率的脉冲,则BUZZER产生各种不同的声音,本设计采用12MHZ晶振,系统频率1MHZ,定时器计数一个1us,其对应关系如下表所示:频率简谱码(T音符音符频率(HZ) 简谱码(T值)(HZ) 值)低 1 DO 262 63628 # 4 FA# 740 64860 # 1 DO# 277 63731 中 5 SO 784 64898 低 2 RE 294 63853 # 5 SO# 831 64934 # 2 RE# 311 63928 中 6 LA 88064968 低 3 M 330 64021 # 6 932 64994 低 4 FA 349 64103 中 7 SI 988 65030 # 4 FA# 370 64185 高 1 DO 1046 65058 低 5 SO 392 64260 # 1 DO# 1109 65085 # 5 SO# 415 64331 高 2 RE 1175 65110 低 6 LA 440 64400 # 2 RE# 1245 65134 # 6 466 64463 高 3 M 1318 65157 低 7 SI 494 64524 高 4 FA 1397 65178中1 DO 523 64580 # 4 FA# 1480 65198# 1 DO# 554 64633 高 5 SO 1568 65217中 2 RE 587 64684 # 5 SO# 1661 65235# 2 RE# 622 64732 高 6 LA 1760 65252中 3 M 659 64777 # 6 1865 65268中 4 FA 698 64820 高 7 SI 1967 65282计算方法:例如产生262HZ频率(发音DO),周期T=1/262=3816 us,由于定时器中断使IO不停取反,故周期T=3816/2=1908 us定时器初值N=65536-1908=63628TH0=63628/256TL0=65536%256三、程序代码说明1 、脉冲产生采用定时器0溢出中断产生脉冲,定时器初始化如下:TMOD = 0x01; //定时器0工作方式1 ,即十六位计数器计数TR0 = 1; //启动定时器ET0 = 1; //定时器0溢出中断使能EA = 1; //总中断使能定时器0溢出中断产生脉冲,void Timer0() interrupt 1代码如下:TH0 = th0;TL0 = tl0;if(th0==0)BUZZER=1; //判断停顿,有停顿不发音else{BUZZER = ~BUZZER;} //无停顿发音2、音普规则:a、音普由一个字节十六进制数组成b、高4位代表节拍,一拍约400MS,将一拍分成8份c、低4位代表音符,一一对应Note[]列表d、0x20代表歌曲结束符e、uint code Note[]={0,64580,64684,64777,64820,64898,64968,65030,/*中音*/63628,63853,64021,64103,64260,64400,64524,/*低音*/65058,65110,65157,65178,65217,65252,65282/*高音*/};该列表为发音所对应的定时器初装值例如编写如下一段音乐列表:0x83,0x81,0x82,0x8d,0x43,0x42,0x41,0x42,0x8d,0x8d,0x40 0x40表示停顿4*50MS /*你是我的小呀小苹果*/3、音普列表解读while(Xiaopingguo[temp]!=0x20) //不停判断音乐是否结尾,结尾跳出{jiepai=Xiaopingguo[temp]>>4; //获取节拍,即高4位数yinpu=Xiaopingguo[temp]&0x0F; //获取音普,即低4位数Timer_Set(yinpu); //根据列表对应发音Delay(jiepai*50); //节拍temp++;P0 = 0x0f;if(P0!=0x0f)goto out;}void Timer_Set(uchar num)为定时器0赋值子程序,包含的代码如下: th0=Note[num]/256;tl0=Note[num]%256;四、程序代码编写/******************************************************************* ***************************项目名称:音乐盒单片机型号:AT89S52频率:外部石英晶振 12MHZ设计时间:2014-08-06设计者:小左MCU工作室Q Q: 576689422******************************************************************** *************************/#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit BUZZER=P1^0;//蜂鸣器输出uchar th0,tl0; //定时器0赋值变量uchar start_; //返回变量uint code Note[]={0,64580,64684,64777,64820,64898,64968,65030,/*中音*/63628,63853,64021,64103,64260,64400,64524,/*低音*/65058,65110,65157,65178,65217,65252,65282/*高音*/};/*********************************************************************** **音普规则:1、音普由一个字节十六进制数组成2、高4位代表节拍,一拍约400MS,将一拍分成8份3、低4位代表音符,一一对应Note[]列表4、0x20代表歌曲结束符******************************************************************** ******/uchar code Xiaopingguo[]={0x83,0x81,0x82,0x6d,0x43,0x42,0x41,0x42,0x8d,0x8d,0x40, /*你是我的小呀小苹果*/0x83,0x81,0x82,0x82,0x45,0x43,0x8e,0x81,0x40,/*怎么爱你都不嫌多*/0x41,0x4e,0x8d,0x4e,0x41,0x82,0x8c,0x46,0x45,0x83,0x83,0x43,0x40, /*红红的小脸温暖我的心窝*/0x42,0x81,0x42,0x43,0x42,0x43,0x42,0x23,0x25,0x85,0x30,0x45,0x10,0x4 5,0x30,0x45,0x10,0x45,0x30,0x85,0x85,0x85,0x40,/*点亮我生命的火火火火火火*/0x83,0x81,0x82,0x6d,0x43,0x42,0x41,0x42,0x8d,0x8d,0x40, /*你是我的小呀小苹果*/0x83,0x81,0x82,0x82,0x45,0x43,0x8e,0x81,0x40,/*就像天边最美丽的云朵*/0x41,0x4e,0x8d,0x4e,0x41,0x82,0x8c,0x46,0x45,0x83,0x83,0x43,0x40, /*春天又来到了花开满山坡*/0x42,0x81,0x42,0x43,0x82,0x8c,0x8d,0x4d,0x41,0x8d,0x20 /*种下希望就会收获*/};//----延时子程序-------------------------------------------------- void Delay(uint xms){uint j;for(;xms>0;xms--)for(j=110;j>0;j--);}//--------------------------------------------------------------- //----定时器变量赋值--------------------------------------------- void Timer_Set(uchar num){th0=Note[num]/256;tl0=Note[num]%256;}//--------------------------------------------------------------- //----系统初始化------------------------------------------------- void Init(){BUZZER = 1; //关闭蜂鸣器TMOD = 0x01; //定时器0工作方式1TR0 = 1; //启动定时器ET0 = 1; //定时器0溢出中断使能EA = 1; //总中断使能start_ = 0; //返回变量初始化}//--------------------------------------------------------------- //----按键扫描--------------------------------------------------- void Key_Scan(){P0 = 0x0f;if(P0!=0x0f){Delay(5);if(P0!=0x0f){P0=0xfe;if(P0==0xee){Timer_Set(8);} //按键1被按下else if(P0==0xde){Timer_Set(12);}//按键5被按下else if(P0==0xbe){Timer_Set(2);} //按键9被按下else if(P0==0x7e){Timer_Set(6);} //按键13被按下else;P0=0xfd;if(P0==0xed){Timer_Set(9);} //按键2被按下else if(P0==0xdd){Timer_Set(13);}//按键6被按下else if(P0==0xbd){Timer_Set(3);} //按键10被按下else if(P0==0x7d){Timer_Set(7);} //按键14被按下else;P0=0xfb;if(P0==0xeb){Timer_Set(10);} //按键3被按下else if(P0==0xdb){Timer_Set(14);}//按键7被按下else if(P0==0xbb){Timer_Set(4);} //按键11被按下else if(P0==0x7b){Timer_Set(15);}//按键15被按下else;P0=0xf7;if(P0==0xe7){Timer_Set(11);} //按键4被按下else if(P0==0xd7){Timer_Set(1);} //按键8被按下else if(P0==0xb7){Timer_Set(5);} //按键12被按下else if(P0==0x77){start_=1;} //按键16被按下else;}}else{th0=0;}}//--------------------------------------------------------------- //----主程序----------------------------------------------------- void main(){uchar temp,yinpu,jiepai;Init();while(1){start:temp=0;while(Xiaopingguo[temp]!=0x20){jiepai=Xiaopingguo[temp]>>4; //获取节拍yinpu=Xiaopingguo[temp]&0x0F; //获取音普Timer_Set(yinpu);Delay(jiepai*50);temp++;P0 = 0x0f;if(P0!=0x0f)goto out;}out:th0 = 0;BUZZER = 1;//关闭蜂鸣器while(1){Key_Scan();if(start_==1){start_=0;goto start;}}}}//---------------------------------------------------------------//----定时器0中断服务程序---------------------------------------- void Timer0() interrupt 1{TH0 = th0;TL0 = tl0;if(th0==0)BUZZER=1; //判断停顿,有停顿不发音else{BUZZER = ~BUZZER;} //无停顿发音}//---------------------------------------------------------------- 更多精彩程序请在淘宝店铺中搜索“小左MCU”QQ:576689422。