/* 8個按鍵發(fā)出8個基本音, 能播放內置音樂,音樂跟隨燈光閃爍 */ sfr P3=0xe8;//定義P3組I0口 #include<reg52.h> #define uint unsigned int #define uchar unsigned char sbit speaker=P1^4;//喇叭接30腳 sbit key1=P1^0;//流水燈按鍵(暫時) sbit key2=P1^1;//播放音樂按鍵(暫定) uchar a,b,num1,s1num,n1,n2; uchar qushu=0; char num;//定義num為可以負數 uchar code yinfu[]={0xfb,0xe9, //Do 0xfc,0x5c, //Re 0xfc,0xc1, //Mi 0xfc,0xef, //Fa 0xfd,0x45, //So 0xfd,0x92, //La 0xfd,0xd0, //Si 0xfd,0xee, //Do# 0x00,0x00, //間隔 }; uchar code shengri_tone[]={ 1,0,1,2,1,4,3,0, //生日快樂音調 1,0,1,2,1,5,4,0, 1,0,1,8,6,4,3,2,0, 7,0,7,6,4,5,4,0 //0代表不發(fā)聲,即停頓;數字即為音調 }; uchar code laohu_tone[]={1,2,3,1,0,1,2, //兩只老虎樂譜 40個音符 3,1,0,3,4,5,0,3, 4,5,0,5,6,5,4,3, 1,0,5,6,5,4,3,1, 0,3,2,1,0,3,2,1,0 }; uchar code yishan_tone[]={1,1,5,5,6,6,5, //星星樂譜 54個音符 0,4,4,3,3,2,2, 1,0,5,5,4,4,3, 3,2,0,5,5,4,4, 3,3,2,0,1,1,5,5, 6,6,5,0,4,4,3, 3,2,2,1,0 }; uchar code shengri_beat[]={ 24,1,24,48,48,48,72,5,//節(jié)拍 24,1,24,48,48,48,72,5, 24,1,24,48,48,48,48,72,5, 24,1,24,48,48,48,72,5 //節(jié)拍,即tone表各音調的延時 }; uchar code laohu_beat[]={ 24,24,24,48,5,24,24,//節(jié)拍 24,48,5,24,24,48,5,24, 24,72,5,24,24,24,24,//節(jié)拍 24,48,5,24,24,24,24,24,72, 5,24,24,48,5,24,24,//節(jié)拍 72,5//節(jié)拍 //節(jié)拍,即tone表各音調的延時 }; uchar code yishan_beat[]={ 24,24,24,24,24,24,48,//節(jié)拍 5,24,24,24,24,24,24,72, 5,24,24,24,24,24,24,//節(jié)拍 48,5,24,24,24,24,24,24,72, 5,24,24,24,24,24,24,//節(jié)拍 48,5,24,24,24,24,24,24,72,5//節(jié)拍,即tone表各音調的延時 }; uchar code ledtable[]={0x7f,0xbf,0xdf,0xef, //取反 0xf7,0xfb,0xfd,0xfe};//P0組口的發(fā)光二極管代碼(焊接過程可能會相反,具體更改) uchar code ledtable2[]={0x7f,0xbf,0xdf,0xef, //取反 0xf7,0xfb,0xfd,0xfe};//P2組口發(fā)光二極管代碼,相反! void check_key();//改為P3組為按鍵 void keyscan(); void turn();//順時針流動 void back(); void qianhou(); void dangshuang(); void delay(uint z);//延時函數聲明 void delay1(void);//聲明第二個延時函數 void play1(void);//播放生日快樂 void main() { s1num=0;//流水燈種類標志 key1=1; key2=1; TMOD=0x01; TH0=a; TL0=b; ET0=1;//打開定時器,但是未允許中斷 TR0=1; while(1) { check_key(); keyscan(); } } void time0() interrupt 1 { TH0=a; TL0=b; speaker=~speaker; } void check_key() { P3=0xff;//先賦給P2組口高電平 switch(P3)//按下一個鍵相應4個燈亮 { case 0xfe:P0=0xee;P2=0x77;a=0xfb;b=0xe9;EA=1;break;//P0,P2組為發(fā)光二極管組 case 0xfd:P0=0xdd;P2=0xbb;a=0xfc;b=0x5c;EA=1;break;// case 0xfb:P0=0xbb;P2=0xdd;a=0xfc;b=0xc1;EA=1;break; case 0xf7:P0=0x77;P2=0xee;a=0xfc;b=0xef;EA=1;break; case 0xef:P0=0xee;P2=0x77;a=0xfd;b=0x45;EA=1;break; case 0xdf:P0=0xdd;P2=0xbb;a=0xfd;b=0x92;EA=1;break; case 0xbf:P0=0xbb;P2=0xdd;a=0xfd;b=0xd0;EA=1;break; case 0x7f:P0=0x77;P2=0xee;a=0xfd;b=0xee;EA=1;break; default:EA=0;speaker=0;//P0=0xff;P2=0xff ; } } void delay(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void keyscan() { if(key1==0) { delay(5); if(key1==0) { s1num++; while(!key1); if(s1num==1) { turn(); } } if(s1num==2) { back(); } if(s1num==3) { qianhou(); } if(s1num==4) { dangshuang(); } if(s1num==5) s1num=1; } if(key2==0) { delay(5); if(key2==0) { qushu++; if(qushu==4) { qushu=1; } while(~key2); play1(); } } } void delay1(void)//第二個延時函數 { uchar n=15; while(n--) { uchar i; for(i=0;i<125;i++); } } void play1(void)//播放生日快樂 { uchar m=0; uchar s; uchar c=1; P0=0xaa; P2=0x55; if(qushu==1) { while(1) { EA=0; c=shengri_tone[m]; //取音符 s=shengri_beat[m]; //取節(jié)拍 a=yinfu[2*c-2]; b=yinfu[2*c-1]; EA=1; while(s--) { delay1(); P0=~P0; P2=~P2; } m++; if(m>=33) return; //數值是shengri相關表中的元素數量 } } else if(qushu==2) { while(1) { EA=0; c=laohu_tone[m]; //取音符 s=laohu_beat[m]; //取節(jié)拍 a=yinfu[2*c-2]; b=yinfu[2*c-1]; EA=1; while(s--) { delay1(); P0=~P0; P2=~P2; } m++; if(m>=40) return; //數值是shengri相關表中的元素數量 } } else if(qushu==3) { while(1) { EA=0; c=yishan_tone[m]; //取音符 s=yishan_beat[m]; //取節(jié)拍 a=yinfu[2*c-2]; b=yinfu[2*c-1]; EA=1; while(s--) { delay1(); P0=~P0; P2=~P2; } m++; if(m>=48) return; //數值是shengri相關表中的元素數量 } } } /*以下為N種流水燈流動花式*/ void turn()//流水燈順時針走動(5次) { for(num1=0;num1<8;num1++) { for(num=0;num<8;num++) { P0=ledtable[num]; delay(30);//時間暫定 } P0=0xff;//之后關閉P1組 for(num=7;num>-1;num--) { P2=ledtable2[num]; delay(30); } P2=0xff;//之后關閉P2組 } } void back()//逆時針流動 { for(num1=0;num1<8;num1++) { for(num=0;num<8;num++) { P2=ledtable[num]; delay(30); } P2=0xff; for(num=7;num>-1;num--) { P0=ledtable2[num]; delay(30); } P0=0xff; } } void qianhou()//前后來回 { for(num1=0;num1<10;num1++) { for(num=0;num<8;num++) { P0=ledtable[num]; P2=ledtable2[num]; delay(30); } P0=0xff; P2=0xff; for(num=7;num>-1;num--) { P0=ledtable[num]; P2=ledtable2[num]; delay(30); } P0=0xff; P2=0xff; } } void dangshuang()//單數雙數 { for(num1=0;num1<15;num1++) { P0=0x55; P2=0xaa; delay(150); P0=0xaa; P2=0x55; delay(150); } }
|