设计电子琴的C语言程序(基于单片机)

#include                           //包含特殊功能寄存器定义的头文件
#include


sbit BUZZER = P1^0;             //定义蜂呜器引脚


sbit KEY1 = P3^0;
sbit KEY2 = P3^1;
sbit KEY3 = P3^2;
sbit KEY4 = P3^3;
sbit KEY5 = P3^4;
sbit KEY6 = P3^5;
sbit KEY7 = P3^6;


sbit KEYSET = P3^7;


//定义595引脚
sbit DS595 = P1^5;
sbit ST595 = P1^6;
sbit SH595 = P1^7;


bit SysMod = 0;                 //系统模式,1为演奏,0为弹奏


unsigned char code SegChar[16]={
    0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 
    0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};


void SendDataTo595(unsigned char Data);
void Output595(void);
    
#include"singing.h"             //包含音乐演奏头文件
#include"playing.h"


/* 主函数:初始化T0 */
void main()
{
    TMOD = 0x11;
    TH0 = 0xFC;
    TL0 = 0x18;
    TR0 = 1;
    ET0 = 1;
    
    TH1 = 0xFC;
    TL1 = 0x18;
    TR1 = 1;
    ET1 = 1;
    
    EA = 1;


    while(1)
    {
        Playing();   //弹奏模式
        Singing();   //演奏模式
    }
}


//给595发送数据
void SendDataTo595(unsigned char Data)
{
    unsigned char i;
    for(i = 0; i < 8; i++)   //循环8次,刚好移完8位
    {
         SH595 = 0;            //先将移位寄存器控制引脚置为低
         _nop_();
         if((Data & 0x80)== 0x80)
             DS595 =1;
         else
             DS595 =0;
     
         Data <<= 1;           //将数据的次高位移到最高位
     
         SH595 = 1;           //再置为高,产生移位时钟上升沿,上升沿时数据寄存器的数据移位
         _nop_();
    }
}


//595输出数据
void Output595(void)
{
  ST595 = 0;    //先将存储寄存器引脚置为低
  _nop_();
  ST595 = 1;    //再置为高,产生移位时钟上升沿,上升沿时移位寄存器的数据进入数据存储寄存器,更新显示数据。
}


/* 定时器T0中断:通过T0TH和T0TL控制中断时间 */
void TIMER0() interrupt 1
{
  TH0 = T0TH;
    TL0 = T0TL;


    BUZZER = ~BUZZER;
}


void TIMER1() interrupt 3
{
    static unsigned char keybuf = 0xFF;
    static unsigned char KeySta = 1;
    static unsigned char KeyBF = 1;


    keybuf = (keybuf << 1) | KEYSET;
    TH1 = 0xFC;
    TL1 = 0x18;
    
    if(keybuf == 0x00)
    {
        KeySta = 0;
    }
    else 
    {
        KeySta = 1;
    }
    
    if(KeyBF != KeySta)
    {
        if(KeyBF != 0)
        {
            SysMod = !SysMod;
        }
        KeyBF = KeySta;

    }

#ifndef _SINGING_H_
#define _SINGING_H_


unsigned char T0TH = 0;    //T0定时器重载值,用以控制频率
unsigned char T0TL = 0;


/********************************************
                 频率初值表
*********************************************/
unsigned char code T0ChuZhi[]={
  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
};


//高4位为音调,低四位为节拍
/********************************************
                    歌曲(C调)
*********************************************/
unsigned char code SongChar[]={             //龙的传人
0x34, 0x14, 0x32, 0x32, 0x14,
0x32, 0x32, 0x52, 0x62, 0x54, 0x04,
0x62, 0x62, 0x62, 0x52, 0x42, 0x42, 0x44,
0x22, 0x32, 0x22, 0x12, 0x24, 0x04,
0x32, 0x02, 0x12, 0x02, 0x32, 0x02, 0x32, 0x02,
0x32, 0x32, 0x52, 0x62, 0x64, 0x04,
0x14, 0x52, 0x52, 0x64, 0x34,
0x22, 0x12, 0x22, 0x32, 0x54, 0x04,
0x14, 0x52, 0x52, 0x64, 0x34,
0x22, 0x12, 0x22, 0x32, 0x14, 0xff
};


/* 延时1ms,12T,12MHz */
void Delay1ms(unsigned int n)       //@12.000MHz
{
    unsigned char i, j;
    while(n--)
    {
        i = 2;
        j = 239;
        do
        {
            while (--j);
        } while (--i);
    }
}


/* 延时125MS,即十六分音符 */
void Delay125ms(unsigned int n) 
{
    unsigned char i, j;
  while(n--)
    {
        i = 244;
        j = 45;
        do
        {
            while (--j);
        } while (--i);
    }
}


/* 音乐演奏 */
void Singing()
{
    int jiepai = 0;               //节拍
    int yinnum = 0;                       //音符计数,即第几个音符
  unsigned char yindiao = 0;    //音调
    unsigned char yinmatemp = 0;  //要处理的音码


    TR0 = 0;
  while(SysMod == 1)  //循环播放
    {
        yinmatemp = SongChar[yinnum];
        
        if(yinmatemp != 0xFF)  //不是歌曲结尾
        {
            yindiao = yinmatemp >> 4;  //取高四位,音调
            
            if(yindiao != 0)  //不是休止符
            {
                T0TH = T0ChuZhi[yindiao*2];
                T0TL = T0ChuZhi[yindiao*2+1];
                TR0 = 1;
            }
            else             //是休止符
            {
                TR0 = 0;
            }
            jiepai = yinmatemp & 0x0F;  //取低四位,节拍
            Delay125ms(jiepai);
            TR0 = 0;
            Delay1ms(10);
            yinnum++;
        }
        
        else              //是歌曲结尾
        {
            TR0 = 0;
            yinnum = 0;
            Delay1ms(3000);
        }
    }
}


#endif

}









你可能感兴趣的:(设计电子琴的C语言程序(基于单片机))