找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机电子琴功能实现问题 记忆,复读这一步用数组实现不了

[复制链接]
跳转到指定楼层
楼主
ID:775058 发表于 2020-6-10 15:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
随机弹奏曲子时,可以实时记忆,并可复读(重复播放)。这一步用数组实现不了请大神给看看
#include<reg51.h>
#define SMG P0
#define KEY P1                           //定义数码管段码输出
sbit LED =P2^1 ;
sbit SPK =P2^0;
sbit K1= P3^2;     
sbit K2= P3^3;
sbit K3= P3^0;                                  //定义方波输出口

unsigned int tone1,tone2,i;
/*****标准音符表*****/
//用于使定时器初值变化以产生相应频率的定时
unsigned char 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     //音符之间的间隔,只要间隔时间小于65ms时,
                                                        //喇叭不会发出声音,用作拍子之间的短暂停顿   
};


unsigned char 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代表不发声,即停顿;数字即为音调
                                   };


unsigned char 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表各音调的延时
unsigned char code button[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
unsigned char code dis[]={0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0xff};
unsigned char code yindiao[]={1,2,3,4,5,6,7,8};
unsigned char tanzou_tone[30];
unsigned char tanzou_beat[30];

/*****15ms延时子程序,用于节拍*****/
void delay(void)
{
       unsigned char n=15;
       while(n--)
       {
              unsigned char i;
              for(i=0;i<125;i++);
       }
}

/*****定时器0初始化*****/
void initTimer(void)
{
      TMOD=0x01;           //定时器0,工作方式1;定时器1,工作方式1
      TH0=tone1;
      TL0=tone2;
}

/*****定时器0中断服务程序*****/
void timer0(void) interrupt 1
{
      TH0=tone1;
      TL0=tone2;
      SPK=~SPK;                           //取反,以产生方波
}

/*****演奏子程序1*****/
void play1(void)
{                 
       unsigned char m=0;
       unsigned char s;   
       unsigned char a=1;
       while(1)
       {
              EA=0;
              LED=0;
              a=shengri_tone[m];            //取音符
              SMG=dis[a-1];
              s=shengri_beat[m];           //取节拍
              tone1=yinfu[2*a-2];                           
              tone2=yinfu[2*a-1];                           
              EA=1;
              while(s--)
              {                           
                           
                     delay();
              }
                                         
             if((!K1)||(!K2))   //发现按键,立即退出播放
            {
              EA=0;
                  SPK=0;
                  SMG=0xff;
                  m=34;                                                                                                                      //改过已
              return;
            }
            else
              LED=1;
              m++;
              if(m>=33) return;      //数值是shengri相关表中的元素数量
           }   
               
}
void play2(void)
{                 
       unsigned char m=0;
       unsigned char s;   
       unsigned char a=1;
       while(1)
       {
              EA=0;
              LED=0;
              a=tanzou_tone[m];            //取音符
              SMG=dis[a-1];
              s=tanzou_beat[m];           //取节拍
              tone1=yinfu[2*a-2];                           
              tone2=yinfu[2*a-1];                           
              EA=1;
              while(s--)
              {                           
                           
                     delay();
              }
           if(P1!=0xff)   //发现按键,立即退出播放
            {
              EA=0;
                  SPK=0;
                  SMG=0xff;                                                                                                                     //改过已
              return;
            }
            else
                        {
              LED=1;
              m++;
              if(m>=29) return;      
            }
          }   
      
}

void Delay_xMs (unsigned int x)//延时函数
{
    unsigned int i,j;
    for(i=0;i<x;i++)
     {
       for(j=0;j<3;j++);
     }
}

void Button_Scan(void)
{
    i=0;
    P1=0xff;
    P3=0xff;
        if(KEY==button[0])
        {
          Delay_xMs(10);
           if(KEY==button[0])
           {
              tone1=0xfb;
                  tone2=0xe9;
                  SMG=dis[0];
                  EA=1;
           }
        }
        if(KEY==button[1])
        {
          Delay_xMs(10);
           if(KEY==button[1])
           {
              tone1=0xfc;
                  tone2=0x5c;
                  SMG=dis[1];
                   EA=1;
           }
        }
        if(KEY==button[2])
        {
           Delay_xMs(10);
           if(KEY==button[2])
           {
              tone1=0xfc;
                  tone2=0xc1;
                  SMG=dis[2];
                   EA=1;
           }
        }
        if(KEY==button[3])
        {
           Delay_xMs(10);
           if(KEY==button[3])
           {
              tone1=0xfc;
                  tone2=0xef;
                  SMG=dis[3];                 
                   EA=1;
           }
        }
        if(KEY==button[4])
        {
          Delay_xMs(10);
           if(KEY==button[4])
           {
             tone1=0xfd;
                 tone2=0x45;
                  SMG=dis[4];                  
                   EA=1;
           }
        }
        if(KEY==button[5])
        {
          Delay_xMs(10);
           if(KEY==button[5])
           {
              tone1=0xfd;
                  tone2=0x92;
                  SMG=dis[5];
                   EA=1;
           }
        }
        if(KEY==button[6])
        {
          Delay_xMs(10);
           if(KEY==button[6])
           {
              tone1=0xfd;
                  tone2=0xd0;
                  SMG=dis[6];
                   EA=1;
           }
        }
        if(KEY==button[7])
        {
          Delay_xMs(10);
           if(KEY==button[7])
           {
              tone1=0xfd;
                  tone2=0xee;
                  SMG=dis[7];
                   EA=1;
           }
         
        }
        if(KEY==0xff)
        {
           Delay_xMs(10);
           if(KEY==0xff)
           {
             EA=0;
                 SPK=0;
                 SMG=0xff;
           }
        }
         switch(P1)
         {
              case 0xfe:
                          while(KEY!=0xfe);
                          tanzou_tone[i++]=yindiao[0];
                      tanzou_beat[i++]=25;
                          break;
                          case 0xfd:
                           while(KEY!=0xfd);
                          tanzou_tone[i++]=yindiao[1];
                      tanzou_beat[i++]=25;
                          break;
                          case 0xfb:
                           while(KEY!=0xfb);
                          tanzou_tone[i++]=yindiao[2];
                      tanzou_beat[i++]=25;
                          break;
                          case 0xf7:
                           while(KEY!=0xf7);
                          tanzou_tone[i++]=yindiao[3];
                      tanzou_beat[i++]=25;
                          break;
                          case 0xef:
                           while(KEY!=0xef);
                          tanzou_tone[i++]=yindiao[4];
                      tanzou_beat[i++]=25;
                          break;
                          case 0xdf:
                           while(KEY!=0xdf);
                          tanzou_tone[i++]=yindiao[5];
                      tanzou_beat[i++]=25;
                          break;
                          case 0xbf:
                           while(KEY!=0xbf);
                          tanzou_tone[i++]=yindiao[6];
                      tanzou_beat[i++]=25;
                          break;
                          case 0x7f:
                           while(KEY!=0x7f);
                          tanzou_tone[i++]=yindiao[7];
                      tanzou_beat[i++]=25;
                          break;
         }
         switch(P3)
     {
              case 0xfb:play1();break;
                          case 0xfe:play2();break;
     }
}
void main(void)
{
       initTimer();
       SMG=dis[8];
       TR0=1;
       ET0=1;
       SPK=0;
       while(1)
       {
        Button_Scan();      
       }
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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