1附录2主程序#includereg52.h#defineucharunsignedchar#defineuintunsignedintsbitKEYON=P2^0;//开始键sbitKEYOFF=P2^1;//关闭键sbitKEYSET=P2^2;//预约键sbitKEYINC=P2^3;//加1键sbitKEYDEC=P2^4;//减1键sbitKEYFREE=P2^5;//预留键sbitPOWER=P3^6;//电源开关指示灯sbitLED=P3^3;//按键指示灯ucharcodedispcode[]={0x3f,0x06,0x05b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//0-9的字型码uchardatadisbuf[]={0,0,0,0};//显示缓冲区ucharhour,min;//小时、分变量bitOnflag,flag;ucharSetflag;voiddelay(uchar);//延时子函数voidinit(void);//定时器初始化子函数ucharGetKeyNum();//求按键号voidKeyprocess(uchar);//按键处理子函数voidcalculate();//计时子函数voiddisplay();//显示子函数//--------------------主函数-------------------------voidmain(void){init();P1=0x00;while(1)display();}//-------------定时器TO、T1初始化,外部中断0初始化子函数-----voidinit(){TMOD=0x11;//TO、T1作定时器、工作方式1TH0=(65536-50000)/256;//定时50msTL0=(65536-50000)%256;TH1=(65536-50000)/256;TL1=(65536-50000)%256;IT0=1;//选择外部中断0为下降沿触发方式EX0=1;//开外部中断0ET1=1;//开定时器1ET0=1;//开定时器0EA=1;//开总中断TR0=1;}//----------显示子函数--------------------------voiddisplay(){uchari,j=0x08;if((Setflag==0)&&!(min|hour))//数码管显示“----”2{for(i=0;i4;i++)disbuf[i]=dispcode[10];}else//正常显示时间{disbuf[0]=dispcode[min%10];//分个位disbuf[1]=dispcode[min/10];//分十位disbuf[2]=dispcode[hour%10]+0x80;//小时个位disbuf[3]=dispcode[hour/10];//小时十位}if((Setflag!=0)&flag)//如果调时,数码管闪烁显示{for(i=0;i4;i++){if((disbuf[i]==0x3f)&&(i2))//不显示前面的0P0=0;elseP0=disbuf[i];if(Setflag==1)P1=j&0xfc;//调时,关断前两位位码elseP1=j&0xf3;//调分,关断后两位位码delay(5);//延时2.5msP1=0x00;j=j1;}}else//数码管正常显示{for(i=0;i4;i++){if((disbuf[i]==0x3f)&&(i2))P0=0;//不显示前面的0elseP0=disbuf[i];P1=j;//位选通delay(5);//延时2.5msP1=0X00;j=j1;}}}//--------------外部中断0中断函数---------------------------------voidint0()interrupt0using0{ucharkeynum;display();//动态显示程序作为去抖动if(INT0==0)//判断是否有按键按下{keynum=GetKeyNum();//有效键,获取键值while(INT0==0);//等待按键释放Keyprocess(keynum);//按键处理}}//-----------------定时器0中断子函数----------------------------voidtime0()interrupt1//处理调时、显示器闪烁{staticucharledcnt,num;//设置静态变量TH0=(65536-50000)/256;//定时50ms3TL0=(65536-50000)%256;if((Onflag&&((hour|min)!=0))|!Onflag)//指示灯每隔0.5s闪烁{ledcnt++;if(ledcnt==10)//10X50mS=0.5S{ledcnt=0;LED=~LED;}}if(Setflag!=0)//调时闪烁{num++;if(num==5){num=0;flag=~flag;}}}//-------------定时器1中断子函数-------------------voidtime1()interrupt3{TH1=(65536-50000)/256;TL1=(65536-50000)%256;calculate();//计时}//-----------------求按键号-------------------------------ucharGetKeyNum(){uchartemp;if(KEYON==0)temp=1;if(KEYOFF==0)temp=2;if(KEYSET==0)temp=3;if(KEYINC==0)temp=4;if(KEYDEC==0)temp=5;if(KEYFREE==0)temp=6;return(temp);}//--------------------按键处理函数----------------------------voidKeyprocess(ucharx){switch(x){case1://KEYON处理函数Onflag=1;//开Onflag标志Setflag=0;//关(Setflag)调时标志if((!Setflag)&&!(hour|min))//没有调时且未处于预约,继电器通{POWER=0;LED=0;}elseTR1=1;//定时器1运行、执行计时程序break;case2://KEYOFF,关处理,标志清04Onflag=0;Setflag=0;hour=0;min=0;POWER=1;LED=1;break;case3://预约调时/调分键,处理调时标志if(Onflag==0){Setflag++;if(Setflag==3)Setflag=1;}break;case4://加1键if(Setflag==1)//调时键,最大只能调到11{hour++;if(hour==12)hour=0;}if(Setflag==2)//调分键,最大只能调到59{min++;if(min==60)min=0;}break;case5://减1键if(Setflag==1)//调时键,减小时处理,最小0{hour--;if(hour==-1)hour=12;}if(Setflag==2)//调分键,减分处理,最小0{min--;if(min==-1)min=59;}break;}}//---------------------计算时间---------------------------------voidcaculate(){staticuinttcount;//tcount为定时次数if((hour|min)!=0){tcount++;//1次50ms到,改变定时次数if(tcount==1200)//1200*50ms=1分钟{tcount=0;//初始化定时次数if(min==0){5min=60;hour--;}min--;}if((min==0)&(hour==0))//预约时间到{POWER=0;//继电器接通LED=0;TR1=0;}}}//-----------------------定时0.5ms------------------------voiddelay(ucharx){ucharj,k;for(j=x;j0;j--)for(k=249;k0;k--);}