一.硬件方案
利用所给键盘的1,2,3,4,5,6,7,8八个键,能够发出7个不同的音调,而且有一个按键可以自动播放歌曲,要求按键按下时发声,松开延时一小段时间,中间再按别的键则发另外一音调的声音,当系统扫描到键盘按下,则快速检测出是哪一个按键被按下,然后单片机的定时器启动,发出一定频率的脉冲,该频率的脉冲经喇叭驱动电路放大滤波后,就会发出相应的音调。电路主要由51单片机+最小系统+蜂鸣器+按键+数码管等组成;
二.设计功能
(1)使用了8个按键对应8个音符;
(2)使用了3个按键来播放内置的3首歌曲;
(3)采用了数码管的显示电路,当按键按下时,数码管显示对应按键的序号;
三.设计原理图
(1)原理图主要采用AD软件进行设计,如图:
(2)Protues仿真图如下:
四.软件设计
(1)主程序源码
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没有按键按下,返回
}
............
}
}
资料链接:https://pan.baidu.com/s/1OcJ5vrJSHrKnmolGPj_lMg?pwd=kavu