找回密码
 立即注册

QQ登录

只需一步,快速开始

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

求单片机音乐彩灯怎么加入按键奏乐程序

[复制链接]
跳转到指定楼层
楼主
ID:339722 发表于 2018-5-28 16:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
原程序如下
#include <reg52.h>
#define uchar unsigned char
#define uint  unsigned int
sbit duan=P2^6;
sbit key1=P3^2;//按key1可切换花样
sbit key2=P3^3;//按key2可切换歌曲
sbit fm=P3^7;//蜂鸣器连续的IO口
sbit P34=P3^4;//矩阵键盘的一列
uchar code huayang1[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,
                                                0xfd,0xfb,0xf7,0xef,0xdf,0xbf};//花样1
uchar code huayang2[]={0x7f,0xfe,0xbf,0xfd,0xdf,0xfb,0xef,0xf7,
                                                0xef,0xfb,0xdf,0xfd,0xbf,0xfe};//花样2
uchar code huayang3[]={0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x0,
                                                0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};
char code huayang4[]={ 0x55,0xaa,0xcc,0x33,0x99,0x66,0x0f,0xf0};
uchar count1;//花样标志       
uchar count2;//歌曲标志       
uchar timeh,timel,i;
//================简谱====================
//编程规则:字节高位是简谱,低位是持续时间,
//代表多少个十六分音符
//1-7代表中央C调,8-E代表高八度,0代表停顿
//最后的0是结束标志
uchar code lzlh[]={         //两只老虎
0x14,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,
        0x14,0x54,0x18,
        0x14,0x54,0x18,
        0xFF         //歌曲结束标志
};
uchar code sb[]={ //送别
0x54,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
};
uchar code mlh[]={ //茉莉花
0x31,0x21,0x31,0x51,0x61,0x51,0x81,0x61,
        0x51,0x31,0x54,0x62,0x82,0x91,0x81,0x58,
                0x51,0x31,0x54,0x62,0x82,0x91,0xA1,0x91,
                0x61,0x52,0x52,0x22,0x31,0x51,0x31,0x21,0x11,0xD1,0x16,
                0x31,0x21,0x12,0x23,0x31,0x52,0x61,0x81,
                0x62,0x52,0x51,0x31,0x22,
                0x31,0x51,0x31,0x21,0x11,0x21,0xD4,0x12,
                0x23,0x31,0x11,0xD1,0x11,0xD1,0xC6,
                0x31,0x21,0x12,0x23,0x31,0x52,0x61,0x81,
                0x62,0x52,0x51,0x31,0x22,
                0x31,0x51,0x31,0x21,0x11,0x21,0xD4,0x12,
                0x23,0x31,0x11,0xD1,0x11,0xD1,0xC6,
                0xFF
};
uchar code xxx[]={ //小星星
0x12,0x12,0x52,0x52,0x62,0x62,0x54,0x42,
        0x42,0x32,0x32,0x22,0x21,0x14,
                0x52,0x52,0x42,0x42,0x32,0x32,0x24,0x52,
                0x52,0x42,0x42,0x32,0x32,0x24,
                0x12,0x12,0x52,0x52,0x62,0x62,0x64,0x42,
                0x32,0x32,0x22,0x22,0x14,
                0xFF
};
//==============简谱音调对应的定时器初值=======
//适合11.0592M的晶振
uchar code cuzhi[]={
         0xff,0xff,//占位
         0xFC,0x8E,//中央C调1-7
         0xFC,0xED,       
         0xFD,0x43,       
         0xFD,0x6A,       
         0xFD,0xB3,       
         0xFD,0xF3,       
         0xFE,0x2D,
         0xFE,0x47,        //高八度1-7          
         0xFE,0x76,
         0xFE,0xA1,
         0xFE,0xC7,       
         0xFE,0xD9,
         0xFE,0xF9,
         0xFF,0x16
         };
uchar yinyue[]={0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0x0,0x0};
//将音调转化为对应的LED样式
void delay1(uint z);        //延时1MS
void delay(uint z);        //延时165MS,即十六分音符
void song();
main()
{        uchar x;
        count1=0;//流水灯无花样
        count2=1;//唱第一首歌
        P34=0;//选取矩阵键盘的一列
        EA=1;//开总中断
        EX0=1;//开外部中断0
        IT0=1;//外部中断0下降沿触发方式
        EX1=1;//开外部中断1
        IT1=1;//外部中断1下降沿触发方式

        TMOD=0x01;//定时器0工作在方式1
        TH0=0;
        TL0=0;
        ET0=1;
       
        while(1)
        {
                if(count1!=0)
                {
                        switch(count1)
                        {
                                case 1:
                                        for(x=0;x<14;x++)
                                        {
                                                duan=1;
                                                P2=huayang1[x];
                                                fm=1;
                                                delay1(300);
                                                duan=0;
                                                if(count1!=1)
                                                        break;       
                                        }
                                break;
                                case 2:
                                        for(x=0;x<14;x++)
                                        {
                                                duan=1;
                                                P2=huayang2[x];
                                                fm=1;
                                                delay1(300);
                                                duan=0;
                                                if(count1!=2)
                                                        break;       
                                        }
                                break;
                                case 3:
                                        for(x=0;x<16;x++)
                                        {
                                                duan=1;
                                                P2=huayang3[x];
                                                fm=1;
                                                delay1(300);
                                                duan=0;
                                                if(count1!=3)
                                                        break;       
                                        }
                                break;
                                case 4:
                                        for(x=0;x<8;x++)
                                        {
                                                duan=1;
                                                P2=huayang4[x];
                                                fm=1;
                                                delay1(300);
                                                duan=0;
                                                if(count1!=4)
                                                        break;       
                                        }
                                break;
                        }
                }
                else
                {
                        song();
                        delay1(1000);
                }
        }
                                
}
void int0() interrupt 0
{
        EA=0;//关总中断
        delay1(1);//去抖
        if(key1==0)
        {
                count2=0;//不让蜂鸣器唱歌
                TR0=0;
                count1++;
                if(count1==5)
                         count1=1;

        }
        EA=1;//开总中断
}
void int1() interrupt 2
{
        EA=0;//关总中断
        delay1(1);//去抖
        if(key2==0)
        {
                count1=0;//流水灯无花样
                TR0=1;
                i=0;//从头开始唱
                count2++;
                if(count2==3)
                         count2=1;

        }
        EA=1;//开总中断
}
void timer0() interrupt 1         //用于产生各种音调
{
        TH0=timeh;
        TL0=timel;
        fm=~fm;
}
void song()
{
        uint temp;
        uchar jp;//jp是简谱
        i=0;
        while(1)
        {        if(count2==0)
                {       
                        break;
                }
                if(count2==1)        //选曲
                         temp=lzlh[i];
                if(count2==2)
                        temp=sb[i];
                if(count2==2)
                    temp=mlh[i];
                if(count2==3)
                    temp=xxx[i];
                if(temp==0xff)
                        break;
                       
                jp=temp/16; //取数的高4位
                duan=1;
                P2=yinyue[jp];
                duan=0;
                if(jp!=0)
                {
                timeh=cuzhi[jp*2];
                timel=cuzhi[jp*2+1];
                }
                else
                {
                TR0=0;
                fm=1;//关蜂鸣器
                }
                delay(temp%16); //取数的低4位
                TR0=0;         //唱完一个音停10MS
                fm=1;
                delay1(10);
                TR0=1;
                i++;
        }
        TR0=0;
        fm=1;
       
}
void delay(uint z)        //延时165MS,即十六分音符
{        uint x,y;
        for(x=z;x>0;x--)
                 for(y=19000;y>0;y--);
}

void delay1(uint z)        //延时1MS
{        uint x,y;
        for(x=z;x>0;x--)
                 for(y=112;y>0;y--);
}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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