找回密码
 立即注册

QQ登录

只需一步,快速开始

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

电子琴设计代码

[复制链接]
跳转到指定楼层
楼主
ID:124982 发表于 2016-6-3 22:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <reg51.h>
sbit speaker = P0^0;

sbit K0=P2^0;
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 green=P0^2;
sbit yello=P0^3;
sbit red=P0^4;
unsigned char timer0h, timer0l, time,YG=0,j,k,l=-1;
unsigned long i;
//--------------------------------------

                                        // 频率-半周期数据表 高八位 本软件共保存了四个八度的28个频率数据
unsigned  char code Hmusic[32] = {
                                                                0xCC,0xF2, 0xF3, 0xF5, 0xF5, 0xF6, 0xF7, 0xF8,          //低音1234567
                                                                0xCC,0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC,          //1,2,3,4,5,6,7,i
                                                                0xCC,0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE,          //高音 234567
                                                                0xCC,0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF           //超高音 1234567
                                                             };         

                                        // 频率-半周期数据表 低八位
unsigned  char code Lmusic[32] = {
                                                                0xCC,0x42, 0xC1, 0x17, 0xB6, 0xD0, 0xD1, 0xB6,          //低音1234567
                                                                0xCC,0x21, 0xE1, 0x8C, 0xD8, 0x68, 0xE9, 0x5B,          //1,2,3,4,5,6,7,i
                                                                0xCC,0x8F, 0xEE, 0x44, 0x6B, 0xB4, 0xF4, 0x2D,          //高音 234567
                                                                0xCC,0x47, 0x77, 0xA2, 0xB6, 0xDA, 0xFA, 0x16           //超高音 1234567
                                                                };

unsigned  char code deng[13]={2
                                                        0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD
                                                          };
                                                                                                                               
void delay(unsigned char t) //延时程序,控制发音的时间长度
{
        unsigned char t1;
        unsigned long t2;
        for(t1 = 0; t1 < t; t1++) //双重循环, 共延时t个半拍
        for(t2 = 0; t2 < 3000; t2++); //延时期间, 可进入T0中断去发音
        TR0 = 0; //关闭T0, 停止发音
}  
void delay1(unsigned int T) //延时程序,控制发音的时间长度
{
        while(T--);
}
                                                        //一个音符有三个数字。前为第几个音、中为第几个八度、后为时长(以半拍为单位)。
                                                        //6, 2, 3 分别代表:6, 中音, 3个半拍;
                                                        //5, 2, 1 分别代表:5, 中音, 1个半拍;
                                                        //3, 2, 2 分别代表:3, 中音, 2个半拍;
                                                        //5, 2, 2 分别代表:5, 中音, 2个半拍;
                                                        //1, 3, 2 分别代表:1, 高音, 2个半拍;
///////////////////////////////////世上只有妈妈好////////////////////////////////////////////
unsigned char code sszymmh[] ={
                                                                6, 2, 3, 5, 2, 1, 3, 2, 2, 5, 2, 2, 1, 3, 2, 6, 2, 1, 5, 2,1,
                                                                6, 2, 4, 3, 2, 2, 5, 2, 1, 6, 2, 1, 5, 2, 2,3, 2, 2, 1, 2, 1,
                                                                6, 1, 1, 5, 2, 1, 3, 2, 1, 2, 2, 4, 2, 2, 3, 3, 2, 1, 5,2, 2,
                                                                5, 2, 1, 6, 2, 1, 3, 2, 2, 2, 2, 2, 1, 2, 4,5,2,6,3,2,2,2,2,2,
                                                                1,2,2,6,1,2,1,2,2,5,1,8,0,0,0
                                                                };
///////////////////////////////////////////新年好/////////////////////////////////////////////////////////
unsigned char code xnh[] ={
                                                   1,2,1,1,2,1,1,2,2,5,1,2,3,2,1,3,2,1,3,2,2,1,2,2,1,2,1,3,2,1,5,2,2,
                                                   5,2,2,4,2,1,3,2,1,2,2,4,2,2,1,3,2,1,4,2,2,4,2,2,3,2,1,2,2,1,3,2,2,
                                                   1,2,2,1,2,1,3,2,1,2,2,2,5,1,2,7,1,1,2,2,1,1,2,4,0,0,0
                                                   };
//////////////////////////////////////外婆的澎湖湾//////////////////////////////////////////////////////
unsigned char code wpdphw[]={
                                                         3,1,2,5,1,2,5,1,2,5,1,2,6,1,1,1,2,3,6,1,2,5,1,2,1,2,2,1,2,2,6,1,2,
                                                         6,1,2,5,1,8,3,2,2,3,2,2,3,2,2,3,2,2,4,2,2,3,2,2,2,2,1,1,2,3,2,2,1,
                                                         2,2,1,2,2,1,2,2,1,2,2,2,3,2,2,2,2,8,3,2,2,3,2,2,3,2,2,3,2,1,3,2,1,
                                                         4,2,2,3,2,2,2,2,1,1,2,3,6,1,2,1,2,2,1,2,2,6,1,2,5,1,8,3,2,2,3,2,2,
                                                         3,2,2,3,2,1,3,2,1,4,2,2,3,2,2,2,2,1,1,2,3,5,1,1,5,1,1,5,1,1,5,1,1,
                                                 2,2,1,1,2,1,7,1,2,1,2,8,3,1,2,5,1,2,5,1,2,5,1,2,6,1,1,1,2,3,6,1,2,
                                                         5,1,2,1,2,2,1,2,1,1,2,1,6,1,2,6,1,2,5,1,8,3,2,2,3,2,2,3,2,2,3,2,2,
                                                         4,2,2,3,2,2,2,2,2,1,2,2,2,2,1,2,2,2,2,2,1,2,2,2,3,2,2,2,2,8,3,2,2,
                                                         3,2,2,3,2,2,3,2,1,3,2,1,4,2,2,3,2,2,2,2,2,1,2,2,6,1,2,1,2,1,1,2,1,
                                                         6,1,2,6,1,2,5,1,8,3,2,2,3,2,2,3,2,2,3,2,2,4,2,2,3,2,2,2,2,2,1,2,2,
                                                         5,1,2,5,1,2,2,2,1,1,2,1,7,1,2,1,2,8,7,1,4,7,1,2,1,2,2,2,2,4,5,1,4,
                                                         1,2,2,5,1,2,1,2,2,2,2,2,3,2,4,1,2,4,4,2,2,4,2,4,3,2,2,2,2,2,1,2,2,
                                                         7,1,2,1,2,2,2,2,6,3,2,2,2,2,8,3,2,6,3,2,2,4,2,4,4,2,3,4,2,1,3,2,3,
                                                         2,2,1,1,2,2,7,1,2,6,2,8,5,1,2,5,1,2,0,1,2,1,2,2,1,2,2,0,1,2,2,2,4,
                                                         1,2,4,2,2,4,1,2,2,2,2,2,3,2,8,5,2,4,4,2,4,3,2,6,1,2,2,7,1,4,1,2,2,
                                                         2,2,2,0,0,0
                                                        };
//////////////////////////////////时间煮雨///////////////////////////////////////////////////////////
unsigned  char code sjzy[]={
                                                        0,1,4,3,2,2,3,2,2,2,2,6,7,1,2,7,1,2,1,2,2,1,2,4,0,1,1,0,1,1,0,1,1,
                                                        3,2,2,3,2,2,2,2,2,1,2,2,2,2,2,5,2,2,5,2,2,3,2,2,3,2,8,0,1,1,0,1,1,
                                                        6,2,2,6,2,2,5,2,4,3,2,2,2,2,2,3,2,4,2,2,4,1,2,8,3,2,4,2,2,2,1,2,2,
                                                        2,2,6,7,1,2,7,1,2,6,1,2,6,1,8,0,1,1,0,1,1,3,2,2,3,2,2,2,2,6,7,1,2,
                                                        7,1,2,1,2,2,1,2,8,0,1,1,0,1,1,3,2,2,3,2,2,2,2,2,1,2,2,2,2,2,5,2,2,
                                                        5,2,2,3,2,2,3,2,8,0,1,2,0,1,1,6,2,2,6,2,2,5,2,4,3,2,2,2,2,2,3,2,4,
                                                        2,2,4,1,2,8,3,2,4,2,2,2,1,2,2,2,2,6,1,2,2,1,2,8,0,1,1,0,1,1,3,2,2,
                                                        5,2,2,6,2,4,1,3,4,7,2,6,5,2,2,3,2,4,0,1,1,1,2,2,1,2,6,6,2,2,6,2,2,
                                                        5,2,2,3,2,2,2,2,2,3,2,8,0,1,1,0,1,1,0,1,1,3,2,2,5,2,2,6,2,4,1,3,4,
                                                        7,2,6,3,2,2,1,3,4,0,1,1,3,2,2,2,2,6,6,2,2,6,2,2,5,2,2,3,2,2,2,2,2,
                                                        1,2,2,1,2,2,1,2,8,0,1,1,1,2,6,6,2,2,6,2,2,5,2,2,3,2,2,2,2,2,2,2,2,
                                                        3,2,2,0,1,2,3,2,2,5,2,2,6,2,6,1,3,2,7,2,4,3,2,4,1,3,4,0,1,1,3,2,2,
                                                        2,2,6,6,2,2,6,2,2,5,2,2,3,2,2,2,2,2,1,2,2,1,2,2,1,2,8,0,1,1,0,1,4,
                                                        3,2,2,5,2,2,6,2,4,1,3,4,7,2,6,3,2,2,2,3,2,1,3,2,0,1,1,3,2,2,2,2,6,
                                                        6,2,2,6,2,2,5,2,2,3,2,4,2,2,1,1,2,1,1,2,2,1,2,8,0,2,2,0,0,0
                                                        };
//////////////////////////////猪八戒背媳妇/////////////////////////////////
unsigned char code zbjbxf[]={
                                                                6,2,4,3,3,3,5,3,1,3,3,2,6,2,2,1,3,4,6,2,1,1,3,1,6,2,1,1,3,1,
                                                                3,3,4,3,3,1,2,3,1,3,3,1,1,3,1,6,2,4,3,3,3,5,3,1,6,3,2,6,3,2,
                                                             6,3,2,3,3,2,5,3,4,3,3,1,5,3,1,3,3,1,5,3,1,6,3,2,6,3,2,6,3,2,
                                                                3,3,2,5,3,4,5,3,2,6,2,2,5,3,2,6,2,2,3,3,1,2,3,1,3,3,1,1,3,4,
                                                                2,3,4,2,3,4,2,3,2,1,3,1,2,3,1,3,3,2,5,3,2,6,3,4,3,4,4,3,3,4,
                                                                3,4,4,3,3,2,3,4,2,3,3,2,3,4,2,3,3,1,2,3,1,3,3,1,1,3,4,2,3,4,
                                                                2,3,4,2,3,2,1,3,1,2,3,1,3,3,2,5,3,2,6,3,8,0,0,0
                                                        };
////////////////////////////////宾克斯的酒///////////////////////////////
unsigned char code bksdj[]={
                                                                3,2,4,5,2,2,5,2,2,5,2,8,6,2,2,5,2,2,3,2,4,5,2,8,3,2,4,5,2,2,
                                                                5,2,2,5,2,8,6,2,2,5,2,2,3,2,4,1,2,8,3,2,4,5,2,2,5,2,2,5,2,8,
                                                                6,2,2,5,2,2,3,2,4,5,2,8,3,2,4,5,2,2,5,2,2,5,2,8,6,2,2,5,2,2,
                                                                3,2,4,1,2,8,5,2,3,3,2,1,2,2,2,1,2,2,6,1,3,7,1,1,1,2,4,5,2,3,
                                                                3,2,1,2,2,2,1,2,2,6,1,3,1,2,1,5,1,4,6,1,3,1,2,1,5,1,4,6,1,3,
                                                                7,1,1,1,2,4,3,2,4,3,2,3,3,2,1,2,2,4,1,2,3,2,2,1,5,2,3,3,2,1,
                                                                2,2,2,1,2,2,6,1,3,7,1,1,1,2,4,5,2,3,3,2,1,2,2,2,1,2,2,6,1,3,
                                                                1,2,1,5,1,4,6,1,3,1,2,1,5,1,4,6,1,3,7,1,1,1,2,4,3,2,4,3,2,3,
                                                                1,2,1,2,2,4,1,2,12,0,0,0
                                                        };

                                                       

void yingao();
void keyscan();
void dupu();  
void song();
void panduan();
void zanting();
void liushui();
void xuange();
void main()
{
        TMOD = 1;                 //置T0定时工作方式1
        ET0 = 1;                 //开T0中断
        EA = 1;                 //开CPU中断
        IT0=1;
        EX0=1;
        while(1)
        {       
                keyscan();
                dupu();
        }
}
       
void ex0_int() interrupt 0
{
        time=0;


}
       
void t0int() interrupt 1 //T0中断程序,控制发音的音调
{
        TR0 = 0;             //先关闭T0
        if(timer0h ==0xcc&&timer0l==0xcc)
        speaker=1;
        else
        speaker = !speaker; //输出方波, 发音
        TH0 = timer0h; //下次的中断时间, 这个时间, 控制音调高低
        TL0 = timer0l;
        TR0 = 1; //启动T0
}

void panduan()
{
        if(YG==1)
        {
                green=0;
                yello=1;
                red=1;
        }
       

        if(YG==2)
        {
                green=1;
                yello=0;
                red=1;
        }

        if(YG==3)
        {
                green=1;
                yello=1;
                red=0;
        }

        if(YG==4)
        {
        red=0;
        green=1;
        yello=0;
        }

       
}

       


void keyscan()
{
                if(!K0)                          //判断按下的是否是按键0
                {
                        delay1(200);                      //消抖
                        if(!K0)                          //再次判断按键0是否确实按下
                        {
                                YG++;                     //如果是LED1亮
                                panduan();
                                while(!K0);                  //等待按键0弹起
                        }
                }
///////////////////////////////////////////////////////////////////////
                if((!K1)&&(YG<=4))                        //判断按下的是否是按键0
                {
                        delay1(200);                      //消抖
                        if(!K1)                          //再次判断按键0是否确实按下
                    {
                            j=1;
                                yingao();                  
                            while(!K1);                  //等待按键0弹起
                                TR0=0;
                    }
           }
/////////////////////////////////////////////////////////////////////
                if((!K2)&&(YG<=4))                           //判断按下的是否是按键0
                {
                        delay1(200);                      //消抖
                        if(!K2)                          //再次判断按键0是否确实按下
                    {
                            j=2;
                                yingao();                  
                            while(!K2);                  //等待按键0弹起
                                TR0=0;
                    }
           }
/////////////////////////////////////////////////////////

                if((!K3)&&(YG<=4))                          //判断按下的是否是按键0
                {
                        delay1(200);                      //消抖
                        if(!K3)                          //再次判断按键0是否确实按下
                    {
                            j=3;
                                yingao();                  
                            while(!K3);                  //等待按键0弹起
                                TR0=0;
                    }
           }
//////////////////////////////////////////////////////////////       
        if((!K4)&&(YG<=4))                          //判断按下的是否是按键0
                {
                        delay1(200);                      //消抖
                        if(!K4)                          //再次判断按键0是否确实按下
                    {
                            j=4;
                                yingao();                  
                            while(!K4);                  //等待按键0弹起
                                TR0=0;
                    }
           }

////////////////////////////////////////////////////////////
        if((!K5)&&(YG<=4))                          //判断按下的是否是按键0
                {
                        delay1(200);                      //消抖
                        if(!K5)                          //再次判断按键0是否确实按下
                    {
                            j=5;
                                yingao();                  
                            while(!K5);                  //等待按键0弹起
                                TR0=0;
                    }
           }
///////////////////////////////////////////////////////////
        if((!K6)&&(YG<=4))                          //判断按下的是否是按键0
                {
                        delay1(200);                      //消抖
                        if(!K6)                          //再次判断按键0是否确实按下
                    {
                            j=6;
                                yingao();                  
                            while(!K6);                  //等待按键0弹起
                                TR0=0;
                    }
           }
////////////////////////////////////////////////////////////////
        if((!K7)&&(YG<=4))                          //判断按下的是否是按键0
                {
                        delay1(200);                      //消抖
                        if(!K7)                          //再次判断按键0是否确实按下
                    {
                            j=7;
                                yingao();                  
                            while(!K7);                  //等待按键0弹起
                                TR0=0;
                    }
           }               
}




void yingao()
{
       
        timer0l=Lmusic[j+8*(YG-1)];
        timer0h=Hmusic[j+8*(YG-1)];
       
        TH0=timer0h;
        TL0=timer0l;
        TR0=1;
       
}

void song() //演奏一个音符
{
        TH0 = timer0h;                 //控制音调
        TL0 = timer0l;
        TR0 = 1;                         //启动T0, 由T0输出方波去发音
        delay(time);                 //控制时间长度
}



void dupu()
{

               
               

                while(YG>4)
                {       
                        green=0;
                        yello=0;
                        red=0;       
                        YG++;
                        if(YG==12)
                        {
                        YG=0;
                        time=0;
                        P0=0X1D;
                        P2=0XFF;
                        }
                        else
                        time=1;
                        delay1(40000);
                        i = 0;
               
                        while(time)
                        {
                                 xuange();
                         
                                //第i个是音符, 第i+1个是第几个八度
                                timer0h = Hmusic[k]; //从数据表中读出频率数值
                                timer0l = Lmusic[k]; //实际上, 是定时的时间长度
                                 //读出时间长度数值
                                i=i+3;
                                song(); //发出一个音符
                                zanting();
                                liushui();
                           }
                }
               
}

void zanting()
{
                if(!K0)                          //判断按下的是否是按键0
                {
                        delay1(200);                      //消抖
                        if(!K0)                          //再次判断按键0是否确实按下
                        {
                                while(!K0);
                                while(1)
                                {
                                        if(!K0)                          //判断按下的是否是按键0
                                        {
                                                delay1(200);                      //消抖
                                                if(!K0)                          //再次判断按键0是否确实按下
                                                {
                                                        while(!K0);
                                                        break;      
                                                }
                                        }

                                }
                        }
                }
}

void liushui()
{
       
        l++;
        if(l==13)
        l=0;
        P2=deng[l];
       

}

void xuange()
{
                if(YG==6)
                                {
                                        k = sszymmh[i] + 8 * (sszymmh[i+1] - 1);
                                        time = sszymmh[i + 2];
                                }
                                if(YG==7)
                                {
                                        k = xnh[i] + 8 * (xnh[i+1] - 1);
                                        time = xnh[i + 2];
                                }
                                        if(YG==8)
                                {
                                        k = zbjbxf[i] + 8 * (zbjbxf[i+1] - 1);
                                        time = zbjbxf[i + 2];
                                }
                                                if(YG==9)
                                {
                                        k =bksdj[i] + 8 * (bksdj[i+1] - 1);
                                        time = bksdj[i + 2];
                                }
                                if(YG==10)
                                {
                                        k = wpdphw[i] + 8 * (wpdphw[i+1] - 1);
                                        time = wpdphw[i + 2];
                                }
                                if(YG==11)
                                {
                                        k = sjzy[i] + 8 * (sjzy[i+1] - 1);
                                        time = sjzy[i + 2];
                                }
}


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:124921 发表于 2016-6-4 10:06 | 只看该作者
先顶一个
回复

使用道具 举报

板凳
ID:260573 发表于 2017-12-12 15:36 | 只看该作者
大神有proteus仿真电路图吗?
回复

使用道具 举报

地板
ID:656121 发表于 2019-12-4 18:14 来自手机 | 只看该作者
能提供一下头文件吗?
回复

使用道具 举报

5#
ID:658466 发表于 2019-12-8 21:38 | 只看该作者
38行多了个字符2,需要删除。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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