• 已解决 73482 个问题
  • 已帮助 5993 位优秀工程师

关于51单片机做一个简易电子琴的问题

sasasasaki 2016-04-23 浏览量:1454

我用51单片机做了一个简易电子琴  仿真的时候没感觉什么

但是用实物调试的时候 声音很奇怪  声音有种抖动的感觉

是不是延时有问题还是什么?程序如下

#include//51单片机头文件
#define uchar unsigned char
#define uint  unsigned int

 
sbit beep=P2^0;//蜂鸣器接口定义
sbit reset=P1^6; //复位
sbit k1=P2^1;
sbit k2=P2^2;
sbit k3=P2^3;
sbit k4=P2^4;
sbit k5=P2^5;
sbit k6=P2^6;
sbit k7=P2^7;
sbit k8=P3^3;
sbit k9=P3^4;
sbit k10=P3^5;
sbit led1=P1^0;
sbit led2=P1^1;
sbit led3=P1^2;
uchar aa,bb;//TH0,TL0
uchar flag=0xff;//模式,0表示音乐,ff表示按键
uchar key=0;//按键代号
uchar cc;
uchar dd=0;
uchar count=2;
uchar code table2[]={    //音乐音符
                        0xfc,0x44,0xfc,0xac,0xfd,0x09,0xfd,0x34,     
                        0xfD,0x82,0xfD,0xc8,0xfd,0x06,0xfb,0x04,     
                        0xfb,0x90,0xfc,0x0c,0xfe,0x22,0xf9,0x5b,
                        0xfa,0x15,  
                    };   

uchar  code smg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,  //共阳数码管段选码表,无小数点
                      0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e} ;
            


uchar code jmszl[]={                                         //曲目二:寂寞沙洲冷
0x12,0x12,0x22,0x32,0x31,0x22,0x21,0x22,
                                                            //自你走后心憔悴
0x21,0x31,0x51,0x52,0x31,0x52,0x61,0x15,0x14,
                                                            //白色油桐风中纷飞
0x51,0x52,0x31,0x52,0x62,0x13,0x11,0x13,0x32,0x28,0x08,0x28,
                                                            //落花似人有情 这个季节
0x31,0x32,0x31,0x32,0x11,0x21,0x51,0x52,0x51,0x52,
                                                            //河畔的风放肆拼命地吹
0x51,0x51,0x31,0x32,0x31,0x32,0x81,0x72,0x63,
                                                            //不断拨弄离人的眼泪

0x62,0x71,0x81,0x72,0x61,0x61,0x52,0x31,0x21,0x32,0x51,0x54,
                                                            //那样浓烈的爱再也无法给
0x22,0x12,0x11,0x12,0x11,0x12,0x12,0x14,0x26,0x32,0x26,
                                                            //伤感一夜一夜
0x32,0x61,0x51,0x51,0x31,0x31,0x21,0x31,0x51,0x61,0x51,0x31,0x51,
                                                            //当记忆的线缠绕过往支离破碎
0x02,0x32,0x81,0x81,0x81,0x81,0x62,0x52,0x34,
                                                            //是慌乱占据了心扉                                                                  
0x31,0x81,0x81,0x81,0x61,0x91,0x82,
                                                            //有花儿伴着蝴蝶
0x51,0x51,0x51,0x51,0x31,0x61,0x53,
                                                            //孤雁可以双飞    
0x21,0x11,0x21,0x11,0x22,0x11,0x21,0x26,
                                                            //夜深人静独徘徊
0x32,0x61,0x51,0x51,0x31,0x31,0x21,0x31,0x51,0x61,0x51,0x31,0x51,0x52,
                                                            //当幸福恋人寄来红色分享喜悦
0x31,0x31,0x81,0x81,0x81,0x61,0x91,0x81,0x61,0x31,0x56,
                                                            //闭上双眼难过头也不敢回
0x32,0x32,0x81,0x81,0x81,0x81,0x91,0x81,0x61,0x81,0x61,0x51,0x31,0x51,0x34,
                                                            //仍然捡尽寒枝不肯安歇微带着后悔
0x21,0x31,0x51,0x31,0x21,0x11,0x61,0x21,0x16,
                                                            //寂寞沙洲我该思念谁
0xff};





uchar code yldbwdx[]={//《月亮代表我的心》
0x02,0x82,0x16,0x32,0x54,0x02,0x52,
0xA6,0x32,0x54,0x02,0x52,0x64,0x74,0xB6,0x64,
0x52,0x5C,0x32,0x22,0x16,0x12,0x14,0x32,0x22,
0x16,0x12,0x14,0x22,0x32,0x26,0x12,0x94,0x22,0x32,
0x2C,0x32,0x52,0x36,0x22,0x14,0x54,0xAC,0x92,0xA2,
0x96,0xA2,0x96,0x82,0x3C,0x54,0x36,0x22,0x14,0x54,
0xAC,0x92,0xA2,0x16,0x12,0x14,0x22,0x32,0x2C,0x02,0x82,0x16,
0x32,0x56,0x12,0xA6,0x32,0x56,0x52,0x66,0x72,0xB6,0x62,0x1C,                                                                            
0xff//结束标志
};
uchar code lzh[]={//《国歌》
0x03,
0x04,0x04,0xc2,0x14,0x12,0x12,0x12,0x11,0x11,0xc2,0xd1,
0xe1,0x14,0x02,0x32,0x12,0x21,0x31,0x52,0x51,0x51,0x54,
0x32,0x31,0x31,0x12,0x11,0x31,0x52,0x51,0x31,0x24,0x24,
0x24,0x64,0x54,0x24,0x34,0x52,0x32,0x21,0x31,0x12,0x11,0x21,0x34,0x04,    
0x52,0x51,0xd1,0x12,0x12,0x32,0x31,0x31,0x52,0x51,0x51,0x22,0x22,0x22,
0xd2,0xd1,0x24,0x22,0xc2,0x14,0x12,0x34,0x32,0x32,0x54,0x54,0x54,0x54,
0x12,0x11,0x31,0x52,0x51,0x51,0x64,0x54,0x32,0x31,0x11,0x52,0x52,0x52,
0x32,0x02,0x12,0x02,0xc4,0x14,0xa2,0xa1,0x11,0x52,0x52,0x52,0x32,0x02,
0x12,0x02,0xc4,0x14,0xc4,0x14,0xc4,0x14,0x14,0x04,0x04,0x04,0x04,0x04,
0xff
};

//按键音符
uchar code table3[]={
                        0xFF,0xFF,0xF8,0x8B,
                        0xF9,0x5B,0xFA,0x14,
                        0xFA,0x66,0xFB,0x03,
                        0xFB,0x8F,0xFC,0x0B,//低音
                        0xFC,0x43,0xFC,0xAB,
                        0xFD,0x08,0xFD,0x33,
                        0xFD,0x81,0xFD,0xC7,
                        0xFE,0x05,//中音
                        0xFE,0x21,0xFE,0x55,
                        0xFE,0x84,0xFE,0X99,
                        0XFE,0xC0,0xFE,0xE3,
                        0xFF,0x02,//高音
                    };
//延时子函数
void delay(uchar i)                  //延时
{
      uchar j,k;
      for(j=0;j          for(k=0;k<148;k++);
}
void delay1(uint z)                    //延时1MS
{    uint x,y;
    for(x=z;x>0;x--)
         for(y=112;y>0;y--);
}



//播放音乐子函数
void music( uchar* musictab )              
{  
    uchar yinfu,jiepai;
    uchar i,j;
    uchar temp;
    temp = count;
    for(i=0;musictab[i]!=0xff;i++)   //判断歌曲是否结束
    {
        yinfu=(musictab[i]>>4);       //提取音调信息
        P0 = smg[yinfu%7];
        jiepai=(musictab[i]&0x0f);   //提取节拍信息
        if(yinfu==0)
            continue;
        aa=table2[(yinfu-1)*2];       //转换成定时器的TH0 值
        bb=table2[(yinfu-1)*2+1];
        TR0=1;
        for(j=jiepai;j>0;--j)      //节拍信息用于控制延时
        {
             delay(250);
        }
        TR0=0;                      //唱完歌 关闭定时器0
        if(flag!=0)
            break;
        if(count!=temp)
            break;
    }
}


//响应按键子函数
void keyscan2()                    
{  
    if(key==0)
          return;
      else
      {
           aa=table3[dd*14+key*2];
           bb=table3[dd*14+key*2+1];
           TR0=1;   
        delay(187);
           TR0=0;   
        key=0;
      }
}
//运行子函数
void yunxing()                 
{
      if(flag==0)  
      {
        led1=1;
        led2=1;
        led3=1;
        switch(count)
        {
            case 1:music(jmszl);  break;
            case 2:music(lzh);  break;
            case 3:music(yldbwdx);  break;
        }
            
    }
      else   
        keyscan2();
}
//按键扫描子函数
void keyscan1()            
{  
    if(k1==1||k2==1||k3==1||k4==1||k5==1||k6==1||k7==1||k8==1||k9==1||k10==1)
        beep=1;
    if(P2==0xfd)            //第一按键按下
     {   
        delay(12);        //延时12MS   
        if(P2==0xfd)         //确定按下  
         {
            key=1;   
            cc=key;
        }
      }  
    else if(P2==0xfb)
     {
        delay(12);
           if(P2==0xfb)   
        {
            key=2;   
            cc=key;
        }
     }
     else if(P2==0xf7)  
    {
           delay(12);  
         if(P2==0xf7)   
        {
            key=3;  
             cc=key;
        }
      }  
    else if(P2==0xef)  
    {
           delay(12);
           if(P2==0xef)
           {
            key=4;  
             cc=key;
        }
    }
    else if(P2==0xdf)
    {
           delay(12);
           if(P2==0xdf)
           {
            key=5;
            cc=key;
        }
      }
       else if(P2==0xbf)
    {
           delay(12);
          if(P2==0xbf)
           {
            key=6;
               cc=key;
        }
      }
     else if(P2==0x7f)
      {
           delay(12);
           if(P2==0x7f)
           {
            key=7;
               cc=key;
        }
      }
      else if(P3==0xf7)              //低音模式键按下
      {   
        delay(12);
          if(P3==0xf7)
           {
            dd=0;
            led1=0;
            led2=1;
            led3=1;
               cc=dd;
        }
      }
     else if(P3==0xef)             //中音模式键按下
     {   
        delay(12);
           if(P3==0xef)
           {
            dd=1;
            led1=1;
            led2=0;
            led3=1;
              cc=dd;
        }
      }
     else if(P3==0xdf)             //高音模式键按下
     {
           delay(12);
           if(P3==0xdf)
           {
            dd=2;
            led1=1;
            led2=1;
            led3=0;  
              cc=dd;
        }
      }
      else   
        return;
}
//数码管显示子函数
void display()                     //显示
{
      switch(cc)
      {
          case 0:    P0=~0x3F;
                break;
           case 1: P0=~0x06;
                break;
           case 2: P0=~0x5B;
                break;
           case 3: P0=~0x4F;
                break;
           case 4: P0=~0x66;
                break;
           case 5: P0=~0x6D;
                break;
           case 6: P0=~0x7D;
                break;
           case 7: P0=~0x07;
                break;
           default:P0=~0x00;
                break;
      }
    switch(dd)
    {
        case 0:    led1=0;led2=1;led3=1;
                break;
           case 1: led1=1;led2=0;led3=1;
                break;
           case 2: led1=1;led2=1;led3=0;
                break;    
    }
}
//主函数                        
void main()
{
      P2=0xff;                     //初始化  
    P0=0xff;
    P3=0xff;
    TMOD=0x01;  
    IT0=1;
    TR0=0;  
    EX0=1;  
    ET0=1;  
    EA=1;
    
    while(1)  
    {   
         keyscan1();                     //按键扫描  
         yunxing();                        //运行   
         display();                      //显示
    }
}
//定时器0中断子函数
void Timer_0() interrupt 1                    //定时器0中断
{  
    TH0=aa;
      TL0=bb;
      beep=~beep;
    if(!reset) flag=1;
}
//外部0中断子函数
void INT_0() interrupt 0             //外部中断0
{
  //    flag=~flag;
    flag = 0 ;
    count++;
    if(count>3)
       count= 1;
      if(flag==0)
      {
           cc=8;
           P0=0xff;
      }
}

0 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
所有亮答 数量:7
  • 延时没有问题的,不过你这相当于用PWM了,51这样的方法出PWM是效果不好的

  • 先调延时,看看效果,如果效果没改善,再考虑加电容滤波。

  • 代码这么长,看着都头晕了……

  • 仿真与实际差距有的时候会非常大

  • 建议用Code编辑框贴代码,,,,

  • 大神们,这个程序有问题吧,我试了一下不能用,改了一些后就是无法实现播放音乐啊。那三首歌没用啊,求大神改个完善的程序照顾照顾小白啊

相关问题

问题达人换一批

关于51单片机做一个简易电子琴的问题