立即注册 登录
返回首页

uid:184758的个人空间

日志

多功能电子琴,能播放三首歌,可以暂停存储切换歌曲,还有随跟随音乐节奏的灯

已有 700 次阅读2017-8-8 16:01

#include<AT89X52.h>
#define KeyPort P0
unsigned char High,Low,t,h; //定时器预装值的高8位和低8位
sbit SPK=P3^7;          //定义蜂鸣器接口
sbit playSongKey=P3^0;           //功能键
sbit keybofang=P3^1;   //播放键
sbit tingzhi=P3^2;
sbit playSongKey1=P3^4;
sbit playSongKey2=P3^5;
sbit qiehuan=P3^3;
unsigned char code freq[][2]={ 
  0xD8,0xF7,//00440HZ 1   
  0xBD,0xF8,//00494HZ 2  
  0x87,0xF9,//00554HZ 3  
  0xE4,0xF9,//00587HZ 4    
  0x90,0xFA,//00659HZ 5     
  0x29,0xFB,//00740HZ 6     
  0xB1,0xFB,//00831HZ 7      
  0xEF,0xFB,//00880HZ 1
};

unsigned char Time,temp,song3[50],t1,flag=0,count=-1; 
unsigned char code YINFU[9][1]={{' '},{'1'},{'2'},{'3'},{'4'},{'5'},{'6'},{'7'},{'8'}};
                          //天空之城
unsigned char code MUSIC[]={
6,2,1,      7,2,1,      1,3,3,  7,2,1,    1,3,2,    3,3,2,    7,2,6,
3,2,1,      3,2,1,      6,2,3,  5,2,1,    6,2,2, 1,3,2,  5,2,6,
3,2,2,      4,2,3,      3,2,1, 4,2,2,  1,3,2, 3,2,5,    1,3,1,
1,3,1,      1,3,1,      7,2,3, 4,2,1,    4,2,2, 7,2,2,  7,2,6,
6,2,1,      7,2,1,      1,3,3, 7,2,1,  1,3,2,   3,3,2,  7,2,6,
3,2,1,      3,2,1,      6,2,3, 5,2,1,  6,2,2,   1,3,2,  5,2,6,
2,2,1,      3,2,1,      4,2,2, 1,3,1,  7,2,2,   1,3,3,  2,3,1, 
2,3,1,      3,3,1,      1,3,5, 1,3,1,  7,2,1,   6,2,1,  6,2,1,
7,2,2,      5,2,2,      6,2,6, 1,3,1,  2,3,1,   3,3,3,  2,3,1,
3,3,2,      5,3,2,      2,3,6, 5,2,1,  5,2,1,   1,3,3,  7,2,1,
1,3,2,      3,3,2,      3,3,8, 6,2,1,  7,2,1,   1,3,2,  7,2,2,
2,3,1,      2,3,1,      1,3,3, 5,2,5,  4,3,2,   3,3,2,  2,3,2,
1,3,2,      3,3,6,      3,3,2, 6,3,4,  5,3,2,   5,3,2,  3,3,1,
2,3,1,      1,3,5,      1,3,1, 2,3,2,  1,3,1,   2,3,1,  2,3,2,
5,3,2,      3,3,6,      3,3,2, 6,3,4,  5,3,4,   3,3,1,  2,3,1,
1,3,5,      1,3,1,      2,3,2, 1,3,1,  2,3,3,   7,2,2,  0,0,0 
                             
                                      };
unsigned char code MUSIC1[]={ //世上只有妈妈好
6,2,3, 5,2,1, 3,2,2, 5,2,2, 1,3,2, 6,2,1, 5,2,1,
6,2,4, 3,2,2, 5,2,1, 6,2,1, 5,2,2, 3,2,2, 1,2,1,
6,1,1, 5,2,1, 3,2,1, 2,2,4, 2,2,3, 3,2,1, 5,2,2,
5,2,1, 6,2,1, 3,2,2, 2,2,2, 1,2,4, 5,2,3, 3,2,1,
2,2,1, 1,2,1, 6,1,1, 1,2,1, 5,1,6, 0,0,0 
                                      };
unsigned char code MUSIC2[]={ //中华人民共和国国歌
5,1,1, 1,2,3, 1,2,1, 1,2,1, 1,2,1, 5,1,1, 6,1,1, 7,1,1, 1,2,2, 1,2,2,
3,2,1, 1,2,1, 2,2,1, 3,2,1, 5,2,2, 5,2,1, 5,2,2,
3,2,2, 3,2,1, 1,2,2, 3,2,1, 5,2,2, 3,2,1, 2,2,2, 2,2,4,
6,2,2,5,2,2,2,2,2,3,2,2,5,2,1,3,2,2,5,2,1,3,2,1,2,2,1,3,2,1,1,2,1,2,2,1,3,2,2,
5,2,2,6,1,1,1,2,1,1,2,1,3,2,2,3,2,1,5,2,2,5,2,1,2,2,1,2,2,1,2,2,1,6,1,1,6,1,1,2,2,4,
5,1,1,1,2,3,1,2,1,3,2,3,3,2,1,5,2,4,5,2,4,
1,2,2,3,2,1,5,2,1,5,1,1,6,2,2,5,2,2,
3,2,2,1,2,1,5,2,1,5,2,1,5,2,1,3,2,1,1,2,1,5,1,2,1,2,2,
3,1,1,1,1,1,5,2,1,5,2,1,5,2,1,3,2,1,1,2,1,5,1,2,1,2,2,5,1,2,1,2,2,5,1,2,1,2,2,1,2,2,
0, 0, 0};

                         // 音阶频率表 高八位
unsigned char code FREQH[]={
                         0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8, 
                         0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC, //1,2,3,4,5,6,7,8,i
                         0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,
                         0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,
                               } ;
                         // 音阶频率表 低八位
unsigned char code FREQL[]={
                         0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,
                         0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F, //1,2,3,4,5,6,7,8,i
                         0xEE,0x44, 0x6B,0xB4,0xF4,0x2D, 
                         0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,
                                };

void Init_Timer0(void);//定时器初始化

//延时函数大约约2*z+5us
void delay2xus(unsigned char z)
{
   while(z--);
}
// 延时函数大约约1ms
void delayms(unsigned char x)
{
   while(x--)
   {
     delay2xus(200);
     
   }
}


/*------------------------------------------------
                节拍延时函数
 各调1/4节拍时间:
 调4/4  125ms
 调2/4  250ms
 调3/4  187ms
------------------------------------------------*/
void delayTips(unsigned char t)
{
    unsigned char i;
          for(i=0;i<t;i++)
    {
            delayms(250);
    }
    TR0=0;
 }
//播放音乐的函数
void PlaySong()
{
   TH0=High;//赋值定时器时间,决定频率
   TL0=Low;
   TR0=1;      //打开定时器
   switch(t)
                {
                 case 1:h=0xfe;break;
                 case 2:h=0xfd;break;
                 case 3:h=0xfb;break;
                 case 4:h=0xf7;break;
                 case 5:h=0xef;break;
                 case 6:h=0xdf;break;
                 case 7:h=0xbf;break;
                 case 8:h=0x7f;break;      //分别对应不用的音调
                 default:h=0xFF;break;
                }
P1=h;
   delayTips(Time); //延时所需要的节拍                      
}
void Init_EX(void)
{
  EX0=1;EX1=1;
  IT0=1;IT1=1;

}
//定时器T0初始化子程序
void Init_Timer0(void)
{
 TMOD |= 0x01;          //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响                     
 EA=1;            //总中断打开
 ET0=1;           //定时器中断打开
}
//定时器T0中断子程序
void Timer0_isr(void) interrupt 1 
{
 TH0=High;
 TL0=Low;
 SPK=!SPK;
}
//主函数
void main (void)
{
  unsigned char num,k,i;
  Init_EX();                 
  Init_Timer0();    //初始化定时器0,主要用于数码管动态扫描
  SPK=0;                        //在未按键时,喇叭低电平,防止长期高电平损坏喇叭         
  while (1)
  {
   /* 按键播音 */
   switch(KeyPort)          //对按键进行处理
                {
                 case 0xfe:num= 1;temp=1;delayms(2000);break;
                 case 0xfd:num= 2;temp=1;delayms(2000);break;
                 case 0xfb:num= 3;temp=1;delayms(2000);break;
                 case 0xf7:num= 4;temp=1;delayms(2000);break;
                 case 0xef:num= 5;temp=1;delayms(2000);break;
                 case 0xdf:num= 6;temp=1;delayms(2000);break;
                 case 0xbf:num= 7;temp=1;delayms(2000);break;
                 case 0x7f:num= 8;temp=1;delayms(2000);break;      //分别对应不用的音调
                 default:num= 0;temp=0;delayms(2000);break;
                }
delayms(20000);
    P1 = KeyPort;
    if(num==0)
    {
       TR0=0;
       SPK=0;   //在未按键时,喇叭低电平,防止长期高电平损坏喇叭
          }
    else 
    {
            High=freq[num-1][1];
            Low =freq[num-1][0];
            TR0=1;
          }
/* 按键播音存储 */

if(temp==1) //标志位,如果标志位为1,则说明有按键被按下
{
temp=0; //将标识位归零
song3[t1++]=num; //将数据存入song3[]数组
}


/* 天空之城按键播音 */
     if(playSongKey==0||count==0)        //如果播放音乐按键被按下
   {
     delayms(10);
     if(playSongKey==0||count==0)
     {
       i=0;
    
       while((i<1000))
            {
                 while(flag);  //暂停播放键
 if(count==1)break;
t=MUSIC[i];         
            k=MUSIC[i]+7*MUSIC[i+1]-1;//去音符振荡频率所需数据
            High=FREQH[k];
            Low=FREQL[k];
            Time=MUSIC[i+2];          //节拍时长
            i=i+3;
            if(P0!=0xff)//长按任意8音键退出播放
            {
               delayms(10);
               if(P0!=0xff)
                i=1000;                 
            }            
            PlaySong();  
            }
                 
  TR0=0;
              }
   }
/* 世上只有妈妈好按键播音 */    
    if(playSongKey1==0||count==1)        //如果播放音乐按键被按下
   {
     delayms(10);
     if(playSongKey1==0||count==1)
     {
       i=0;
    
       while((i<1000))
            {
                  while(flag);  //暂停播放键
  if(count==2)break;
t=MUSIC1[i];         
            k=MUSIC1[i]+7*MUSIC1[i+1]-1;//去音符振荡频率所需数据
            High=FREQH[k];
            Low=FREQL[k];
            Time=MUSIC1[i+2];          //节拍时长
            i=i+3;
            if(P0!=0xff)//长按任意8音键退出播放
            {
               delayms(10);
               if(P0!=0xff)
                i=1000;                 
            }            
            PlaySong();  
            }
                 
  TR0=0;
              }
   }

/* 中华人民共和国国歌按键播音 */
if(playSongKey2==0||count==2)        //如果播放音乐按键被按下
   {
     delayms(10);
     if(playSongKey2==0||count==2)
     {
       i=0;
    
       while((i<1000))
            {
                 while(flag);  //暂停播放键
 if(count==3)break;
t=MUSIC2[i];         
            k=MUSIC2[i]+7*MUSIC2[i+1]-1;//去音符振荡频率所需数据
            High=FREQH[k];
            Low=FREQL[k];
            Time=MUSIC2[i+2];          //节拍时长
            i=i+3;
            if(P0!=0xff)//长按任意8音键退出播放
            {
               delayms(10);
               if(P0!=0xff)
                i=1000;                 
            }            
            PlaySong();  
            }
                 
  TR0=0;
              }
   }




/* 回放键 */
   if(keybofang==0) //回放键
{
   
delayms(10);
while(!keybofang); //检测回放键是否被按下
song3[t1++]=30;
  t1=0;
while(song3[i]!=30) //进入while循环。
{
                   High=freq[song3[i]-1][1];
                   Low =freq[song3[i]-1][0];
                   TR0=1;
  delayms(220);
  i++;
  TR0=0;
  delayms(220);
            }    
 
}
 } 
 }
void E0()interrupt 0 //外部中断0作为暂停/播放键
{
   
if(tingzhi==0);
{
delayms(5);
if(tingzhi==0)
{
  flag=~flag;
 
}
}

}




void E1()interrupt 2 //外部中断1作为切换键
{
   
if(qiehuan==0);
{
delayms(5);
if(qiehuan==0)
{
  count++;
  if(count==5)count=0;
 
}
}

}

路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)

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

Powered by 单片机教程网

返回顶部