📄 电子钟.c
字号:
#include<reg51.h>
#define Bus P0//数据线
#define Key_port P1//键盘端口
#define Select P2//位选择端口
#define OFF 0xff
//分别定义四个键值
#define UP 3
#define DOWN 1
#define SETUP 2
#define CHOOSE 4
#define Glitter_time 40//闪烁时间
#define Key_delay 16//去抖动的时间
#define Backtrack_time 3 //定义多少秒后自动返回时间页面
unsigned char code LedTable[11]={
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF
};//0到9的字型码,共阳数码管
unsigned char code Month_max[2][13]={
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
};
unsigned char code time_max[3]={59,59,23};
unsigned char glitter[6]={0,0,0,0,0,0};
unsigned char date[3]; //日期数组
unsigned char time[3]; //时间数组
unsigned char desecond; //秒计算辅助变量
unsigned char leap_year; //闰年标志位,1为闰年
bit second_flag; //秒改变标志
bit page=0; //显示页面标志,默认显示时间
unsigned char backtrack=0; //自动返回时间页面变量
//*******************************************]
//时钟及日期初始化函数
void ClockInit(void)
{
date[2]=5; //年初始化
date[1]=5; //月初始化
date[0]=27; //日初始化
time[2]=23; //小时初始化
time[1]=40; //分初始化
time[0]=30; //秒初始化
desecond=0;
second_flag=0; //
//开定时器0,设定为工作方式1,设定定时初值
IE=0x82; //允许中断,选中T0中断
TMOD=0x01; //定时器0,使用TR0启动方式,选中工作方式1
TH0=0x3C; //设置定时初值 65536-50000=15536
TL0=0xB1; //考虑中断响应时间,把B0改为B1
TR0=1; //启动T0
}
//*******************************************]
//中断响应函数
void Timer(void) interrupt 1 using 1
{
TH0=0x3C; //重载定时初值 65536-50000=15536
TL0=0xB1; //考虑中断响应时间(约20us),把B0改为B1
// 时钟处理
desecond++;
if(desecond>19)
{
desecond=0; //50000*20=1000000
second_flag=1;
}
}
//*******************************************]
//时间函数
void Clock(void)
{
if(second_flag==1)
{
if(backtrack<Backtrack_time)
backtrack++;
else
page=0;
time[0]++; //秒位增加
if(time[0]>59)
{
time[0]=0;
time[1]++; //分位增加
if(time[1]>59)
{
time[1]=0;
time[2]++; //小时增加
if(time[2]>23)
{
time[2]=0;
date[0]++; //日期增加
if((date[2]%4)==0)//判断是否是闰年
leap_year=1;//1为闰年
else
leap_year=0;
if(date[0]>Month_max[leap_year][date[1]])
{
date[0]=1;
date[1]++; //月增加
if(date[1]>12)
{
date[1]=1;
date[2]++;//年增加
date[2]=date[2]%100;
}
}
}
}
}
second_flag=0;
}
}
//*******************************************
//延时函数
void DelayXms(unsigned int count)
{
unsigned int delay;
unsigned int Xms;
for(Xms=0;Xms<count;Xms++)
for(delay=0;delay<200;delay++)
;
}
//*******************************************
//显示一位函数
void Dis_one_bit(unsigned char One_bit,unsigned char select_bit)
{
Bus=LedTable[One_bit];
Select=~select_bit;
DelayXms(1);
Select=OFF;
}
//*******************************************
//显示一字节函数
void Dis_one_word(unsigned char word,unsigned char select_word)
{
unsigned char one,ten,select_temp=1;
one=word%10;
ten=word/10;
select_temp<<=select_word;
Dis_one_bit(one,select_temp);
select_temp<<=1;
Dis_one_bit(ten,select_temp);
}
//*******************************************
//显示一个页面函数
void Display(bit page)
{
unsigned char temp1,temp2;
if(page==0)
{
for(temp1=0;temp1<3;temp1++)
{
temp2=temp1+temp1;
if(glitter[temp1]<Glitter_time)
Dis_one_word(time[temp1],temp2);
else
DelayXms(2);
}
}
else
{
for(temp1=0;temp1<3;temp1++)
{
temp2=temp1+temp1;
if(glitter[temp1+3]<Glitter_time)
Dis_one_word(date[temp1],temp2);
else
DelayXms(2);
}
}
}
//*******************************************
//键盘去抖动函数
void Remove_tingle(unsigned char key_delay,unsigned char choise)
{
unsigned char temp;
glitter[choise]=Glitter_time-1;
for(temp=0;temp<key_delay;temp++)
{
Display(page);
}
}
//*******************************************
//键盘检测函数
unsigned char Key(unsigned char choise)
{
unsigned char temp;
temp=Key_port|0xF0;
if(temp==0xFF)
return(0);
Remove_tingle(Key_delay,choise);//去抖动
temp=Key_port|0xF0;
switch(temp)
{
case 0xFE: return(1);
case 0xFD: return(2);
case 0xFB: return(3);
case 0xF7: return(4);
default : return(0);
}
}
//*******************************************
//键盘处理函数
void Key_process(void)
{
unsigned char key_temp,key_data,choise;
if(page==1)
choise=3;
else
choise=0;
key_data=Key(choise);//读取键盘
if(key_data==UP)//向上翻页
{
page=1;
backtrack=0;
return;
}
if(key_data==DOWN)//向下翻页
{
page=0;
return;
}
if(key_data!=SETUP)//不是进行设置
return;
TR0=0;//关闭T0;
while(1)
{
key_temp=Key(choise);
if((date[2]%4)==0)
leap_year=1;//闰年标志位,1为闰年
else
leap_year=0;
switch(key_temp)
{
case SETUP:
page=0;//默认显示时间
glitter[choise]=0;//消闪烁
TR0=1;//启动T0
return;
case CHOOSE:
glitter[choise]=0;
choise=(choise+1)%6;
if(choise>2)
page=1;
else
page=0;
break;
case UP:
if(choise<3)
if(time[choise]<time_max[choise])
time[choise]++;
else
time[choise]=0;
else if(choise==3)
{
page=1;
if(date[0]<Month_max[leap_year][date[1]])
date[0]++;
else
date[0]=1;
}
else if(choise==4)
{
if((date[2]%4)==0)
leap_year=1;//闰年标志位,1为闰年
else
leap_year=0;
if(date[0]>Month_max[leap_year][date[1]])
date[0]=Month_max[leap_year][date[1]];
page=1;
if(date[1]<12)
date[1]++;
else
date[1]=1;
}
else if(choise==5)
{
if((date[2]%4)==0)
leap_year=1;//闰年标志位,1为闰年
else
leap_year=0;
if(date[0]>Month_max[leap_year][date[1]])
date[0]=Month_max[leap_year][date[1]];
page=1;
if(date[2]<99)
date[2]++;
else
date[2]=0;
}
break;
case DOWN:
if(choise<3)
if(time[choise]>0)
time[choise]--;
else
time[choise]=time_max[choise];
else if((choise==3))
{
page=1;
if(date[0]>1)
date[0]--;
else
date[0]=Month_max[leap_year][date[1]];
}
else if(choise==4)
{
if((date[2]%4)==0)
leap_year=1;//闰年标志位,1为闰年
else
leap_year=0;
if(date[0]>Month_max[leap_year][date[1]])
date[0]=Month_max[leap_year][date[1]];
page=1;
if(date[1]>1)
date[1]--;
else
date[1]=12;
}
else if(choise==5)
{
if((date[2]%4)==0)
leap_year=1;//闰年标志位,1为闰年
else
leap_year=0;
if(date[0]>Month_max[leap_year][date[1]])
date[0]=Month_max[leap_year][date[1]];
page=1;
if(date[2]>0)
date[2]--;
else
date[2]=99;
}
break;
default: ;
}
glitter[choise]=(glitter[choise]+1)%(Glitter_time+Glitter_time);//用来控制被选中的位亮或灭
Display(page);
}
}
//*******************************************
//主函数
void main(void)
{
ClockInit();
while(1)
{
Key_process();
Clock();
Display(page);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -