目录
具体实现功能
系统由STC89C52单片机+数码管+电源电路+音符按键+乐曲切换按键+蜂鸣器构成。
具体功能:
1、数码管显示所按的音符
2、从左到右的按键实现的音符分别是:do、re、mi、fa、so、la、si、do(高音);
3、三个按键可实现三首歌的切换:A是《挥着翅膀的女孩》,B是《同一首歌》,C是《两只蝴蝶》。
设计介绍
51单片机简介
51单片是一种低功耗、高性能CMOS-8位微控制器,具有8K可编程Flash存储器,使得其为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。
51系列单片机具有以下标准功能:
8k字节Flash,512字节RAM,
32位I/O口线,看门狗定时器,
内置4KB EEPROM,
MAX810复位电路,
三个16位定时器/计数器,
一个6向量2级中断结构,
全双工串行口。
另外, 51系列在空闲模式下,CPU停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机停止工作,直到下一个中断或硬件复位为止。本设计所使用的芯片可兼容以下所有的51系列单片机(包括AT系列和STC系列)。
设计思路
文献研究法:搜集整理相关研究资料,阅读文献,为研究做准备;
调查研究法:通过调查、分析、具体实验等方法,发现相关存在问题和解决办法;
比较分析法:比较不同设计的具体原理,以及同一类传感器性能的区别,分析系统的研究现状与发展前景;
软硬件设计法:通过软硬件设计实现硬件,最后测试各项功能是否满足要求。
设计内容
原理图(AD19)
本系统原理图设计采用Altium Designer19,具体如图。

程序(Keil5)
本设计利用KEIL5软件实现程序设计,主函数如下:
void main() //主函数入口
{
Time0_Init(); //定时器T0初始化
Speak=1; //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
while(1) //无限循环
{
switch(P1) //switch语句判断检测 P1按键状态
{
case 0xfe: //P1=0xfe "do"按键按下
delay_ms(10); //延时去抖
if(P1==0xfe) //再判断"do"按键是否按下
{
SMG=table[1]; //数码管显示"1"
i=0; //i置0
TR0=0; //关闭定时器T0
sth=Music_Code[2*i]; //定时器高八位赋值 "do"
stl=Music_Code[2*i+1]; //定时器低八位赋值 "do"
TR0=1; //启动定时器T0
for(j=0;j<=1000;j++) //软件延时,在一定时间里检测
{
delay_ms(10); //延时一下
if(P1==0xfe) continue; //"do"按键按下,跳出(继续发音)
else break; //松开了,则返回
}
SMG=0xff; //关闭数码管显示
Speak=1; //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
TR0=0; //关闭定时器T0
for(;;)
{
while(P1==0xfe); //等待按键松开
delay_ms(10); //延时去抖
if(P1==0xfe) continue;
else break; //确定松开,退出
}
TR0=0; //关闭定时器T0
}
break; //返回
case 0xfd: //P1=0xfd "re"按键按下
delay_ms(10); //延时去抖
if(P1==0xfd) //再判断"re"按键是否按下
{
SMG=table[2]; //数码管显示"2"
i=1; //i置1
TR0=0; //关闭定时器T0
sth=Music_Code[2*i]; //定时器高八位赋值 "re"
stl=Music_Code[2*i+1]; //定时器低八位赋值 "re"
TR0=1; //启动定时器T0
for(j=0;j<=1000;j++) //软件延时,在一定时间里检测
{
delay_ms(10); //延时一下
if(P1==0xfd) continue; //"re"按键按下,跳出(继续发音)
else break; //松开了,则返回
}
SMG=0xff; //关闭数码管显示
Speak=1; //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
TR0=0; //关闭定时器T0
for(;;)
{
while(P1==0xfd); //等待按键松开
delay_ms(10); //延时去抖
if(P1==0xfd) continue;
else break; //确定松开,退出
}
}
TR0=0; //关闭定时器T0
break; //返回
case 0xef: //P1=0xef "mi"按键按下
delay_ms(10); //延时去抖
if(P1==0xef) //再判断"mi"按键是否按下
{
SMG=table[3]; //数码管显示"3"
i=2; //i置2
TR0=0; //关闭定时器T0
sth=Music_Code[2*i]; //定时器高八位赋值 "mi"
stl=Music_Code[2*i+1]; //定时器低八位赋值 "mi"
TR0=1; //启动定时器T0
for(j=0;j<=1000;j++) //软件延时,在一定时间里检测
{
delay_ms(10); //延时一下
if(P1==0xef) continue; //"mi"按键按下,跳出(继续发音)
else break; //松开了,则返回
}
SMG=0xff; //关闭数码管显示
Speak=1; //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
TR0=0; //关闭定时器T0
for(;;)
{
while(P1==0xef); //等待按键松开
delay_ms(10); //延时去抖
if(P1==0xef) continue;
else break; //确定松开,退出
}
}
TR0=0; //关闭定时器T0
break; //返回
default: break; //没有P1没有按键按下,返回
}
switch(P3) //switch语句判断检测 P3按键状态
{
case 0xfe: //P3=0xfe "fa"按键按下
delay_ms(10); //延时去抖
if(P3==0xfe) //再判断"fa"按键是否按下
{
SMG=table[4]; //数码管显示"4"
i=3; //i置3
TR0=0; //关闭定时器T0
sth=Music_Code[2*i]; //定时器高八位赋值 "fa"
stl=Music_Code[2*i+1]; //定时器低八位赋值 "fa"
TR0=1; //启动定时器T0
for(j=0;j<=1000;j++) //软件延时,在一定时间里检测
{
delay_ms(10); //延时一下
if(P3==0xfe) continue; //"fa"按键按下,跳出(继续发音)
else break; //松开了,则返回
}
SMG=0xff; //关闭数码管显示
Speak=1; //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
TR0=0; //关闭定时器T0
for(;;)
{
while(P3==0xfe); //等待按键松开
delay_ms(10); //延时去抖
if(P3==0xfe) continue;
else break; //确定松开,退出
}
}
TR0=0; //关闭定时器T0
break; //返回
case 0xf7: //P3=0xf7 "so"按键按下
delay_ms(10); //延时去抖
if(P3==0xf7) //再判断"so"按键是否按下
{
SMG=table[5]; //数码管显示"5"
i=4; //i置4
TR0=0; //关闭定时器T0
sth=Music_Code[2*i]; //定时器高八位赋值 "so"
stl=Music_Code[2*i+1]; //定时器低八位赋值 "so"
TR0=1; //启动定时器T0
for(j=0;j<=1000;j++) //软件延时,在一定时间里检测
{
delay_ms(10); //延时一下
if(P3==0xf7) continue; //"so"按键按下,跳出(继续发音)
else break; //松开了,则返回
}
SMG=0xff; //关闭数码管显示
Speak=1; //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
TR0=0; //关闭定时器T0
for(;;)
{
while(P3==0xf7); //等待按键松开
delay_ms(10); //延时去抖
if(P3==0xf7) continue;
else break; //确定松开,退出
}
}
TR0=0; //关闭定时器T0
break; //返回
case 0xef: //P3=0xef "la"按键按下
delay_ms(10); //延时去抖
if(P3==0xef) //再判断"la"按键是否按下
{
SMG=table[6]; //数码管显示"6"
i=5; //i置5
TR0=0; //关闭定时器T0
sth=Music_Code[2*i]; //定时器高八位赋值 "la"
stl=Music_Code[2*i+1]; //定时器低八位赋值 "la"
TR0=1; //启动定时器T0
for(j=0;j<=1000;j++) //软件延时,在一定时间里检测
{
delay_ms(10); //延时一下
if(P3==0xef) continue; //"la"按键按下,跳出(继续发音)
else break; //松开了,则返回
}
SMG=0xff; //关闭数码管显示
Speak=1; //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
TR0=0; //关闭定时器T0
for(;;)
{
while(P3==0xef); //等待按键松开
delay_ms(10); //延时去抖
if(P3==0xef) continue;
else break; //确定松开,退出
}
}
TR0=0; //关闭定时器T0
break; //返回
case 0xdf: //P3=0xdf "si"按键按下
delay_ms(10); //延时去抖
if(P3==0xdf) //再判断"si"按键是否按下
{
SMG=table[7]; //数码管显示"7"
i=6; //i置6
TR0=0; //关闭定时器T0
sth=Music_Code[2*i]; //定时器高八位赋值 "si"
stl=Music_Code[2*i+1]; //定时器低八位赋值 "si"
TR0=1; //启动定时器T0
for(j=0;j<=1000;j++) //软件延时,在一定时间里检测
{
delay_ms(10); //延时一下
if(P3==0xdf) continue; //"si"按键按下,跳出(继续发音)
else break; //松开了,则返回
}
SMG=0xff; //关闭数码管显示
Speak=1; //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
TR0=0; //关闭定时器T0
for(;;)
{
while(P3==0xdf); //等待按键松开
delay_ms(10); //延时去抖
if(P3==0xdf) continue;
else break; //确定松开,退出
}
}
TR0=0; //关闭定时器T0
break; //返回
case 0xbf: //P3=0xbf "高音do"按键按下
delay_ms(10); //延时去抖
if(P3==0xbf) //再判断"高音do"按键是否按下
{
SMG=table[1]&0x7f; //数码管显示"1"带小数点(1.)
i=7; //i置7
TR0=0; //关闭定时器T0
sth=Music_Code[2*i]; //定时器高八位赋值 "高音do"
stl=Music_Code[2*i+1]; //定时器低八位赋值 "高音do"
TR0=1; //启动定时器T0
for(j=0;j<=1000;j++) //软件延时,在一定时间里检测
{
delay_ms(10); //延时一下
if(P3==0xbf) continue; //"高音do"按键按下,跳出(继续发音)
else break; //松开了,则返回
}
SMG=0xff; //关闭数码管显示
Speak=1; //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
TR0=0; //关闭定时器T0
for(;;)
{
while(P3==0xbf); //等待按键松开
delay_ms(10); //延时去抖
if(P3==0xbf) continue;
else break; //确定松开,退出
}
}
TR0=0; //关闭定时器T0
break; //返回
default: break; //没有P3没有按键按下,返回
}
if(Key1==0) //按键1按下(播放 "挥着翅膀的女孩")
{
delay_ms(10); //延时去抖
if(Key1==0) //再判断按键1是否按下
{
SMG=table[10]; //数码管显示"A"
for(i=0;Music_hzcb[i]!=0xff;i++) //for循环语句
{ //Music_hzcb[]=0ff时,跳出for循环语句,停止播放音乐
sth=yinfu1[(Music_hzcb[i]%100)/10-1][((Music_hzcb[i]%10)-1)*2]; //定时器高八位赋值
stl=yinfu1[(Music_hzcb[i]%100)/10-1][((Music_hzcb[i]%10)-1)*2+1];//定时器低八位赋值
i++; //i加1
TR0=1; //启动定时器T0
delay_ms(4*500/length[Music_hzcb[i]%10]); //确定几分音符(节拍)
TR0=0; //节拍结束,关闭定时器T0
}
SMG=0xff; //关闭数码管显示
Speak=1; //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
for(;;)
{
while(Key1==0); //等待按键松开
delay_ms(10); //延时去抖
if(Key1==0) continue;
else break; //确定松开,退出
}
}
}
if(Key2==0) //按键2按下(播放 "同一首歌")
{
delay_ms(10); //延时去抖
if(Key2==0) //再判断按键2是否按下
{
SMG=table[11]; //数码管显示"B"
for(i=0;Music_tyshg[i]!=0xff;i++) //for循环语句
{ //Music_tyshg[]=0ff时,跳出for循环语句,停止播放音乐
sth=yinfu1[(Music_tyshg[i]%100)/10-1][((Music_tyshg[i]%10)-1)*2]; //定时器高八位赋值
stl=yinfu1[(Music_tyshg[i]%100)/10-1][((Music_tyshg[i]%10)-1)*2+1];//定时器低八位赋值
i++; //i加1
TR0=1; //启动定时器T0
delay_ms(4*500/length[Music_tyshg[i]%10]); //确定几分音符(节拍)
TR0=0; //节拍结束,关闭定时器T0
}
SMG=0xff; //关闭数码管显示
Speak=1; //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
for(;;)
{
while(Key2==0); //等待按键松开
delay_ms(10); //延时去抖
if(Key2==0) continue;
else break; //确定松开,退出
}
}
}
if(Key3==0) //按键3按下(播放 "两只蝴蝶")
{
delay_ms(10); //延时去抖
if(Key3==0) //再判断按键3是否按下
{
SMG=table[12]; //数码管显示"C"
for(i=0;Music_lzhhd[i]!=0xff;i++) //for循环语句
{ //Music_lzhhd[]=0ff时,跳出for循环语句,停止播放音乐
sth=yinfu1[(Music_lzhhd[i]%100)/10-1][((Music_lzhhd[i]%10)-1)*2]; //定时器高八位赋值
stl=yinfu1[(Music_lzhhd[i]%100)/10-1][((Music_lzhhd[i]%10)-1)*2+1];//定时器低八位赋值
i++; //i加1
TR0=1; //启动定时器T0
delay_ms(4*500/length[Music_lzhhd[i]%10]); //确定几分音符(节拍)
TR0=0; //节拍结束,关闭定时器T0
}
SMG=0xff; //关闭数码管显示
Speak=1; //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
for(;;)
{
while(Key3==0); //等待按键松开
delay_ms(10); //延时去抖
if(Key3==0) continue;
else break; //确定松开,退出
}
}
}
}
}
代码运行截图:

仿真实现(protues8.7)
本设计利用protues8.7软件实现仿真设计。

全部资料
全部资料包括程序(KEIL5)、AD原理图(AD19)、protues仿真(protues8.7)、参考论文(仅供参考)、开题报告、任务书、实物图、讲解视频、软硬件设计框图等,具体如图,全网最全!!


资料获取:
https://docs.qq.com/doc/DSXZnZHl4cVhkTk5p
该博客围绕51单片机音乐切换系统展开,介绍了系统由STC89C52单片机等构成,具备数码管显示音符、按键切换乐曲等功能。阐述了51单片机特性,采用多种研究方法进行设计,给出原理图、程序及仿真实现,还提供了丰富资料获取途径。
4万+

被折叠的 条评论
为什么被折叠?



