基于Proteus学习单片机系列(五)——定时器实现电子表

  项目下载

    点击下载

1. 电路图

  2. 程序

主函数

#include<reg51.h>
#include<DEFINE.c>
#include<KEY.c>
#include<DISPLAY.c>
void timer_isr()interrupt 1			  //中断服务函数
{
	TL0 = (65536-2000) %256;			  //TL0重置函数
	TH0 = (65536-2000)/256;			  //TH0重置函数
	cp++;
	if(cp>=250)       //0.5s
	{
		cp1++;
		cp = 0;
		flash = ~flash;        //0.5s  - 闪烁
		if(cp1>=2)    //1s
		{
			if(mode==0)		   //调整时,时间停止
			sec++;
			cp1 = 0;
			if(sec>=60)     //1min
			{
				min++;
				sec = 0;
				if(min>60)	 //1h
				{
					hour++;
					min = 0;
					if(hour>=24)hour = 0;
				}
			}
		}
	}
	P0 = 0xff;    //消隐
	switch(mode)
	{
		case 0:dis_play0();break;  //正常
		case 1:dis_play1();break;  //调时
		case 2:dis_play2();break;  //调分
		case 3:dis_play3();break;  //调秒
		case 4:dis_play4();break;  //调闹时
		case 5:dis_play5();break;  //调闹分
	}
	i++;
	if(i>=8)i = 0;	
}
void timer0_init()				   //中断初始化函数
{
	TMOD = 0x01;				  //方式一
	TL0 = (65536-2000)%256;		  //TL0 预置,65536十六进制低8位。
	TH0 = (65536-2000)/256;		  //TH0 预置,65536十六进制高8位。
	EA = 1;							//CPU中断开放 ,总中断打开
	ET0 = 1;						//定时计数器T0的溢出终端控制位,T0中断打开
	TR0 = 1;						//定时计数器T0的启停控制位,启动T0
}
void main()
{
	timer0_init();				   //timer0初始化,为中断做准备
	while(1)
	{
		key();
		if(hour == hour_n && min == min_n)	   //闹钟到时间,蜂鸣器响
		{
			P3_2 = !P3_2;
			delay(50);
		}
	}
 }

定义

#define uchar unsigned char;
#define uint unsigned int;
sbit key_set = P2^0;
sbit key_up = P2^1;
sbit key_down = P2^2;
sbit P3_0 = P3^0;
sbit P3_2 = P3^2; //蜂鸣器
sbit P2_4 = P2^4;
uchar sec = 45,min = 12,hour;
uchar sec_t,min_t,hour_t;
uchar min_n = 13,hour_n;
uchar cp,cp1;
uchar flash,mode,i;
code uchar seven_seg[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
			0x82,0xf8,0x80,0x90};


按键函数

void delay(unsigned int x)	//延时函数
{
	while(x--);
}
void key()				   //按键函数
{
	P2_4 = 0;
	if(key_set==0)		   //如果调整按键按下
	{
		delay(300);		   //消抖
		if(key_set==0)	   //如果调整按键真的按下
		{
			while(key_set==0);
			mode++;
			if(mode>=6)mode = 0;   //mode=0,退出调整
			hour_t = hour;
			min_t = min;
			sec_t = sec;
		}
	}
	if(key_up==0)				  //如果增加按键按下
	{
		delay(300);				  //消抖
		if(key_up==0)			  //如果增加按键真的按下
		{
			while(key_up==0);
			if(mode==1)hour_t++;if(hour_t>24)hour_t = 23;hour = hour_t;
			if(mode==2)min_t++;if(min_t>60)min_t = 59;min=min_t;
			if(mode==3)sec_t++;if(sec_t>60)sec_t = 59;sec = sec_t;
			if(mode==4)hour_n++;if(hour_n>24)hour_n = 23;
			if(mode==5)min_n++;if(min_n>60)min_n = 59;

		}
	}
	if(key_down==0)				 //如果减小按键按下
	{							 
		delay(300);				 //消抖
		if(key_down==0)			 //如果减小按键真的按下
		{
			while(key_down==0);
			if(mode==1)hour_t--;if(hour_t<0)hour_t = 0;hour = hour_t;
			if(mode==2)min_t--;if(min_t<0)min_t = 0;min=min_t;
			if(mode==3)sec_t--;if(sec_t<0)sec_t = 0;sec = sec_t;
			if(mode==4)hour_n--;if(hour_n<0)hour_n = 0;
			if(mode==5)min_n--;if(min_n<0)min_n = 0;

		}
	}
}

显示函数

void display(unsigned char x1,x2)
{
	P3_0 = 0;	  //锁存器关
	P0 = x1;	  //输入位选			 
	P3_0 = 1;	  //锁存器开
	P3_0 = 0;	  //锁存器关
	P0 = x2;	  //输入段选		
}
void dis_play0()			  //mode = 0 正常  显示
{
	switch(i)
	{
		case 0:display(0x01,seven_seg[sec%10]);break;	  //显示秒个位
		case 1:display(0x02,seven_seg[sec/10]);break;	  //显示秒十位
		case 2:display(0x04,0xbf|flash);break;			  //显示 -	  闪烁
		case 3:display(0x08,seven_seg[min%10]);break;	  //显示分个位
		case 4:display(0x10,seven_seg[min/10]);break;	  //显示分十位
		case 5:display(0x20,0xbf|flash);break;			  //显示 -    闪烁
		case 6:display(0x40,seven_seg[hour%10]);break;	  //显示时个位
		case 7:display(0x80,seven_seg[hour/10]);break;	  //显示时十位
	}
}
void dis_play1()			  //mode = 1 调时
{
	switch(i)
	{
		case 0:display(0x01,seven_seg[sec_t%10]);break;	  //显示调秒个位
		case 1:display(0x02,seven_seg[sec_t/10]);break;	  //显示调秒十位
		case 2:display(0x04,0xbf);break;				  //显示 -
		case 3:display(0x08,seven_seg[min_t%10]);break;	  //显示调分个位
		case 4:display(0x10,seven_seg[min_t/10]);break;	  //显示调分十位
		case 5:display(0x20,0xbf);break;				  //显示 -
		case 6:display(0x40,seven_seg[hour_t%10]|flash);break;	 //显示调时个位	   闪烁
		case 7:display(0x80,seven_seg[hour_t/10]|flash);break;	 //显示调时十位	   闪烁
	}
}
void dis_play2()			  //mode = 2 调分
{
	switch(i)
	{
		case 0:display(0x01,seven_seg[sec_t%10]);break;	  //显示调秒个位
		case 1:display(0x02,seven_seg[sec_t/10]);break;	  //显示调秒十位
		case 2:display(0x04,0xbf);break;				  //显示  -
		case 3:display(0x08,seven_seg[min_t%10]|flash);break;	  //显示调分个位   闪烁
		case 4:display(0x10,seven_seg[min_t/10]|flash);break;	  //显示调分十位   闪烁
		case 5:display(0x20,0xbf);break;						  //显示 -
		case 6:display(0x40,seven_seg[hour_t%10]);break;		  //显示调时个位
		case 7:display(0x80,seven_seg[hour_t/10]);break;		  //显示调时十位
	}
}
void dis_play3()			  //mode = 3 调秒
{
	switch(i)
	{
		case 0:display(0x01,seven_seg[sec_t%10]|flash);break;	  //显示调秒个位  闪烁
		case 1:display(0x02,seven_seg[sec_t/10]|flash);break;	  //显示调秒十位  闪烁
		case 2:display(0x04,0xbf);break;						  //显示 -
		case 3:display(0x08,seven_seg[min_t%10]);break;			  //显示调分个位
		case 4:display(0x10,seven_seg[min_t/10]);break;			  //显示调分十位
		case 5:display(0x20,0xbf);break;						  //显示 -
		case 6:display(0x40,seven_seg[hour_t%10]);break;		  //显示调时个位
		case 7:display(0x80,seven_seg[hour_t/10]);break;		  //显示调时十位
	}
}		
void dis_play4()			  //mode = 4 调闹时
{
	switch(i)
	{
		case 0:display(0x01,0xbf);break;						  //显示 -
		case 1:display(0x02,0xbf);break;						  //显示 -
		case 2:display(0x04,0xbf);break;						  //显示 -
		case 3:display(0x08,seven_seg[min_n%10]);break;			  //显示闹分个位
		case 4:display(0x10,seven_seg[min_n/10]);break;			  //显示闹分十位
		case 5:display(0x20,0xbf);break;						  //显示 -
		case 6:display(0x40,seven_seg[hour_n%10]|flash);break;	  //显示闹时个位    闪烁
		case 7:display(0x80,seven_seg[hour_n/10]|flash);break;	  //显示闹时十位    闪烁
	}
}
void dis_play5()			  //mode = 5 调闹分
{
	switch(i)
	{
		case 0:display(0x01,0xbf);break;						  //显示 -
		case 1:display(0x02,0xbf);break;						  //显示 -
		case 2:display(0x04,0xbf);break;						  //显示 -
		case 3:display(0x08,seven_seg[min_n%10]|flash);break;	  //显示闹分个位    闪烁
		case 4:display(0x10,seven_seg[min_n/10]|flash);break;	  //显示闹分十位	闪烁
		case 5:display(0x20,0xbf);break;						  //显示 -
		case 6:display(0x40,seven_seg[hour_n%10]);break;		  //显示闹时个位
		case 7:display(0x80,seven_seg[hour_n/10]);break;		  //显示闹时十位
	}
}


猜你喜欢

转载自blog.csdn.net/qq_39020934/article/details/80032206