#include <reg51.h>//頭文件的引用
void T0_init();//定義初值
void Key(); //按鍵掃描函數(shù)
void yingyue(); //音樂播放函數(shù)
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
};//感恩的心音調(diào)
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};//感恩的心節(jié)拍
void main(void)//主函數(shù)
{
T0_init();//初始化函數(shù)調(diào)用
while(1){
if(i==0){
led_song=1;
led_dz=0;
Key();//按鍵掃描函數(shù)的調(diào)用
Display();
}
if(i==1){
k++;
time1=Tone_H8[song[k]];
time2=Tone_L8[song[k]];
time=len[k]; //節(jié)拍
led_song=0;
led_dz=1;
yingyue();//發(fā)出一個音符
}
}
}
//--------------------------------------*********------------------------------------------------
void Display()//音符音調(diào)顯示函數(shù)
{
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];//顯示按鍵音調(diào)
Delay_ms(10);
P0=0x00;
}
//--------------------------------------*********------------------------------------------------
void T0_int(void) interrupt 1 //T0中斷程序,控制發(fā)音的音符
{
TH0= Tone_H8[index];
TL0= Tone_L8[index];
beep=~beep;
}
void t0int() interrupt 3 //T1中斷程序,控制發(fā)音的音符
{
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寄存器中設(shè)置T0,T1的工作方式
ET1=1;
ET0=1;
EX0=1;
IT0=1;
PX0=1;
}
//--------------------------------------*********------------------------------------------------
void delay(unsigned char t) //延時程序,控制發(fā)音的時間長度
{
unsigned char t1;
unsigned long t2;
for(t1=0;t1<t;t1++) //雙重循環(huán), 共延時t個半拍
for(t2=0;t2<6000;t2++); //延時期間, 可進入T0中斷去發(fā)音
TR1=0; //關(guān)閉T0, 停止發(fā)音
}
//--------------------------------------*********------------------------------------------------
//延時函數(shù)
void yingyue() //演奏一個音符
{
TH1=time1; //控制音調(diào)
TL1=time2;
TR1=1; //啟動T0, 由T0輸出方波去發(fā)音
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);
}
}
//--------------------------------------*********------------------------------------------------
//按鍵掃描函數(shù)
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
}
}
}
|