博主福利:100G+电子设计学习资源包!
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar sec = 6, min = 6, hou = 6, a = 0, b = 0, c = 0;
uchar num = 0, cmd = 0;
uint time = 0;
uint flag = 0;
sbit P30 = P3^0;
sbit P35 = P3^5;
sbit P32 = P3^2;
sbit P33 = P3^3;
uchar code tab[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0xbf, 0xff, 0xc6};//数码管显示数字
void delay(uchar i);
void time_rec();
void display();
void displaym();
void keyscan();
void led_display();
void init();
void delay(uchar i)
{
uchar j;
while ((i--) != 0)
{
for(j = 0; j < 125; j--);
}
}
void time_rec()
{
if(sec == 60)
{
sec = 0;
min ++;
if(min == 60)
{
min = 0;
hou ++;
if(hou == 24)
{
hou = 0;
}
}
}
}
void display()
{
P1 = 0X01;//位选第一个数码管
P2 = 0x20;//打开段选
P0 = tab[hou / 10];//显示数字
P2 &= 0x1f;//关闭段选
P2 = 0xff;
delay(4);
P1 = 0x02;
P2 = 0x20;
P0 = tab[hou % 10];
P2 &= 0x1f;
delay(4);
P1 = 0x04;
P2 = (P2&0x1f)|0x20;
P0 = 0xbf;
P2 &= 0x1f;
delay(4);
P1 = 0x08;
P2 = (P2&0x1f)|0x20;
P0 = tab[min / 10];
P2 &= 0x1f;
delay(4);
P1 = 0x10;
P2 = (P2&0x1f)|0x20;
P0 = tab[min % 10];
P2 &= 0x1f;
delay(4);
P1 = 0x20;
P2 = (P2&0x1f)|0x20;
P0 = 0xbf;
P2 &= 0x1f;
delay(4);
P1 = 0x40;
P2 = (P2&0x1f)|0x20;
P0 = tab[sec / 10];
P2 &= 0x1f;
delay(4);
P1 = 0x80;
P2 = (P2&0x1f)|0x20;
P0 = tab[sec % 10];
P2 &= 0x1f;
delay(4);
}
void keyscan()
{
if(P35 == 0)
{
delay(5);
if(P35 == 0)
{
cmd = cmd + 1;
}
while(P35 == 0) {display();}
}
if(P32 == 0)
{
delay(5);
if(P32 == 0)
{
EX0 = 1;
}
while(P32 == 0) {display();}
}
if(P33 == 0)
{
delay(5);
if(P33 == 0)
{
EX1 = 1;
}
while(P33 == 0) {display();}
}
}
void init()
{
ET0 = 1;
TMOD = 0x11; //time0为定时器,方式1
TH0 = (65535 - 50000) / 256; //预置计算初值
TL0 = (65535 - 50000) % 256;
ET1 = 1;
TH1 = 0xff;
TL1 = 0xff;
IT0 = 1; //低电平有效
IT1 = 1;
TR0 = 1; //为1时启动计数
TR1 = 1;
EA = 1;
}
int main()
{
P3 = 0xff; //初始化P3口,全设为1
init();
while(1)
{
display();
time_rec();
keyscan();
}
return 0;
}
void timer_0() interrupt 1
{
TH0 = (65535 - 50000) / 256;
TL0 = (65535 - 50000) % 256;
time++;
if(time == 20)
{
if(flag == 0)
{
sec++;
time = 0;
}
else
{
time = 0;
}
}
}
void T1_int() interrupt 3 using 2 //中断T1 用于 可在时间校准的减
{
if(cmd != 0)
{
cmd = 0;
TH1=0xff;
TL1=0xff;
switch(num)
{
case 1:hou = hou - 1;if(hou <= 0) hou = 23;break;
case 2:min = min - 1;if(min <= 0) min = 59;break;
case 3:sec = sec - 1;if(sec <= 0) sec = 59;break;
default:break;
}
}
}
void I0_int() interrupt 0 //外部中断0 用于校准时间在时、分、秒之间进行切换
{
num = num + 1;
if(num == 3)
{
flag = 1;
}
if(num == 4)
{
flag = 0;
num = 0; //退出调时功能
}
}
void I1_int() interrupt 2 //外部中断1 用于调时的加
{
EX1 =0;
switch(num)
{
case 1:hou = hou + 1;if(hou >= 24) hou = 0;break;
Case 2:min = min + 1;if(min >= 60) min = 0;break;
case 3:sec = sec + 1;if(sec >= 60) sec = 0;break;
default:break;
}
}