51单片机电子琴C代码

#include
#include
#include
#include
#include
#define uchar unsigned char

typedef unsigned char      uint8;                // 无符号8位整型变量
typedef signed   char      int8;                 // 有符号8位整型变量
typedef unsigned short     uint16;               // 无符号16位整型变量
typedef signed   short     int16;                // 有符号16位整型变量
typedef unsigned int       uint32;               // 无符号32位整型变量
typedef signed   int       int32;                // 有符号32位整型变量
typedef float              fp32;                 // 单精度浮点数(32位长度)
typedef double             fp64;                 // 双精度浮点数(64位长度)

sbit row1 = P1 ^ 0;
sbit row2 = P1 ^ 1;
sbit row3 = P1 ^ 2;
 
sbit col1 = P0 ^ 1;
sbit col2 = P0 ^ 2;
sbit col3 = P0 ^ 3;
sbit col4 = P0 ^ 4;
sbit col5 = P0 ^ 5;
sbit col6 = P0 ^ 6;
sbit col7 = P0 ^ 7;


#define uint unsigned int
uchar STH0;      //定时器计数初值
uchar STL0; 
bit FY=0;     //放乐曲时FY=1, 电子琴弹奏时FY=0
uchar Song_Index=0,Tone_Index=0;   //放音乐的参数
uchar k, key;
sbit SPK=P3^7;
sbit LED1=P1^0;
sbit LED2=P1^1;
sbit LED3=P3^4;
sbit LED4=P3^5;
sbit LED5=P3^6;





void Delay(uint16 count)
{
  uint8 i;               
  while(--count != 0)       
    {
     for(i = 0; i < 125; i++);                // ";" 表示空语句,CPU空转。
   }                                // i 从0加到125,在12M晶体下CPU大概耗时1毫秒
}




uint8 KeyDown(void)
{
  col1=0; col2=0; col3=0; col4=0; col5=0; col6=0; col7=0;                      // 列线全部置低
 
  if((row1==0) || (row2==0) || (row3==0))     // 若有任一行线读回状态为低
   {
     Delay(80);                                            // 延时消抖
     if((row1==0) || (row2==0) || (row3==0))  // 再次读行线状态,若有任一行线读回状态为低
       return 1;                // 返回1,表明有键盘按下
     else                    
       return 0;                   // 返回0,表明无键盘按下
  }
  else
    return 0;    
}


uint8 KeyUp(void)
{
  col1=0; col2=0; col3=0; col4=0; col5=0; col6=0; col7=0;                          
  if((row1==1) && (row2==1) && (row3==1))   
   {
     Delay(80);            
     if((row1==1) && (row2==1) && (row3==1))  
       return 1;              
     else
       return 0;           
   }
  else
    return 0;
}



uint8  KeyNum(void)
{
  uint8 KeyTemp;
 
  KeyTemp=0;
  if(KeyDown()==1)                                        
   {
     col1=0; col2=1; col3=1; col4=1; col5=1; col6=1; col7=1;            // 将列线1置低,其他列线置高
     if (row1==0) KeyTemp=1;            // 若行线1读回状态为低,则表明按键1被按下
     if (row2==0) KeyTemp=8;            // 若行线2读回状态为低,则表明按键8被按下
     if (row3==0) KeyTemp=15;           // 若行线3读回状态为低,则表明按键15被按下
    
  col1=1; col2=0; col3=1; col4=1; col5=1; col6=1; col7=1;           
     if (row1==0) KeyTemp=2;            
     if (row2==0) KeyTemp=9;          
     if (row3==0) KeyTemp=16;           
    
     col1=1; col2=1; col3=0; col4=1; col5=1; col6=1; col7=1;    
     if (row1==0) KeyTemp=3;           
     if (row2==0) KeyTemp=10;           
     if (row3==0) KeyTemp=17;         
     
col1=1; col2=1; col3=1; col4=0; col5=1; col6=1; col7=1;    
     if (row1==0) KeyTemp=4;           
     if (row2==0) KeyTemp=11;           
     if (row3==0) KeyTemp=18;          
 
col1=1; col2=1; col3=1; col4=1; col5=0; col6=1; col7=1;   
     if (row1==0) KeyTemp=5;           
     if (row2==0) KeyTemp=12;          
     if (row3==0) KeyTemp=19;        
 
col1=1; col2=1; col3=1; col4=1; col5=1; col6=0; col7=1;  

     if (row1==0) KeyTemp=6;           
     if (row2==0) KeyTemp=13;           
     if (row3==0) KeyTemp=20;           
 
col1=1; col2=1; col3=1; col4=1; col5=1; col6=1; col7=0;    
     if (row1==0) KeyTemp=7;            
     if (row2==0) KeyTemp=14;           
     if (row3==0) KeyTemp=21;       
      
     return KeyTemp;                  
    }
  else
      return 0;           //无按键按下
}



uchar code DSY_CODE[]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07,0x06};
uchar code GE_CODE[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07,
  0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71};
uchar code Song[][100]=               //任意选几首音乐的旋律
{
{5,3,5,3,5,3,1,2,4,3,2,5,5,3,5,3,5,3,1,2,4,3,2,1,2,2,4,4,3,1,5,2,4,3,2,5,5,3,5,3,5,3,1,2,4,3,2,1,-1},  //《粉刷匠》
{1,2,3,4,5,3,1,8,6,4,5,5,3,1,2,3,4,5,3,2,1,2,3,2,5,1,2,3,4,5,3,1,8,6,4,5,3,1,2,3,4,5,3,2,1,2,3,1,1,8,6,4,5,5,1,8,6,4,5,3,1,2,3,4,5,3,2,1,2,3,1,1,-1},//《小红帽》
{1,2,3,1,1,2,3,1,3,4,5,3,4,5,5,6,5,4,3,1,5,6,5,4,3,1,1,5,1,1,5,1,-1},  //《两只老虎》
{5,8,6,8,5,3,5,2,3,5,0,3,5,6,8,5,6,5,3,5,1,3,2,0,3,2,1,2,3,6,5,3,5,6,0,5,8,6,5,3,5,2,5,2,3,2,1,-1},  //《一分钱》
{5,3,5,3,5,3,2,3,5,5,5,3,6,5,3,5,3,2,1,2,3,5,3,2,1,2,3,6,5,6,5,2,3,5,6,5,6,5,2,3,1,-1},  //《丢手绢》
{5,3,5,3,5,6,5,3,6,5,1,1,2,3,5,3,2,0,3,5,5,5,6,5,3,5,5,6,5,8,6,5,1,5,3,2,1,2,3,5,5,2,3,1,10,9,8,6,5,5,6,6,5,6,8,10,8,9,0,5,10,9,8,6,5,5,6,6,5,6,10,9,9,10,9,8,6,5,5,8,6,5,3,2,1,0,2,3,5,5,0,5,6,8,-1},                //《七子之歌-澳门》
{5,6,5,6,5,6,5,5,8,7,6,5,3,5,5,3,4,5,5,3,1,4,3,2,1,2,1,-1},   //《找朋友》
{5,10,9,10,3,8,7,6,6,9,8,9,6,8,9,9,9,9,8,10,10,9,9,5,10,9,10,3,8,7,6,5,6,8,8,8,9,10,9,8,7,8,8,-1},//《感恩的心》
{3,3,4,5,5,4,3,2,1,1,2,3,3,2,2,3,3,4,5,5,4,3,2,1,1,2,3,2,1,1,2,2,3,1,2,3,4,3,1,2,3,4,3,2,1,2,1,3,3,3,4,5,5,4,3,4,2,1,1,2,3,2,1,1,-1},  //《欢乐颂》
{5,8,5,4,3,2,1,1,1,2,3,3,1,3,4,5,5,5,8,5,4,3,5,2,4,3,2,6,5,2,3,1,1,0,5,3,6,8,7,6,7,5,3,9,9,9,8,7,6,8,5,5,5,3,6,8,7,6,7,8,9,5,6,7,8,9,5,8,8,-1}, //《我爱北京天安门》
{3,5,8,5,6,0,6,5,3,3,5,5,3,5,6,8,9,8,5,3,2,5,3,3,3,3,5,8,5,6,0,8,9,8,5,3,5,7,6,0,3,2,3,5,10,9,7,8,3,5,8,3,5,8,5,6,0,8,9,8,5,3,5,7,6,0,3,2,3,5,10,9,7,8,3,5,2,3,5,10,9,9,9,7,8,-1},//《北京欢迎你》
{1,2,3,1,5,6,6,8,6,5,6,6,8,5,6,5,6,5,3,5,3,1,2,3,1,-1},   //《上学歌》
{10,9,9,10,8,0,3,8,6,5,3,5,0,5,5,6,8,8,8,6,8,3,5,5,6,5,3,2,2,0,10,9,9,10,8,0,3,8,6,5,3,5,0,5,5,6,8,8,6,5,6,3,0,3,10,10,10,10,9,6,8,-1},//《当兵的人》
{3,3,5,6,8,8,6,5,5,6,5,3,3,5,6,8,8,6,5,5,6,5,5,5,5,3,5,6,6,5,3,2,3,5,3,2,1,1,2,1,-1},//《茉莉花》
{3,1,3,3,1,3,3,5,6,5,0,6,6,5,5,4,4,4,2,3,2,1,2,0,3,1,0,3,1,0,3,3,5,6,6,0,8,5,5,6,3,2,1,2,3,5,8,5,5,6,3,2,1,2,3,1,-1},//《数鸭子》
{1,1,3,4,5,5,5,3,4,4,4,2,1,3,5,0,1,1,3,4,5,5,5,3,4,4,4,2,1,3,1,0,6,6,4,5,5,5,5,3,4,4,4,2,1,3,5,0,6,6,4,5,5,5,5,3,4,4,4,2,1,3,1,0,-1},//《洋娃娃和小熊跳舞》
};
uchar code Len[][100]=           //上面几首音乐的旋律每个音符对应的节拍       
{
{2,2,2,2,2,2,4,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,2,4,-1}, //《粉刷匠》
{2,2,2,2,4,2,2,4,2,2,2,2,4,2,2,2,2,2,2,2,2,4,4,4,4,2,2,2,2,4,2,2,4,2,2,4,4,2,2,2,2,2,2,2,2,4,4,4,4,4,2,2,2,2,4,4,2,2,4,4,2,2,2,2,2,2,2,2,4,4,4,4,-1}, //《小红帽》
{2,2,2,2,2,2,2,2,2,2,4,2,2,4,2,2,2,2,4,4,2,2,2,2,4,4,2,2,4,2,2,4,2,2,4,-1},  //《两只老虎》
{4,4,2,2,4,2,2,2,2,4,4,2,2,2,2,2,2,2,2,2,4,2,4,4,2,2,2,2,8,2,2,2,2,4,4,2,2,2,2,2,2,4,2,2,2,2,8,-1}, //《一分钱》
{6,2,6,2,2,2,2,2,8,2,4,2,4,4,2,2,2,2,4,4,4,4,2,2,2,2,8,2,2,2,2,2,2,4,2,2,2,2,4,4,8,-1}, //《丢手绢》
{4,2,2,2,6,2,2,2,2,8,4,2,2,4,2,2,4,2,2,8,2,2,2,2,2,4,2,2,2,2,2,8,4,2,2,2,2,4,2,6,2,2,4,16,4,2,1,2,2,4,2,4,2,2,1,2,2,12,2,2,4,2,1,2,2,4,2,4,2,4,2,2,16,4,2,1,2,2,4,4,2,2,2,2,4,4,2,2,8,8,4,2,2,16,-1},  //《七子之歌-澳门》
{2,2,2,2,2,2,4,2,2,2,2,4,4,2,2,2,2,2,2,4,2,2,2,2,2,2,4,-1}, //《找朋友》
{2,4,2,6,2,4,2,6,2,4,2,5,1,1,2,1,1,2,1,1,2,2,4,2,4,2,6,2,4,2,6,2,2,1,1,2,2,2,4,2,2,2,8,-1},//《感恩的心》
{4,4,4,4,4,4,4,4,4,4,4,4,5,2,6,4,4,4,4,4,4,4,4,4,4,4,4,5,2,6,4,4,4,4,4,2,2,4,4,4,2,2,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,4,4,4,4,5,2,6,-1},//《欢乐颂》
{2,2,2,2,2,2,4,2,2,2,2,2,2,2,2,6,6,2,2,2,2,2,2,4,2,2,2,2,4,2,2,6,4,4,5,2,4,4,4,2,2,4,4,2,2,2,2,4,2,2,6,6,5,2,4,4,2,2,2,2,6,2,2,2,2,4,4,6,4,-1},//《我爱北京天安门》
{4,4,2,2,4,2,2,2,2,2,2,6,2,2,2,2,2,2,2,2,2,2,2,2,6,2,2,2,2,4,2,2,2,2,2,2,2,2,4,2,2,2,2,2,2,5,2,8,2,2,8,2,2,2,2,4,2,2,2,2,2,2,2,2,4,2,2,2,2,2,2,5,2,8,2,2,2,2,2,2,6,10,8,4,10,-1},//《北京欢迎你》
{2,2,2,2,6,2,2,2,2,6,2,2,4,2,2,4,2,2,2,2,2,2,2,2,6,-1},//《上学歌》
{6,4,3,2,8,4,4,4,2,2,4,8,4,4,2,2,4,3,2,4,4,6,4,2,2,4,2,2,8,4,6,4,3,2,8,4,4,4,2,2,4,8,4,2,4,2,4,4,4,2,2,4,2,2,2,4,2,4,2,2,8,4,-1},//《当兵的人》
{4,2,2,2,2,2,2,4,2,2,6,4,2,2,2,2,2,2,4,2,2,6,4,4,4,2,2,4,4,6,4,2,2,4,2,2,4,2,2,8,-1},//《茉莉花》
{4,4,2,2,4,2,2,2,2,4,4,2,2,2,2,2,2,4,2,2,2,2,4,4,4,2,2,4,2,2,2,2,2,2,4,4,4,2,2,4,4,2,2,2,2,6,4,2,2,4,4,2,2,2,2,6,-1},//《数鸭子》
{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,-1},//《洋娃娃和小熊跳舞》
};
uint code tab[]=
0,63628,63835,64021,64103,64260,64400,64524,
  64580,64684,64777,64820,64898,64968,65030,
  65058,65110,65157,65178,65217,65252,65283
}; 
void delay1(uint ms)         //播放歌曲时实现节拍的延时函数
{
 uchar t;
 while(ms--) for (t=0;t<120;t++);
}
void delay(void)
{
uchar i;
for (i=300;i>0;i--);
}




void EX0_INT() interrupt 0
  FY=0; LED1=0; LED2=1; STL0=STL0;
}
void EX1_INT() interrupt 2
{
 FY=1; LED1=1; LED2=0;LED3=1;LED4=1;LED5=1;P2=0xff; Tone_Index=-1;Tone_Index++;
                         STH0=(tab[Song[k][Tone_Index]])/256;
                         STL0=(tab[Song[k][Tone_Index]])%6;
}
void time0_int(void) interrupt 1 using 0
{
  TH0 = STH0;
  TL0 = STL0; 
SPK=!SPK; // 反相,产生输出脉冲
if(FY==0)    
{P2=~DSY_CODE[k] ;}
else {if(FY==1) {P2=~GE_CODE[k];}}
}
void main(void)
{ LED1=0;
  LED2=1;
  LED3=1;LED4=1;LED5=1;
  P2=0xff;
  IE=0x87;
  TMOD=0x01;
  IT0=1;
  IT1=1;
  while(1)
   {
if (KeyDown())  
 {
k = KeyNum();  // 调用键盘扫描函数  
  if(FY==0)
{  
       
       STH0 = tab[k]/256;
         STL0 = tab[k]%6; 
       TR0 = 1;   // 开始计数 
              while (KeyUp()==0); // 若没有松开按键,则等待,等待期间弹奏该音符
              TR0 = 0; // 若按键松开,则停止计数,不产生脉冲输出
 }
           else 
              {  
           while (FY==1) 
                  {   
           if (Song[k][Tone_Index]==-1) 
            Tone_Index=0;
                   STH0=(tab[Song[k][Tone_Index]])/256;
                   STL0=(tab[Song[k][Tone_Index]])%6;
            P2=~GE_CODE[Song[k][Tone_Index]] ;
                   TR0 = 1; 
                   delay1(150*Len[k][Tone_Index]);
                   Tone_Index++;
TR0 = 0;
            }
 }
                         if(k>=1&&(k<=7)){LED3=0;LED4=1;LED5=1;}
 else 
 {if(k>=8&&(k<=14)){LED3=1;LED4=0;LED5=1;}
        else
{if (k==0){LED3=1;LED4=1;LED5=1;}
 else
{LED3=1;LED4=1;LED5=0;}} }    
         
              } 
       
  
        }
    }

你可能感兴趣的:(电子开发)