/**********************************************
名称:电子琴演奏程序
作者:hs795
功能:按下按键蜂鸣器发出相应的音符,可以进行演奏!
p20接的按键用于播放示例音乐,p21用于停止当前播放音乐
2011年4月16日
**********************************************/
#include<reg52.h>
#define unchar unsigned char
#define unint unsigned int
sbit beep=P3^1;//蜂鸣器接口
sbit p30=P3^0; //演示歌曲用
sbit p31=P3^2; //停止键
sbit pk1=P3^3;
sbit pk2=P3^4;
sbit pk3=P3^5;
//数码管段码表
unchar code LED[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00}
//以下定义低中高共21个音阶的定时参数,通过定时器来实现不同音频的输出
unint code ti[21][2]={
{0xf8,0x8c},{0xf9,0x5c},{0xfa,0x14},{0xfa,0x67},{0xfb,0x04},{0xfb,0x90},{0xfc,0x0c}, //低音
{0xfc,0x44},{0xfc,0xb6},{0xfd,0x09},{0xfd,0x34},{0xfd,0x82},{0xfd,0xc8},{0xfe,0x06}, //中音
{0xfe,0x22},{0xfe,0x56},{0xfe,0x8c},{0xfe,0x9a},{0xfe,0xc1},{0xfe,0xe4},{0xff,0x03}}; //高音
//简谱由音阶x[]和节拍y[],两部分组成
//节拍为每个音阶的输出时间
//下列出现“+7”是为了得到中音
//**《两只老虎》
unchar code x0[]={1+7,2+7,3+7,1+7,1+7,2+7,3+7,1+7,3+7,4+7,5+7,3+7,4+7,5+7,5+7,6+7,5+7,4+7,3+7,1+7,5+7,6+7,5+7,4+7,3+7,1+7,1+7,5,1+7,1+7,5,1+7};
unchar code y0[]={4,4,4,4,4,4,4,4,4,4,8,4,4,8,3,1,3,1,4,4,3,1,3,1,4,4,4,4,8,4,4,8};
//**《粉刷匠》
unchar code x1[]={5+7,3+7,5+7,3+7,5+7,3+7,1+7,2+7,4+7,3+7,2+7,5+7,5+7,3+7,5+7,3+7,5+7,3+7,1+7,2+7,4+7,3+7,2+7,1+7,2+7,
2+7,4+7,4+7,3+7,1+7,5+7,2+7,4+7,3+7,2+7,5+7,5+7,3+7,5+7,3+7,5+7,3+7,1+7,2+7,4+7,3+7,2+7,1+7};
unchar code y1[]={4,4,4,4,4,4,8,4,4,4,4,16,4,4,4,4,4,4,8,4,4,4,4,16,4,4,4,4,4,4,8,4,4,4,4,16,4,4,4,4,4,4,8,4,4,4,4,16};
//**《祝你生日快乐》
unchar code x2[]={5,5,6,5,1+7,7,5,5,6,5,2+7,1+7,5,5,5+7,3+7,1+7,7,6,4+7,4+7,3+7,1+7,2+7,1+7};
unchar code y2[]={8,8,8,8,8,16,8,8,8,8,8,16,8,8,8,8,8,8,8,8,8,8,8,8,16};
//**《最幸福的人》
unchar code x3[]={3+7,5+7,6+7,6+7,6+7,6+7,6+7,3+14,3+14,2+14,2+14,3+14,2+14,7+7,7+7,6+7,5+7,5+7,6+7,7+7,1+14,6+7,6+7,5+7,6+7,2+14,2+14,2+14,1+14,2+14,2+14,3+14,1+14,7+7,6+7,
5+7,5+7,5+7,6+7,7+7,7+7,7+7,1+14,2+14,2+14,1+14,7+7,6+7};
unchar code y3[]={2,2,4,2,2,4,2,2,2,2,2,2,8,4,2,2,2,2,2,2,2,2,2,2,8,2,2,2,2,8,2,2,2,2,8,2,2,2,2,2,2,2,2,2,2,2,2,4};
//**《天边的眷恋》
unchar code x5[]= {3+7,3+7,2+7,3+7,3+7,0,1+7,2+7,1+7,7,6,6,0,0,6,6+7,6+7,5+7,5+7,5+7,2+7,2+7,1+7,2+7,
3+7,0,0,3+7,3+7,6+7,6+7,5+7,5+7,5+7,0,2+7,2+7,5+7,3+7,2+7,1+7,0,6,7,1+7,0,1+7,1+7,2+7,3+7,7,7,0};
unchar code y5[]={2,2,1,1,8,2,1,1,2,1,1,4,4,4,4,2,2,2,1,1,2,2,2,2,2,6,4,2,
2,2,2,2,1,1,4,2,2,2,2,2,1,1,2,1,1,8,2,2,2,2,3,1,8,4};
//**《心肝宝贝》
unchar code x6[]={3+7,3+7,3+7,2+7,3+7,2+7,1+7,1+7,1+7,3,5,6,1+7,1+7,6,1+7,5+7,3+7,3+7,0,
6+7,6+7,6+7,5+7,6+7,3+7,5+7,5+7,5+7,3+7,5+7,3+7,2+7,2+7,1+7,6,1+7,3+7,
2+7,3+7,2+7,2+7,3+7,3+7,3+7,2+7,3+7,2+7,1+7,1+7,1+7,3,5,6,1+7,1+7,6,1+7,
5+7,3+7,3+7,0,6+7,6+7,6+7,5+7,6+7,3+7,5+7,5+7,5+7,3+7,5+7,3+7,2+7,2+7,
1+7,6,1+7,6+7,5+7,3+7,5+7,5+7,5+7,5+7,6+7,5+7,3+7,2+7,2+7,2+7,2+7,2+7,
3+7,2+7,1+7,6,1+7,1+7,1+7,0,3,3,6,6,5,5,6,1+7,1+7,1+7,1+7,6,6,5+7,5+7,
5+7,6+7,5+7,3+7,3+7,2+7,2+7,2+7,2+7,0,2+7,2+7,1+7,3+7,2+7,2+7,3+7,5+7,
5+7,5+7,5+7,6+7,5+7,3+7,2+7,2+7,2+7,2+7,2+7,3+7,2+7,1+7,6,1+7,1+7,1+7,
1+7,3,6,6,5,5,6,1+7,1+7,1+7,1+7,6,5+7,5+7,5+7,5+7,5+7,3+7,2+7,2+7,2+7,
1+7,3+7,2+7,6,2+7,1+7,1+7};
unchar code y6[181]={1,1,1,1,3,1,1,1,1,1,4,1,1,1,1,2,1,1,4,4,1,1,1,1,3,1,1,1,1,1,2,1,1,1,2,1,2,1,1,1,3,4,1,1,
1,1,3,1,1,1,1,1,4,1,1,1,1,2,1,1,4,4,1,1,1,1,3,1,1,1,1,1,2,1,1,1,2,1,2,2,8,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,4,1,1,1,1,1,1,2,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,2,
4,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,3,4,1,1,1,1,2,2,1,1,1,1,2,2,1,1,1,1,2,2,2,1,1,4};
unint i,th,tl,m;
unchar key_l,key_h,key;
void delay(unint t)
{
unint x,y;
for(x=t;x>0;x--)
for(y=110;y>0;y--);
}
void play1()//演奏《两只老虎》
{
for(i=0;i<32;i++)
{
th=ti[x0[i]-1][0];
tl=ti[x0[i]-1][1];
TH0=th;
TL0=tl;
TR0=1;
delay(y0[i]*100);
TR0=0;
if(p30==0||p31==0)break;
}
}
void play2()//演奏《粉刷匠》
{
for(i=0;i<48;i++)
{
th=ti[x1[i]-1][0];
tl=ti[x1[i]-1][1];
TH0=th;
TL0=tl;
TR0=1;
delay(y1[i]*90);
TR0=0;
if(p30==0||p31==0)break;
}
}
void play3()//演奏《祝你生日快乐》
{
for(i=0;i<25;i++)
{
th=ti[x2[i]-1][0];
tl=ti[x2[i]-1][1];
TH0=th;
TL0=tl;
TR0=1;
delay(y2[i]*70);
TR0=0;
if(p30==0||p31==0)break;
}
}
void play4()//演奏《最幸福的人》
{
for(i=0;i<48;i++)
{
th=ti[x3[i]-1][0];
tl=ti[x3[i]-1][1];
TH0=th;
TL0=tl;
TR0=1;
delay(y3[i]*150);
TR0=0;
if(p30==0||p31==0)break;
}
}
void play5()//演奏《天边的眷恋》
{
for(i=0;i<53;i++)
{
if(x5[i]){
th=ti[x5[i]-1][0];
tl=ti[x5[i]-1][1];
}
TH0=th;
TL0=tl;
TR0=1;
delay(y5[i]*250);
TR0=0;
if(p30==0||p31==0)break;
}
}
void play6()//演奏《心肝宝贝》
{
for(i=0;i<181;i++)
{
if(x6[i]){
th=ti[x6[i]-1][0];
tl=ti[x6[i]-1][1];
}
TH0=th;
TL0=tl;
TR0=1;
delay(y6[i]*300);
TR0=0;
if(p30==0||p31==0)break;
}
}
void main()
{
TMOD = 0x01;//设置定时器为工作方式1
SM0 = 0;
SM1 = 1;
REN = 1;
EA = 1;
ES = 1;
ET0 = 1;
TR0 = 0;
while(1)
{
P1=0xff;
if(p30==0)
{
delay(2);
if(p30==0)
{
m++;
if(m>=7)m=0;
while(p30==0)
delay(2);
}
}
if(p31==0)m=0;
if(m)
P1=LED[m];
switch(m)
{
case 1:play1();break;
case 2:play2();break;
case 3:play3();break;
case 4:play4();break;
case 5:play5();break;
case 6:play6();break;
}
//键盘扫描
pk1=0;
pk2=0;
pk3=0;
key_l=P2;
key_l=key_l&0x7f;
if(key_l!=0x7f)
{
delay(2);
key_l=P2;
key_l=key_l&0x7f;
if(key_l!=0x7f)
{
pk1=1;pk2=1;pk3=0;
key_l=P2;
key_l=key_l&0x7f;
if(key_l!=0x7f)
key_h=0;
else
{
pk1=1;pk2=0;pk3=1;
key_l=P2;
key_l=key_l&0x7f;
if(key_l!=0x7f)
key_h=1;
else
{
pk1=0;pk2=1;pk3=1;
key_l=P2;
key_l=key_l&0x7f;
if(key_l!=0x7f)
key_h=2;
}
}
}
switch(key_l)
{
case 0x7e:key=0;break;
case 0x7d:key=1;break;
case 0x7b:key=2;break;
case 0x77:key=3;break;
case 0x6f:key=4;break;
case 0x5f:key=5;break;
case 0x3f:key=6;break;
default:key=10;
}
P1=LED[key+1];
key+=key_h*7;
//有按键,演奏相应音符
th=ti[key][0];
tl=ti[key][1];
TH0=th;
TL0=tl;
TR0=1;
}
pk1=0;
pk2=0;
pk3=0;
while(key_l!=0x7f)
{
key_l=P2;
key_l=key_l&0x7f;
}
delay(20);
TR0=0;
}
}
void timer0() interrupt 1 /* T0中断服务程序 */
{
beep=~beep;
TH0=th;
TL0=tl;
}