基于51单片机的电子时钟课程设计

#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;
  }
}

                       

猜你喜欢

转载自blog.csdn.net/zzb_mx/article/details/80848843