//------------------------------------------------------------------------
//名称:按键调节数码管显示
//------------------------------------------------------------------------
//说明:
// 按MOD键一次,时间暂停,如果这时按+键或键-键,
// 秒的数量就加1或减一;再按MOD键(两次),如果这时按+键或键-键,
// 分的数量就加1或减一;再按MOD键(三次),如果这时按+键或键-键,
// 时的 数量就加1或减一;再按MOD键(四次),启动计时(恢复正常计时)。
//------------------------------------------------------------------------
#include //调用含有51专用寄存器的头文件
#define uchar unsigned char //用uchar代替unsigned char
#define uint unsigned int //用uint代替unsigned int
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳极数码管断码表
//uchar codetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴极数码管断码表
sbit mode = P1^0; //模式调节
sbit s1 = P1^1;//加
sbit s2 = P1^2;//减
int sec=20,min=5,hour=12;//显示初值
uint temp; //临时变量
uchar m,n;
/***********************************
延时子函数
*************************************/
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=120;j>0;j--);
}
/*******************************
显示子函数
********************************/
void display(void)
{
P2=0x80;
P0=table[sec%10]; //显示秒个位
delayms(5);
P2=0x40;
P0=table[sec/10]; //显示秒十位
delayms(5);
P2=0x20; //显示横线
P0=0xbf;
delayms(5);
P2=0x10;//显示分个位
P0=table[min%10];
delayms(5);
P2=0x08;//显示分十位
P0=table[min/10];
delayms(5);
P2=0x04; //显示横线
P0=0xbf;
delayms(5);
P2=0x02; //显示时个位
P0=table[hour%10];
delayms(5);
P2=0x01;//显示时十位
P0=table[hour/10];
delayms(5);
}
/*****************************************
按键子函数
*******************************************/
void key()
{
if(mode==0)//第一次判断"模式"按键按下
{
delayms(5);//延时消抖
if(mode==0)//第二次判断"模式"按键按下
{ TR0=0;n++; } //暂停计时,并且记录按键按下的次数
while(!mode) //等待按键释放
{display();} //调用显示函数消除数码管闪烁
}
if(n>3) //如果第四次按下mode键则继续计时,并且重新记录按下的按键次数
{TR0=1;n=0;}
/********************************
调整+
*********************************/
if (s1==0)//第一次判断"+"按键按下
{
{delayms(10); //延时消抖
if (s1==0)//第二次判断"模式"按键按下
{
switch(n)//根据"模式"按键按下的次数,执行对应程序
{
case 1:sec++;if(sec>59)sec=0; //秒递增,最大显示59,若59继续递增则显示00
break;
case 2:min++;if(min>59)min=0; //分递增,最大显示59,若59继续递增则显示00
break;
case 3:hour++;if(hour>23)hour=0; //时递增,最大显示59,若23继续递增则显示00
break;
}
}
}
while(!s1) //等待"+"按键释放
{display();} //调用显示函数消除数码管闪烁
}
/******************************
调整-
*******************************/
if (s2==0) //第一次判断"-"按键按下
{
{delayms(10);//延时消抖
if(s2==0) //第二次判断"模式"按键按下
{
switch(n)//根据"模式"按键按下的次数,执行对应程序
{
case 1:sec--;if(sec<=0)sec=59; //秒递减,最小显示00,若00继续递减则显示59
break;
case 2:min--;if(min<=0)min=59; //分递减,最小显示00,若00继续递减则显示59
break;
case 3:hour--;if(hour<=-1)hour=23; //时递减,最小显示00,若00继续递减则显示23
break;
}
}
}
while(!s2)//等待按键释放
{display();}//调用显示函数消除数码管闪烁
}
}
/*************主函数************/
void main(void)
{
TMOD=0x11; //设置工作方式
ET0=1; //使能定时器0
TH0=(65536-50000)/256;//定时器的初值
TL0=(65536-50000)%256;
TR0=1; //停止开启定时器0
EA=1; //使能中断
while(1)
{
display();//调用显示函数
key(); //调用按键处理函数
}
}
/************定时器0中断计时**********/
voidTime0() interrupt 1
{
TH0=(65536-50000)/256; //重装初值50ms;
TL0=(65536-50000)%256;
m=m+1;
key();
if(m>20)// m=20说明1秒时间到
{
m=0;
sec++;
if(sec>59) //判断到达60s
{
min++;//分钟加1
sec=0;
if(min>59) //判断到达60分
{
hour=hour+1; //小时加1
min=0;
}
if(hour==24)hour=0;
}
}
}