#include
#define uchar unsigned char
#define uint unsigned int
uchar code Tab0[]= //定义数码管数组,没有小数点
{
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
};
uchar code Tab1[]= //定义数码管数组,有小数点
{
0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef
};
uchar miaobiao[80]; //定义存储秒表数组
sbit K1=P3^2; //模式选择键,本程序三种模式,分别是时间显示、秒表、时间设置
sbit K2=P3^3; //设置时间时加一/开始(暂停)秒表按键
sbit K3=P3^4; //切换设置位/清零秒表按键
sbit K4=P3^5; //秒记录
void Delay(uchar x); //延时函数
void Display0(); //时间显示函数
void Display1(); //秒表显示函数
void Display2(); //时间设置显示函数
void Display3(); //保存的秒表显示函数
void Init(); //中断初始化函数
void Mode_K1(); //模式切换函数
void KEY_MiaoBiao(); //检测秒表操作按键
void KEY_Time_Set(); //检测时间设置按键
void KEY_MiaoBiao_keep(); //检测秒表记录显示按键操作
uchar Hours=12,Minutes=00,seconds=00; //分别定义三个变量表示时、分、秒
uchar Time0_bit=0; //用于定时器0的溢出标志
bit Set_Time=0; //设置时 闪烁时长的标志位
bit Set0=0; //设置时间标志,确定是设置‘分’还设置‘时’
uchar K1_bit=0,m=0; //用于模式切换的标志
uchar Miao_Biao0,Miao_Biao1,Miao_Biao2,Miao_Biao3,Miao_Biao4; //用于秒表的变量
uchar Miao_Biao11,Miao_Biao22,Miao_Biao33,Miao_Biao44; //用于保存秒表显示时的变量
void main()
{
Init(); //中断初始化
while(1) //死循环
{
Mode_K1(); //模式扫描
switch(K1_bit) //模式选择
{
case 0:
{
Display0(); //显示时间
break;
}
case 1:
{
Display1(); //显示秒表
KEY_MiaoBiao(); //扫描秒表操作
break;
}
case 2:
{
Display2(); //设置时间时的显示程序,可闪烁定位
KEY_Time_Set(); //扫描按键
break;
}
case 3:
{
Display3(); //显示秒表
KEY_MiaoBiao_keep(); //扫描秒表操作
break;
}
}
}
}
void KEY_Time_Set() //设置时间时的按键扫描函数
{
if(K1_bit==2) //判断是否为时间设置模式
{
if(K2==0) //K2有按下(下同)
{
Delay(10); //延时消抖(下同)
if(K2==0) //再次检测是否为误按
{
if(Set0==0) //检测是设置‘时’还是分,Set0为0时设置‘分’,Set0为1时设置‘时’
{
Minutes++; //‘分’加1
if(Minutes==60) //当'分'加到60时,重新赋值0
Minutes=0;
}
else
{
Hours++; //‘时’加1
if(Hours==24) //当'时'加到24时,重新赋值0
Hours=0;
}
while(!K2);//按键松开检测,消除松开按键时的抖动干扰
}
}
if(K3==0)
{
Delay(10);
if(K3==0)
{
Set0=~Set0; //K3每按一次Set0取反,时分切换,Set0为0时设置‘分’,Set0为1时设置‘时’
while(!K3);
}
}
}
}
void KEY_MiaoBiao() //检测秒表按键操作
{
if(K1_bit==1) //判断是否为秒表模式
{
if(K2==0)
{
Delay(10);
if(K2==0)
{
TR1=~TR1; //K2每按一次TR1取反,0暂停或1开始定时器1,达到暂停或开始秒表的目的
while(!K2);
}
}
if(K4==0) //当K4按下时秒表记录一组数据
{
Delay(10);
if(K4==0)
{
miaobiao[4*m]=Miao_Biao1;
miaobiao[4*m+1]=Miao_Biao2;
miaobiao[4*m+2]=Miao_Biao3;
miaobiao[4*m+3]=Miao_Biao4;
m++;
while(!K4);
}
}
if(K3==0)
{
Delay(10);
if(K3==0) //当K3按下时秒表所有数据清零,并停止定时器1
{
uchar i;
for(i=0;i<81;i++)
{
miaobiao[i]=0; //清除所有秒记录数据
}
TR1=0; //停止定时器1
Miao_Biao0=0; //清零数据
Miao_Biao1=0;
Miao_Biao2=0;
Miao_Biao3=0;
Miao_Biao4=0;
m=0; //秒表记录清零
while(!K3);
}
}
}
}
void KEY_MiaoBiao_keep() //检测秒表记录显示按键操作
{
if(K1_bit==3) //判断是否为秒表记录显示模式
{
if(K2==0)
{
Delay(10);
if(K2==0)
{
m++;
while(!K2);
}
}
Miao_Biao11=miaobiao[4*m];
Miao_Biao22=miaobiao[4*m+1];
Miao_Biao33=miaobiao[4*m+2];
Miao_Biao44=miaobiao[4*m+3];
if(K3==0)
{
Delay(10);
if(K3==0) //当K3按下时秒表所有数据清零,并停止定时器1
{
uchar i;
for(i=0;i<81;i++)
{
miaobiao[i]=0; //清除所有秒记录数据
}
while(!K3);
}
}
}
}
void Mode_K1() //模式选择键,本程序三种模式,分别是时间显示、秒表、时间设置
{
if(K1==0)
{
Delay(10);
if(K1==0)
{
K1_bit++;
// if(K1_bit==1) m=0;
if(K1_bit==3) m=0;
if(K1_bit==4)
{
K1_bit=0;
}
while(!K1);
/***********************************************************************
*************当K1_bit为0时显示时钟,为1时进入秒表,*********************
*******************为2时进入时间设置模式,3时进入秒表记录显示***********
***********************************************************************/
}
}
}
void Time1() interrupt 3 //定时器1函数
{
TH1=(65536-50000)/256; //重装初值
TL1=(65536-50000)%256;
Miao_Biao0++;
if(Miao_Biao0==2) //以下为秒表数据处理,每两次循环进行一次操作
{
Miao_Biao0=0;
Miao_Biao1++; //Miao_Biao1每加1次为100ms
if(Miao_Biao1==10)
{
Miao_Biao1=0;
Miao_Biao2++;
if(Miao_Biao2==60)
{
Miao_Biao2=0;
Miao_Biao3++;
if(Miao_Biao3==60)
{
Miao_Biao3=0;
Miao_Biao4++;
if(Miao_Biao4==10)
Miao_Biao4=0;
}
}
}
}
}
void Time0() interrupt 1 //定时器0函数
{
TH0=(65536-50000)/256; //重装初值
TL0=(65536-50000)%256;
Time0_bit++;
if((Time0_bit%10)==0) //每溢出10次Time0_bit取反一次
Set_Time=~Set_Time; //0.5秒闪烁一次
if(Time0_bit==20) //以下为时间数据处理
{
Time0_bit=0;
seconds++;
if(seconds==60)
{
seconds=0;
Minutes++;
if(Minutes==60)
{
Minutes=0;
Hours++;
if(Hours==24)
{
Hours=0;
}
}
}
}
}
void Init() //中断初始化函数
{
EA=1; //开总中断
TMOD=0X11; //定时器工作方式选择,定时器0和定时器1都选择第1种工作方式
TH0=(65536-50000)/256; //定时器0装初值,定时50ms
TL0=(65536-50000)%256;
ET0=1; //开定时器0开关
TR0=1; //开定时器0小开关
TH1=(65536-50000)/256; //定时器1装初值,定时50ms
TL1=(65536-50000)%256;
ET1=1; //开定时器1开关
TR1=0; //关定时器1小开关
}
void Display3() //显示保存的秒表
{
P0=Tab0[Miao_Biao11%10]; //显示1/10秒的个位
P1=0xdf; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab1[Miao_Biao22%10]; //显示秒的个位,需要加上小数点做分隔符
P1=0xef; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab0[Miao_Biao22/10]; //显示秒的十位
P1=0xf7; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab1[Miao_Biao33%10]; //显示分的个位,需要加上小数点做分隔符
P1=0xfb; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab0[Miao_Biao33/10]; //显示分的十位
P1=0xfd; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab1[Miao_Biao44%10]; //显示时的个位,需要加上小数点做分隔符
P1=0xfe; //段选
Delay(10); //延时
P0=0X00; //消隐
}
void Display2() //时间设置时的显示函数
{
if(Set0==0) //判断是否为设置‘时’还是‘分’
{
P0=Tab0[seconds%10]; //显示秒的个位
P1=0xdf; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab0[seconds/10]; //显示秒的十位
P1=0xef; //段选
Delay(10); //延时
P0=0X00; //消隐
if(Set_Time) //这个if语句实现分钟以0.5秒的频率闪烁
{
P0=Tab1[Minutes%10]; //显示分的个位,需要加上小数点做分隔符
P1=0xf7; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab0[Minutes/10]; //显示分的十位
P1=0xfb; //段选
Delay(10); //延时
P0=0X00; //消隐
}
else
{
P0=0x00; //显示分的个位,需要加上小数点做分隔符
P1=0xf7; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=0x00; //显示分的十位
P1=0xfb; //段选
Delay(10); //延时
P0=0X00; //消隐
}
P0=Tab1[Hours%10]; //显示时的个位,需要加上小数点做分隔符
P1=0xfd; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab0[Hours/10]; //显示时的十位
P1=0xfe; //段选
Delay(10); //延时
P0=0X00; //消隐
}
else //‘时’钟闪烁
{
P0=Tab0[seconds%10]; //显示秒的个位
P1=0xdf; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab0[seconds/10]; //显示秒的十位
P1=0xef; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab1[Minutes%10]; //显示分的个位,需要加上小数点做分隔符
P1=0xf7; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab0[Minutes/10]; //显示分的十位
P1=0xfb; //段选
Delay(10); //延时
P0=0X00; //消隐
if(Set_Time) //这个if语句实现‘时’钟以0.5秒的频率闪烁
{
P0=Tab1[Hours%10]; //显示时的个位,需要加上小数点做分隔符
P1=0xfd; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab0[Hours/10]; //显示时的十位
P1=0xfe; //段选
Delay(10); //延时
P0=0X00; //消隐
}
else
{
P0=0x00; //显示时的个位,需要加上小数点做分隔符
P1=0xFF; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=0X00; //显示时的十位
P1=0xFF; //段选
Delay(10); //延时
P0=0X00; //消隐
}
}
}
void Display1() //显示秒表
{
P0=Tab0[Miao_Biao1%10]; //显示1/10秒的个位
P1=0xdf; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab1[Miao_Biao2%10]; //显示秒的个位,需要加上小数点做分隔符
P1=0xef; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab0[Miao_Biao2/10]; //显示秒的十位
P1=0xf7; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab1[Miao_Biao3%10]; //显示分的个位,需要加上小数点做分隔符
P1=0xfb; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab0[Miao_Biao3/10]; //显示分的十位
P1=0xfd; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab1[Miao_Biao4%10]; //显示时的个位,需要加上小数点做分隔符
P1=0xfe; //段选
Delay(10); //延时
P0=0X00; //消隐
}
void Display0() //显示时钟
{
P0=Tab0[seconds%10]; //显示秒的个位
P1=0xdf; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab0[seconds/10]; //显示秒的十位
P1=0xef; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab1[Minutes%10]; //显示分的个位,需要加上小数点做分隔符
P1=0xf7; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab0[Minutes/10]; //显示分的十位
P1=0xfb; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab1[Hours%10]; //显示时的个位,需要加上小数点做分隔符
P1=0xfd; //段选
Delay(10); //延时
P0=0X00; //消隐
P0=Tab0[Hours/10]; //显示时的十位
P1=0xfe; //段选
Delay(10); //延时
P0=0X00; //消隐
}
void Delay(uchar x) //延时
{
uchar i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}