找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机电子琴代码

[复制链接]
跳转到指定楼层
楼主
ID:788227 发表于 2020-6-23 22:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <reg51.h>//头文件的引用
void T0_init();//定义初值
void Key();        //按键扫描函数
void yingyue(); //音乐播放函数
void delay(unsigned char t) ;
void Display();
void Delay_ms(unsigned int t);
sbit beep=P2^7;//定义蜂鸣器
sbit DO=P1^0;//DO音符端口
sbit RE=P1^1;//RE音符端口
sbit MI=P1^2;//MI音符端口
sbit FA=P1^3;//FA音符端口
sbit SO=P1^4;//SO音符端口
sbit LA=P1^5;//LA音符端口
sbit SI=P1^6;//SI音符端口
sbit key1=P2^4;//低音按键功能
sbit key2=P2^5;//中音按键功能
sbit key3=P2^6;//高音按键功能
sbit led_song=P2^2;//音乐播放模式指示灯
sbit led_dz=P2^3;//电子琴模式指示灯
sbit  SW1=P2^0;//控制位选码
sbit  SW2=P2^1;//控制位选码
unsigned char code yinfu_table[]={0X40,0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0-9的段码(共阳)
unsigned char code yindiao_table[]={0X40,0xc0,0xf9,0xa4,0xb0}; //0-4的段码(共阳)
unsigned char time1, time2, time;
unsigned int index=0,j=0;
unsigned char i=0;
unsigned int k=0 ;
//--------------------------------------*********------------------------------------------------
unsigned char Tone_H8[22]={        0X00,
                           0xf8,0xf9,0xfa,0xfa,0xfb,0xfb,0xfc,//低音的DO~SI初值高八位
                           0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfe,//中音的DO~SI初值高八位
                                                   0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff };//高音的DO~SI初值高八位        
unsigned char Tone_L8[22]={0X00,
                         0x44,0xAC,0x09,0x34,0x82,0xC8,0x06, //低音的DO~SI初值低八位
                         0x44,0xac,0x09,0x34,0x82,0xc8,0x06 , // 中音的DO~SI初值低八位
                                                 0x22,0x56,0x85,0x88,0xc1,0xe4,0x02 };//高音的DO~SI初值低八位
code unsigned char song[]={
5,10,9, 10,3,8, 7,6,6, 9,8,9,
6,8,9, 9,9,9,8, 10,10,9, 9,5,10,
9,10,3, 8,7,6, 5,6,8, 8,8,9,
10,9,8, 7,8,8,
-1
};//感恩的心音调
unsigned char len[]={
2,4,2, 6,2,4, 2,6,2, 4,2,5,
1,1,2, 1,1,2, 1,1,2, 2,4,2,
4,2,6, 2,4,2, 6,2,2, 1,1,2,
2,2,4, 2,2,2,8,
-1};//感恩的心节拍
   void main(void)//主函数
{           
        T0_init();//初始化函数调用
                while(1){
        if(i==0){
         led_song=1;
         led_dz=0;  
         Key();//按键扫描函数的调用                 
         Display();
         }         
        if(i==1){
                k++;
        time1=Tone_H8[song[k]];
        time2=Tone_L8[song[k]];
        time=len[k]; //节拍
            led_song=0;
            led_dz=1;
        yingyue();//发出一个音符
           }
            }
        }
  //--------------------------------------*********------------------------------------------------
void Display()//音符音调显示函数
{
        SW1=1;
        SW2=0;
        P0=yinfu_table[(index-1)%7];//显示按键音符
        Delay_ms(10);
        P0=0x00;
        SW1=0;
        SW2=1;
        P0=yindiao_table[(index-1)/7];//显示按键音调
        Delay_ms(10);
        P0=0x00;
}
  //--------------------------------------*********------------------------------------------------

void T0_int(void) interrupt 1 //T0中断程序,控制发音的音符
{
    TH0= Tone_H8[index];
        TL0= Tone_L8[index];
        beep=~beep;
}
void t0int() interrupt 3         //T1中断程序,控制发音的音符
{
    TR1= 1;                    
    TH1 = time1;               
    TL1 = time2;
        beep=~beep;
}
void T0_inter()interrupt 0         //外部中断0程序,控制功能的选择
{        
          i++;
          i=i%2;
         if(i==0) //选择弹奏音乐
         {
           k=0;
         time1=0;
         time2=0;
         time=0;
         }
         if(i==1){         //选择演奏音乐
         TR0=0;
         TR1=1;
         index=0;        
         }
    if(i==100)i=0;
}         
//--------------------------------------*********------------------------------------------------
//中断初始化程序
void T0_init(){
           EA=1; //开总中断
        TMOD=0x11;//在TMOD寄存器中设置T0,T1的工作方式        
        ET1=1;
        ET0=1;
        EX0=1;
        IT0=1;
        PX0=1;
}
//--------------------------------------*********------------------------------------------------
void delay(unsigned char t) //延时程序,控制发音的时间长度
{
    unsigned char t1;
    unsigned long t2;
    for(t1=0;t1<t;t1++)    //双重循环, 共延时t个半拍
    for(t2=0;t2<6000;t2++); //延时期间, 可进入T0中断去发音
    TR1=0;                                          //关闭T0, 停止发音
}
//--------------------------------------*********------------------------------------------------
//延时函数
void yingyue()                      //演奏一个音符
{
    TH1=time1;  //控制音调
    TL1=time2;
    TR1=1; //启动T0, 由T0输出方波去发音
    delay(time); //控制时间长度                                       
}
//--------------------------------------*********------------------------------------------------
void Delay_ms(unsigned int t)                //@12.000MHz
{
        unsigned char i, j, k;
        for(k=0;k<t;k++){
                i = 12;
                j = 169;
                do
                {
                        while (--j);
                } while (--i);
        }
}
//--------------------------------------*********------------------------------------------------
//按键扫描函数
void Key()
{
                if(key1==0)          //低音按键功能
                {
                        Delay_ms(20);
                        if(key1==0)
                {        TR0=0;
                        j=0;
                        }
                 }
                 if(key2==0)           //中音按键功能
                 {
                        Delay_ms(20);
                        if(key2==0)        
                        {TR0=0;
                                j=7;
                        }
                 }
                         if(key3==0)                 //高音按键功能
                        {
                        Delay_ms(20);
                        if(key3==0)
                        {        
                        TR0=0;
                        j=14;
                        }
                 }
                if(P1!=0xFF)
                {
                        Delay_ms(20);
                        switch(P1)
                        {
                                case  0xFE: index=j+1;TR0=1;break;//DO
                                case  0xFD: index=j+2;TR0=1;break;//RE
                                case  0xFB: index=j+3;TR0=1;break;//MI
                                case  0xF7: index=j+4;TR0=1;break;//FA
                                case  0xEF: index=j+5;TR0=1;break;//SO
                                case  0xDF: index=j+6;TR0=1;break;//LA
                                case  0xBF: index=j+7;TR0=1;break;//SI  
                        }
           }
        }

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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