这是之前做过的一个声光电子琴小制作;
很有意思;
51单片机的,拿来和大家一起分享一下
电路原理图如下:
单片机源程序如下:
- /*
- 8个按键发出8个基本音,
- 能播放内置音乐,音乐跟随灯光闪烁
- */
- #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代表不发声,即停顿;数字即为音调
- };
- 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,//节拍
- 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 //节拍,即tone表各音调的延时
- };
- uchar code laohu_beat[]={ 24,24,24,48,5,24,24,//节拍
- 24,48,5,24,24,48,5,24,
- 24,72,5,24,24,24,24,//节拍
- 24,48,5,24,24,24,24,24,72,
- 5,24,24,48,5,24,24,//节拍
- 72,5//节拍 //节拍,即tone表各音调的延时
- };
- uchar code yishan_beat[]={ 24,24,24,24,24,24,48,//节拍
- 5,24,24,24,24,24,24,72,
- 5,24,24,24,24,24,24,//节拍
- 48,5,24,24,24,24,24,24,72,
- 5,24,24,24,24,24,24,//节拍
- 48,5,24,24,24,24,24,24,72,5//节拍,即tone表各音调的延时
- };
- uchar code ledtable[]={0x7f,0xbf,0xdf,0xef, //取反
- 0xf7,0xfb,0xfd,0xfe};//P0组口的发光二极管代码(焊接过程可能会相反,具体更改)
- uchar code ledtable2[]={0x7f,0xbf,0xdf,0xef, //取反
- 0xf7,0xfb,0xfd,0xfe};//P2组口发光二极管代码,相反!
- 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组为发光二极管组
- case 0xfd:P0=0xdd;P2=0xbb;a=0xfc;b=0x5c;EA=1;break;//注意:EA不能改为TR0
- 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]; //取节拍
- 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]; //取节拍
- 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]; //取节拍
- 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()//前后来回
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
声光电子琴.zip
(8.96 MB, 下载次数: 180)
|