#include<reg52.h> #include<intrins.h>#define LED_code_port P0 // 段码数据口#define LED_segmnet_port P2 // 位码数据口sbit KEYL3=P1^5;sbit KEYH1=P1^0;sbit KEYH2=P1^1;sbit KEYH3=P1^2;sbit KEY1=P3^3;//四个按键数据口unsigned int flag;unsigned char time_data[3]={00,10,0};unsigned char code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};//段码数组unsigned char n=0; // n为节拍常数变量unsigned char code music_tab[] ={ 0x18, 0x30, 0x1C , 0x10, //格式为频率常数, 节拍常数, 频率常数, 节拍常数,0x20, 0x40, 0x1C , 0x10,0x18, 0x10, 0x20 , 0x10,0x1C, 0x10, 0x18 , 0x40,0x1C, 0x20, 0x20 , 0x20,0x1C, 0x20, 0x18 , 0x20,0x20, 0x80, 0xFF , 0x20,0x30, 0x1C, 0x10 , 0x18,0x20, 0x15, 0x20 , 0x1C,0x20, 0x20, 0x20 , 0x26,0x40, 0x20, 0x20 , 0x2B,0x20, 0x26, 0x20 , 0x20,0x20, 0x30, 0x80 , 0xFF,0x20, 0x20, 0x1C , 0x10,0x18, 0x10, 0x20 , 0x20,0x26, 0x20, 0x2B , 0x20,0x30, 0x20, 0x2B , 0x40,0x20, 0x20, 0x1C , 0x10,0x18, 0x10, 0x20 , 0x20,0x26, 0x20, 0x2B , 0x20,0x30, 0x20, 0x2B , 0x40,0x20, 0x30, 0x1C , 0x10,0x18, 0x20, 0x15 , 0x20,0x1C, 0x20, 0x20 , 0x20,0x26, 0x40, 0x20 , 0x20,0x2B, 0x20, 0x26 , 0x20,0x20, 0x20, 0x30 , 0x80,0x20, 0x30, 0x1C , 0x10,0x20, 0x10, 0x1C , 0x10,0x20, 0x20, 0x26 , 0x20,0x2B, 0x20, 0x30 , 0x20,0x2B, 0x40, 0x20 , 0x15,0x1F, 0x05, 0x20 , 0x10,0x1C, 0x10, 0x20 , 0x20,0x26, 0x20, 0x2B , 0x20,0x30, 0x20, 0x2B , 0x40,0x20, 0x30, 0x1C , 0x10,0x18, 0x20, 0x15 , 0x20,0x1C, 0x20, 0x20 , 0x20,0x26, 0x40, 0x20 , 0x20,0x2B, 0x20, 0x26 , 0x20,0x20, 0x20, 0x30 , 0x30,0x20, 0x30, 0x1C , 0x10,0x18, 0x40, 0x1C , 0x20,0x20, 0x20, 0x26 , 0x40,0x13, 0x60, 0x18 , 0x20,0x15, 0x40, 0x13 , 0x40,0x18, 0x80, 0x00};sbit S=P2^2;void delay (unsigned char m) // 控制频率延时{unsigned char i=3*m;while(--i);}void delayms(unsigned char a) // 毫秒延时子程序{while(--a); // 采用while(--a) 不要采用while(a--);}void KILL() //播放音乐函数{unsigned char p,m; // m为频率常数变量unsigned char i=0;TMOD =0x10;TH1=0xd8;TL1=0xef;ET1=1;EA=1;ES=1;play:while(1){a:p=music_tab[i];if(p==0x00){i=0, delayms(1000);goto play;} // 如果碰到结束符,延时1秒,回到开始再来一遍else if(p==0xff){i=i+1;delayms(100),TR1=0;goto a;} // 若碰到休止符,延时100ms,继续取下一音符else{m=music_tab[i++], n=music_tab[i++];} // 取频率常数和节拍常数TR1=1; // 开定时器1while(n!=0) S=~S,delay(m); //等待节拍完成, 通过P1口输出音频(可多声道哦!) TR1=0; //关定时器1}}void delay_ms(unsigned int x) // 延时毫秒级{unsigned int a=0,b=0,c=0;for(a=x;a>0;a--)for(b=5;b>0;b--)for(c=128;c>0;c--);}void LED_display(unsigned char seg_code,unsigned char shuju){if(seg_code<1||seg_code>4) seg_code=1;if(shuju>15) shuju=15;LED_segmnet_port=(LED_segmnet_port|0xf0)&_crol_(0xef,seg_code-1); // 送入位码LED_code_port=table[shuju]; // 送入段码delay_ms(2); // 保持显示2毫秒LED_segmnet_port=LED_segmnet_port|0xf0; // 关掉所有数码管}void display_time(){LED_display(1,time_data[0]/10);LED_display(2,time_data[0]%10);LED_display(3,time_data[1]/10);LED_display(4,time_data[1]%10);}void time_initial(){TMOD=0x01; //定时器,方式1TH0=0x4c; //写入初值高8位TL0=0; //写入初值低8位EA=1; // 开总中断ET0=1; // 定时中断允许TR0=1; // 开启定时器}void int0() interrupt 3 // 采用中断1 控制节拍{TH1=0xd8;TL1=0xef;n--;}void main(){time_initial();TR1=0;while(1){KEYL3=0;display_time();if((time_data[0]==0)&(time_data[1]==0)){TR0=0;TR1=1;KILL();}display_time();//判断计时是否为0,如为0,播放音乐if(KEYH1==0)//键盘扫描{delay_ms(5);//消斗if(KEYH1==0)//按键1按下,标志位置1{flag=1;}}if(flag==1){ if(KEYH2==0){delay_ms(5);if(KEYH2==0){time_data[0]++;display_time();}//标志位置1情况下,如果按键2按下,分钟加1 }if(KEYH3==0){delay_ms(5);if(KEYH3==0){time_data[0]--;display_time();}//标志位置1情况下,如果按键3按下,分钟减1}if(KEY1==0){delay_ms(5);if(KEY1==0){flag=0; delay_ms(50);display_time();}} //标志位置1情况下,如果按键4按下,标志位置0,设置完成}if(flag==0){if(KEYH2==0) {delay_ms(5);if(KEYH2==0){while(!KEYH2);time_data[0]=05;time_data[1]=00;display_time();}}//按下2键,显示“0500”if(KEYH3==0) {delay_ms(5);if(KEYH3==0){while(!KEYH3);time_data[0]=10;time_data[1]=00;display_time();}}//按下3键,显示“1000”if(KEY1==0) {delay_ms(5);if(KEY1==0){time_data[0]=20;time_data[1]=00;display_time();}}//按下4键,显示“2000”}}}void timer0() interrupt 1 //中断{TH0=0x4c; //重新写入初值TL0=0;time_data[2]++;if(time_data[2]==20){time_data[2]=0;time_data[1]--;//秒数减一if(time_data[1]==0xff){time_data[1]=59;time_data[0]--;//秒数减为0,置为59,同时分钟减一}}}。