#include <REGX52.H> //AT89S52头文件
#define uint unsigned int
#define uchar unsigned char
uchar code dispcode[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, //共阳数码管字库
0x80,0x90,0xFF};
//变量定义
uchar timecount,Hour,Minute,Second,T_Min,T_Sec,qian,bai,shi,ge,
biao,keytemp,disH,disL,THour,TMinute;
bit biaoA,biaoB;
/*硬件端口定义*/
sbit led0=P1^0; //**数码管位选
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
sbit LED="P3"^2; //倒计时 指示灯
sbit K0=P2^0; //**按键接口
sbit K1=P2^1;
sbit K2=P2^2;
sbit K3=P2^3;
//子程序声明
void display(); //显示处理子程序
void key(); //按键检测处理子程序
void LED_out(); //数码管显示子程序
uchar UpDown(char dd,uchar max,uchar min); //加减按键子程序
void DaoTime(void); //倒计时处理
void delay(uchar i) /***延时1ms***/
{ uint x;
for(;i>0;i--)
for(x=114;x>0;x--); //11.0592=114
}
void initTimer(void) //定时/计数器初始化
{
TMOD=0x1;
TH0=0x20;
TL0=0x35;
}
void main(void) //主程序
{
initTimer();
TR0=1;
ET0=1;
EA=1;
Hour=12;
Minute=34;
while(1)
{
key();
display();
}
}
/***T1***中***断***函***数***/
void timer0(void) interrupt 1 using 3 //T2中断,使用寄存器组3
{
TH0=0x20;
TL0=0x35;
timecount++; //timecount变量加1, timecount加到16为1秒
if((timecount%8)==0)
biaoA=~biaoA;
if(timecount==16) //如果1秒时间到?
{timecount=0; // timecount清零
Second++; //秒加1
if(biaoB==0)DaoTime();
if(Second==60) //如果1分时间到?
{Second=0; //秒清零
Minute++; //分加1
if(Minute==60) //如果1小时时间到?
{Minute=0; //分清零
Hour++; //小时加1
if(Hour==24) //如果1天时间到?
Hour="0"; //小时清零
}
}
}
switch (biao)
{
case 0: disH="Hour";disL=Minute; //显示时,分
break;
case 1: disH="T"_Min;disL=T_Sec; //显示倒计时时间
break;
}
}
/***显***示***函***数***/
void display()
{
if(disH==100) //如果显示缓冲高位等于100
{qian=10;bai=10;shi=disL/10;ge=B;} //数码管千位,百位不显示
else //如果显示缓冲高位不为100
{if(disL==100) //如果显示缓冲低位等于100
{qian=disH/10;bai=B;shi=10;ge=10;} //数码管十位,个位不显示
else //如果显示缓冲低位不为100
{qian=disH/10;bai=B;shi=disL/10;ge=B;} //数码管千位,百位,十位,个位同时显示
}
if(biao>3|biaoB)
if(timecount>8)
{
switch (keytemp)
{
case 0: {qian=10;bai=10;}
break;
case 1: {shi=10;ge=10;}
break;
case 2: {qian=10;bai=10;}
break;
}
}
LED_out();
}
/**显示缓冲送数码管显示**/
void LED_out()
{
if(qian){ //千位处理
P0=dispcode[qian];
led0=0;delay(2);led0=1;}
/*
if(biaoA&&(biao<2)) //百位处理
P0=dispcode[bai]&0x7f;
else */
P0=dispcode[bai];
led1=0;delay(2);led1=1;
if(biaoA&&(biao<2)) //十位处理
P0=dispcode[shi]&0x7f;
else
P0=dispcode[shi];
led2=0;delay(2);led2=1;
if(biaoA&&(biao<2)) //个位处理
P0=dispcode[ge]&0x7f;
else
P0=dispcode[ge];
led3=0;delay(2);led3=1;
}
/****按键检测****/
void key()
{ uchar temp;
if(K3==0)
{delay(5);if(K3==0)
{while(!K3)
{display();
temp++;
if(temp==125)
{if(biao==0)
{biao=4;THour=Hour;TMinute=Minute;keytemp=0;break;} //进入设定时间
else
{temp=0;break;}
}
}
if((temp!=125)&&(biao==4)) //选择设定(时,分)
{keytemp++;
if(keytemp==2)
keytemp="0";
}
else
{if(biao<2) //切换显示(实时时间,倒计时间)
{
biao++;
if(biao==2)
{
biao="0";
keytemp="0";
biaoB="0";
}
}
}
while(!K3)display();
}
temp="0";
}
switch (biao)
{
case 1: {if(K2==0){delay(5);if(K2==0) //进入设定倒计时间
{keytemp++;biaoB=1;LED=1;
if(keytemp==3)
{keytemp=0;biaoB=0;if((T_Min||T_Sec)!=0)LED=0;} //倒计启动点亮LED
}
while(!K2)display();
}
if(biaoB)
{
if(keytemp==2){T_Min=UpDown(T_Min,90,0);} //设定倒计时小时
if(keytemp==1){T_Sec=UpDown(T_Sec,59,0);} //设定倒计时分钟
}
}
break;
case 4:{if(keytemp==0){THour=UpDown(THour,23,0);disH=THour;disL=TMinute;display();} //设定当前时间小时
if(keytemp==1){TMinute=UpDown(TMinute,59,0);disH=THour;disL=TMinute;display();} //设定当前时间分钟
if(K2==0){delay(5);if(K2==0) //保存数据并退出
{TR0=0;Second=0;timecount=0;Hour=THour;
Minute="TMinute";TR0=1;biao=0;
while(!K2)display();}}}
break;
}
}
/*加减按键子程序*/
uchar UpDown(char dd,uchar max,uchar min)
{uint x="35"; //定义连续调整的间隔延时
if(K1==0){delay(5);if(K1==0){ //K1按下参数dd加一
dd++;
if(dd>max) dd="min"; //如果参数dd大于上限值dd返回最小值
while(--x){display();if(K1)break;} //循环显示一段时间参数继续加一
}}
if(K0==0){delay(5);if(K0==0){ //K0按下参数dd减一
dd--;
if(dd<min)dd=max; //如果参数dd小于下限值dd返回最大值
while(--x){display();if(K0)break;} //循环显示一段时间参数继续减一
}}
return dd;
}
/*倒计时处理*/
void DaoTime(void)
{
if(T_Min||T_Sec)
{
if(T_Sec)
T_Sec--; //秒倒计
else
if(T_Min)
{T_Min--;T_Sec=59;} //分倒计
if((T_Min||T_Sec)==0)LED=1; // 倒计时 时间到关闭LED
}
}
文章评论(0条评论)
登录后参与讨论