找回密码
 立即注册

QQ登录

只需一步,快速开始

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

求51单片机电子琴类作品

[复制链接]
跳转到指定楼层
楼主
求51单片机电子琴类作品
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:99130 发表于 2016-6-24 15:17 | 只看该作者
回复

使用道具 举报

板凳
ID:99130 发表于 2016-6-24 15:18 | 只看该作者
#ifndef _MAIN_H_
#define _MAIN_H_

#define ledDB P0        //led显示端口
#define thesongMAX  8   //总计X首歌

#include<reg52.h>


/********************************************
                 定义各口
*********************************************/
sbit BUZZ = P2^0;      //蜂鸣器连续的IO口
sbit led0 = P0^0;                   //各LED小灯
sbit led1 = P0^1;
sbit led2 = P0^2;
sbit led3 = P0^3;
sbit led4 = P0^4;
sbit led5 = P0^5;
sbit led6 = P0^6;
sbit led7 = P0^7;
sbit ledF = P3^7;     //功能指示灯(处于演奏状态时亮
sbit key0 = P1^0;                        //各按键
sbit key1 = P1^1;
sbit key2 = P1^2;
sbit key3 = P1^3;
sbit key4 = P1^4;
sbit key5 = P1^5;
sbit key6 = P1^6;
sbit key7 = P1^7;
sbit keyF = P3^2;                        //功能切换键——外中断0端口

/********************************************
                 频率初值表
*********************************************/
unsigned char code chuzhi[]={
  0xFF,0xFF,                //                            low                      mid                   high
        0xFC,0x44,                //1    ##  5 6 7  1 2 3 4 5 6 7  1 2 3
        0xFC,0xAC,                //2                 ##         D C B  1 2 3 4 5 6 7  8 9 A
        0xFD,0x09,                //3
        0xFD,0x34,                //4
        0xFD,0x82,                //5
        0xFD,0xC8,                //6
        0xFE,0x06,                //7
        0xFE,0x22,                //8 --high 1         N = 470;
        0xFE,0x56,                //9 --hign 2         N = 440;
        0xFE,0x85,    //A --hign 3         N = 410;
        0xFC,0x0C,                //B---low  7         N = 1012
        0xFB,0x90,    //C --low  6
        0xFB,0x04,    //D --low  5
        0xFA,0x15                  //E --low  3
};

unsigned char T0TH = 0;    //T0定时器重载值,用以控制频率
unsigned char T0TL = 0;
bit func = 0;    //功能模式:0-弹奏;1-播放  
int yinma = 0;   //音码,高4为音调,低4为节拍
char thesong = 0;  //正在播放的曲子

void LedShowJiePai();
void InitSys();
void Delay1ms(int cnt);



#endif
#ifndef _MUSIC_H_
#define _MUSIC_H_

//高4位为音调,低四位为节拍
/********************************************
                    歌曲(C调)
*********************************************/
unsigned char code song0[]={                  //两只老虎
  0x08,0x14,0x24,0x34,0x14,0x14,0x24,0x34,0x14,
        0x34,0x44,0x58,0x34,0x44,0x58,
        0x53,0x61,0x53,0x41,0x34,0x14,
        0x53,0x61,0x53,0x41,0x34,0x14,                 //16--1
        0x14,0x54,0x18,                                                 //8 --2
        0x14,0x54,0x18,                                                 //4 --4
        0xFF          //歌曲结束标志
};
unsigned char code song1[]={                  //送别
  0x08,0x54,0x32,0x52,0x88,0x64,0x84,0x58,
        0x54,0x12,0x22,0x34,0x22,0x12,0x28,0x04,0x04,
        0x54,0x32,0x52,0x86,0x72,0x64,0x84,0x58,
        0x54,0x22,0x32,0x46,0xB2,0x18,0x04,0x04,
        0x64,0x84,0x88,0x74,0x62,0x72,0x88,
        0x62,0x72,0x82,0x62,0x62,0x52,0x32,0x12,0x28,0x04,0x04,
        0x54,0x32,0x52,0x86,0x72,0x64,0x84,0x58,
        0x54,0x22,0x32,0x46,0xB2,0x18,0x04,0x04,
        0xFF
};
unsigned char code song2[]={                         //数鸭子
  0x08,0x34,0x14,0x32,0x32,0x14,0x32,0x32,0x52,0x62,0x54,0x04,
        0x62,0x62,0x62,0x52,0x42,0x42,0x44,
        0x22,0x32,0x22,0x12,0x22,0x04,
        0x34,0x12,0x02,0x34,0x12,0x02,0x32,0x32,0x52,0x62,0x64,0x04,
        0x84,0x52,0x52,0x64,0x34,0x22,0x12,0x22,0x32,0x58,
        0x84,0x52,0x52,0x64,0x34,0x22,0x12,0x22,0x32,0x18,  //第二遍
        0xFF
};
unsigned char code song3[]={                          //喜欢你
  0x08,0x23,0x21,0x22,0x32,0x22,0x12,0xd2,0x12,0x12,0xb4,0xc1,0xe1,0xe6,0x02,
        0x23,0x21,0x22,0x32,0x22,0x12,0xd2,0x12,0x12,0xb4,0x11,0xb1,0xc4,
        0xc2,0x12,0x32,0x22,0x22,0x11,0x21,0x24,0xc2,0x12,0x32,0x22,0x22,0x12,0x28,  
        0x04,0x23,0x21,0x22,0x32,0x22,0x12,0xd2,0x12,0x12,0xb4,0xc1,0xe1,0xe6,0x02,         //secondly
        0x23,0x21,0x22,0x32,0x22,0x12,0xd2,0x12,0x12,0xb4,0x11,0xb1,0xc4,
        0xc2,0x12,0x32,0x22,0x22,0x11,0x21,0x24,0xc2,0x12,0x32,0x22,0x22,0x12,0x28,
        0x04,0x34,0x31,0x21,0x12,0x18,0x12,0x22,0x12,0xB2,0xC8,                                                //high up
        0x12,0x22,0x12,0xB2,0xC8,0xB4,0x14,0x28,0x34,0X31,0x21,0x12,0x18,0x12,0x22,0x12,0xB2,0xC8,
        0x12,0x22,0x12,0xB2,0xC8,0xB4,0x14,0x28,0x14,0xB4,0x1B,0X04,
        0xFF  
};
unsigned char code song4[]={                         //哈巴狗
  0x08,0x12,0x12,0x12,0x22,0x38,
        0x32,0x32,0x32,0x42,0x58,
        0x62,0x62,0x52,0x42,0x38,
        0x52,0x52,0x22,0x32,0x18,
        0XFF
};
unsigned char code song5[]={                                //幸福拍手歌
  0x08,0XD3,0XD1,0X13,0X11,0X13,0X11,0X13,0X11,0XB3,0X11,0X24,0XA3,0X01,0XA3,0X01,
        0XD3,0XD1,0X23,0X21,0X23,0X21,0X23,0X21,0X13,0X21,0X34,0XA3,0X01,0XA3,0X01,
        0X33,0X31,0X33,0X31,0X34,0X23,0X31,0X44,0X33,0X21,0X14,0XB3,0X11,
        0X24,0X23,0X11,0XB3,0XD1,0XC3,0XB1,0X14,0XA3,0X01,0XA3,0X01,
        0X04,0XD3,0XD1,0X13,0X11,0X13,0X11,0X13,0X11,0XB3,0X11,0X24,0XA3,0X01,0XA3,0X01,
        0XD3,0XD1,0X23,0X21,0X23,0X21,0X23,0X21,0X13,0X21,0X34,0XA3,0X01,0XA3,0X01,
        0X33,0X31,0X33,0X31,0X34,0X23,0X31,0X44,0X33,0X21,0X14,0XB3,0X11,
        0X24,0X23,0X11,0XB3,0XD1,0XC3,0XB1,0X14,0XA3,0X01,0XA3,0X01,
        0XFF
};
unsigned char code song6[]={                                //龙的传人
  0x08,0X64,0X72,0X82,0X94,0XA2,0X92,0X84,0X82,0X72,0X68,
        0X64,0X72,0X82,0X94,0XA2,0X92,0X82,0X72,0X82,0X92,0XA8,
        0X64,0X72,0X82,0X94,0XA2,0X92,0X82,0X72,0X82,0X72,0X68,
        0X74,0X74,0X72,0X84,0X72,0X64,0X62,0X52,0X68,
        0XA4,0XA4,0XA4,0X92,0X82,0X94,0X92,0XA2,0X98,
        0X84,0X84,0X84,0X92,0X82,0X74,0X72,0X82,0X78,
        0XA4,0XA4,0XA2,0XA2,0X92,0X82,0X94,0X92,0XA2,0X98,
        0X84,0X84,0X72,0X84,0X72,0X64,0X62,0X52,0X68,                 //secondly
        0X04,0X64,0X72,0X82,0X94,0XA2,0X92,0X84,0X82,0X72,0X68,
        0X64,0X72,0X82,0X94,0XA2,0X92,0X82,0X72,0X82,0X92,0XA8,
        0X64,0X72,0X82,0X94,0XA2,0X92,0X82,0X72,0X82,0X72,0X68,
        0X74,0X74,0X72,0X84,0X72,0X64,0X62,0X52,0X68,
        0XA4,0XA4,0XA4,0X92,0X82,0X94,0X92,0XA2,0X98,
        0X84,0X84,0X84,0X92,0X82,0X74,0X72,0X82,0X78,
        0XA4,0XA4,0XA2,0XA2,0X92,0X82,0X94,0X92,0XA2,0X98,
        0X84,0X84,0X72,0X84,0X72,0X64,0X62,0X52,0X68,
        0XFF
};
unsigned char code song7[]={                                  //上学歌
  0x08,0x12,0x22,0x32,0x12,0x58,0x62,0x62,0x82,0x62,0x58,
        0x62,0x62,0x84,0x52,0x62,0x34,
        0x62,0x52,0x32,0x52,0x32,0x12,0x22,0x32,0x18,    //secondly
        0x04,0x12,0x22,0x32,0x12,0x58,0x62,0x62,0x82,0x62,0x58,
        0x62,0x62,0x84,0x52,0x62,0x34,
        0x62,0x52,0x32,0x52,0x32,0x12,0x22,0x32,0x18,
        0XFF
};
unsigned char code song8[]={                 //一分钱
  0x08,0x54,0x84,0x62,0x82,0x54,0x32,0x52,0x22,0x32,0x54,0x04,
        0x32,0x52,0x62,0x82,0x52,0x62,0x52,0x32,0x52,0x14,0x32,0x24,0x04,
        0x32,0x22,0x12,0x22,0x38,0x62,0x52,0x32,0x52,0x64,0x04,
        0x52,0x82,0x62,0x52,0x32,0x52,0x24,0x52,0x22,0x32,0x22,0x18,
        0xFF
};

#endif
#ifndef _PLAYING_H_
#define _PLAYING_h_

void Playing()  //弹奏
{
        unsigned char keynum = 0;  //按键码
        while(func == 0)
        {
                if(key0 == 0)
                {
                        keynum = 1;
                        led0 = 0;
                }
                else if(key1 == 0)
                {
                        keynum = 2;
                        led1 = 0;
                }
                else if(key2 == 0)
                {
                        keynum = 3;
                        led2 = 0;
                }
                else if(key3 == 0)
                {
                        led3 = 0;
                        keynum = 4;
                        }
                else if(key4 == 0)
                {  
                        led4 = 0;
                        keynum = 5;
                }
                else if(key5 == 0)
                {
                        led5 = 0;
                        keynum = 6;
                }
                else if(key6 == 0)
                {
                        led6 = 0;
                        keynum = 7;
                }
                else if(key7 == 0)
                {
                        led7 = 0;
                        keynum = 8;
                }
                else                //包含没有键按下的情况
                {
                        keynum = 88;
                        ledDB = 0xFF;
                }
                if((keynum>=0)&&(keynum<=8))  //为有效琴键
                {
                        T0TH = chuzhi[keynum*2];
                        T0TL = chuzhi[keynum*2+1];
                        TR0 = 1;
            ET1 = 0;
                        Delay1ms(300);
                        ET1 = 1;
                        ledDB = 0xFF;
                }
                else
                {
                        TR0 = 0;
                        ledDB = 0xFF;
                }
        }
}

void Delay1ms(int cnt)    //延时1ms,12T,11059200Hz
{
  unsigned int i = 0;
        for( ; cnt>0; cnt--)
          for(i=0; i<123; i++);
}

void Delay125ms(unsigned char x)        //延时125MS,即十六分音符
{       
  unsigned int i,  j;
  for( ; x>0; x--)
        {
                for(i=0; i<120; i++)
                {
                  for(j=0; j<123; j++);
                        if((key6==0)||(key7==0)||keyF==0)  //如果在延时过程中有键按下
                        {
                                TR0 = 0;
                                ET1 = 1;    //马上打开定时器1,扫描按键
                        }
                }
        }
}

// 开机流水灯
void StartLedShow()
{
  unsigned int ledshow = 0x01;
  unsigned int stop = 0;
  bit dirt = 0;  //方向
  unsigned int n = 0;  //延时时长控制
  unsigned int ledchar[] = {
   0x81, 0xC3, 0xE7, 0xFF,
         0xFF, 0xE7, 0xC3, 0x81
  };
  while(!stop)
  {
    ledDB = ~ledshow;
                Delay1ms(n);
                if(dirt == 0)                                                //流水灯效果
                {
                        ledshow <<= 1;
                        if(ledshow == 0x80)
                        dirt = 1;
                }
                else
                {
                        ledshow >>= 1;
                        if(ledshow == 0x01)
                        dirt = 0;
                }
                n += 2;
                if((n>100)&&(ledshow==0x01))
                         stop = 1;
  }
  for(n=0;n<8;n++)
  {
    ledDB = ~ledchar[n];
          Delay125ms(1);
  }
  ledDB = 0xFF;
}

#endif
#ifndef _SINGING_H_
#define _SINGING_H_

void Singing()  //播放
{
        int jiepai = 0;  //节拍
  unsigned char yindiao = 0;  //音调
        unsigned char yinmatemp = 0;  //要处理的音码
  while(func == 1)  //循环播放
        {
                switch(thesong)
                {
                        case 0: yinmatemp = song0[yinma]; break;
                        case 1: yinmatemp = song1[yinma]; break;
                        case 2: yinmatemp = song2[yinma]; break;
                        case 3: yinmatemp = song3[yinma]; break;
                        case 4: yinmatemp = song4[yinma]; break;
                        case 5: yinmatemp = song5[yinma]; break;
                        case 6: yinmatemp = song6[yinma]; break;
                        case 7: yinmatemp = song7[yinma]; break;
                        case 8: yinmatemp = song8[yinma]; break;
                        default: break;
                }
                if(yinmatemp != 0xFF)  //不是歌曲结尾
                {
                        yindiao = yinmatemp >> 4;  //取高四位,音调
                        if(yindiao != 0)  //不是休止符
                        {
                                T0TH = chuzhi[yindiao*2];
                                T0TL = chuzhi[yindiao*2+1];
                                TR0 = 1;
                                LedShowJiePai();
                        }
                        else  //是休止符
                        {
                                TR0 = 0;
                                ledDB = 0xFF;
                        }
                        jiepai = yinmatemp & 0x0F;  //取低四位,节拍
                        ET1 = 0;
                        Delay125ms(jiepai);
                        ET1 = 1;
                        TR0 = 0;
                        Delay1ms(10);
                        yinma++;
                }
                else    //是歌曲结尾
                {
                        TR0 = 0;
                        Delay1ms(1000);
                        yinma = 0;
                        thesong++;
                        if(thesong > thesongMAX)
                                thesong = 0;
                }
        }
        TR0 = 0;
}

void LedShowJiePai()  //LED流水灯显示节拍
{
  static unsigned char ledshow = 0x01;  //显示值
        static char dirt = 0;  //方向
        ledDB = ~ledshow;
        if(dirt != 0)
        {
          ledshow >>= 1;
                if(ledshow == 0x01)
                        dirt = 0;
        }
        else
        {
          ledshow <<= 1;
                if(ledshow == 0x80)
                        dirt = 1;
        }
}

#endif
void main()
{
  InitSys();
        StartLedShow();
        while(1)
        {
          if(func != 0)
                        Singing();
                else
                        Playing();
        }
}

void InitSys()
{
  TMOD = 0x11;  //T0和T1都打开,T0控制频率,T1作按键扫描
        TH0 = 0xFC;
        TL0 = 0x66;    //定时1ms
        ET0 = 1;
        TR0 = 0;  //暂不启动
        TH1 = 0xFC;
        TL1 = 0x66;
        ET1 = 1;
        TR1 = 1;  //马上启动
        EA = 1;
        ledF = func;  //当前模式显示灯
}

void T0_interr() interrupt 1
{
  TH0 = T0TH;
        TL0 = T0TL;
        BUZZ =~BUZZ;
}

void T1_interr() interrupt 3   //用作按键扫描
{
  static unsigned char keytemp[] = {0xFF, 0xFF, 0xFF};
        static unsigned char staBF[] = {1, 1, 1};
        static char keysta[] = {0, 0, 0};
        char flagKey = 0;   //按键值
        unsigned char i = 0;
        TH1 = 0xFC;
        TL1 = 0x66;
        keytemp[0] = (keytemp[0] << 1) | keyF;
        if(keytemp[0] == 0x00)    //作模式切换键
        {
          keysta[0] = 0;
        }
        else
                keysta[0] = 1;
       
        if(keysta[0] != staBF[0])
        {
          if(staBF[0] == 1)
                {
                        EA = 0;  //暂时关闭中断
                  func = ~func;
                        ledF = func;
                        if(func == 1)  //如果进入播放模式
                                yinma = 0;  //音码值归0
                        EA = 1;
                }
                staBF[0] = keysta[0];
        }
       
        if(func == 1)  //如果是在播放模式下,才有上一曲和下一曲
        {
          keytemp[1] = (keytemp[1] << 1) | key6;  //作上一曲
                keytemp[2] = (keytemp[2] << 1) | key7;  //作下一曲
                for(i=1; i<3; i++)
                {
                        if(keytemp[i] == 0x00)
                                keysta[i] = 0;
                        else
                                keysta[i] = 1;
          }
                for(i=1; i<3; i++)
                {
                        if(keysta[i] != staBF[i])
                        {
                                if(staBF[i] == 1)
                                {
                                        flagKey = i;
                                }
                                staBF[i] = keysta[i];
                        }
                }
                if(flagKey != 0)  //有按键动作
                {
                  EA = 0;
                        yinma = 0;
                        if(flagKey == 2)  //下一曲
                        {
                          thesong++;
                                if(thesong > thesongMAX)
                                        thesong = 0;
                        }
                        else             //上一曲
                        {
                                thesong--;
                                if(thesong < 0)
                                        thesong = thesongMAX;
                        }
                        flagKey = 0;    //按键值归0
                        Delay1ms(500);
                        EA = 1;
                }
        }
}
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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