找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2145|回复: 0
打印 上一主题 下一主题
收起左侧

声光电子琴主程序

[复制链接]
跳转到指定楼层
楼主
ID:367788 发表于 2018-7-9 11:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*
8个按键发出8个基本音,
能播放内置音乐,音乐跟随灯光闪烁
*/
sfr P3=0xe8;//定义P3I0
#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;//
                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()//前后来回
{
        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);
        }                                                            
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表