⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 电子钟.c

📁 51单片机制作的电子钟
💻 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 + -