电子时钟(全)

本文为博主 LED-执棋困局,csdn原创首发。希望看完后能对你有所帮助,不足之处请指正!一起交流学习,共同进步!
> 发布人:LED-执棋困局
> 欢迎你为独创博主LED-执棋困局点赞❤❤❤+关注👍+收藏🌹+评论☺。

系列专栏:CSDN-单片机学习系列🎁
> 我的格言是:“尽最大努力,做最好的自己!💪
版权声明:本文为CSDN博主「LCD-执棋困局」的原创文章,CSDN独一份。

如需转载,还请通知一声噢⚠!
————————————————
版权声明:本文为CSDN博主「LCD-执棋困局」的原创文章,转载请附上原文出处链接及本声明。

一、项目要求及全景

1.1项目要求

电子时钟:

1.能正常显示时分秒

2.可以调节时分秒三个参数,第一个按键可以控制要调节哪个参数,第二个按键将要调节的参数+1。

1.2项目全景

基于51单片机的电子时钟具有如下的全景:

  1. 安装方便:由于单片机体积小、可编程性强,因此制作出的电子时钟体积小巧,易于安装搭配。

  2. 显示效果好:采用LED数码管进行显示,可清晰地显示时间、日期等信息,还可以实现多种显示效果,例如闪烁、滚动等。

  3. 功能丰富:电子时钟可具备多种功能,例如自动校正、闹钟、倒计时、温度显示等。

  4. 低功耗:单片机功耗低,电子时钟可以采用电池供电,无需频繁更换电池。

  5. 系统稳定:单片机具有强大的自动校正能力,可保证电子时钟的时间准确度和系统的稳定性。

  6. 系统可靠性高:由于单片机系统的稳定性和可靠性比较高,因此电子时钟的故障率较低,使用寿命长。

  7. 制作过程简单:基于51单片机制作电子时钟的过程相对简单,不需要太多专业的电子知识,适合初学者入门学习。

二、系统原理

2.1定时原理

用到两个定时器,定时器T0定时1ms,用于延时,从而显示数码管(数码管要显示,需要4步,消隐-位码-线码-延时1ms),而定时器T1定时50ms,用于时分秒正常显示,20次50ms=1s,1s*60次=1min,1min*60次=1hour

2.2数码管显示原理

因为不同窗口wnd,数码管屏幕不同,需要分别写正常显示函数、调节时函数、调节分函数、调节秒函数,并写一个服务函数key_service(),根据wnd值,采用switch-case语句,将这四个函数分别显示到数码管屏幕上。

2.3切屏原理

定义窗口变量wnd,用于调节不同窗口

外部中断0,每按一次第一个按键,wnd加1,wnd>3时,wnd=0。

2.4调参数原理

外部中断1,秒变量min范围为0-60,min范围为0-60,hour范围为0-24,根据不同的wnd,调节不同的参数,每按一下按键,要调节的参数+1。

三、仿真图

70580ce9bd624cb898e1625184eb17fa.png

四、项目代码

4.1代码思路

定义窗口变量wnd、时参数变量hour、分参数变量min、秒参数变量sec。正常显示:用定时器T0定时1ms显示数码管,定时器T1定时50ms,累加20次,sec加1,再次基础上,sec累加60次,min加1,min累加60,hour加1。利用外部中断0,调节窗口wnd,利用外部中断1,根据不同wnd值,采用switch-case语句,用于调节参数,wnd=1时,hour++,wnd=2时,min++,wnd=3时,写sec++。不同窗口对于不同的显示屏幕,可以分别写正常显示函数、调节时函数、调节分函数、调节秒函数。

4.2主模块与子模块

4.2.1时分秒显示模块

窗口0,正常显示时分秒。

void Timer1_Init(void)		//50毫秒@12.000MHz
{
	TMOD &= 0x0F;			//设置定时器模式
	TMOD |= 0x10;			//设置定时器模式
	TL1 = 0xB0;				//设置定时初始值
	TH1 = 0x3C;				//设置定时初始值
	TF1 = 0;				//清除TF1标志
	ET1=1;
	//TR1 = 1;				//定时器1开始计时
}

void T1_timer() interrupt 3 //正常显示时分秒
{
	TR1=0;
	i++;
	if(i>=20)
	{
		i=0;
	  sec++;
	  if(sec>=60)
	  {
		  sec=0;
		  min++;
		  if(min>=60)
		  {
			  min=0;
			  hour++;
			  if(hour>=24)
			  {
				  hour=0;
			  }
		  }
	  }
	}
	TL1 = 0xB0;				//设置定时初始值
	TH1 = 0x3C;				//设置定时初始值
	TR1=1;
}

4.2.2数码管显示模块

数码管要显示,display()要利用定时器定时延时1ms。

void Timer0_Init(void)		//1毫秒@12.000MHz 定时器0
{
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	ET0=1;
	TR0 = 1;				//定时器0开始计时
}

void T0_timer() interrupt 1 //实现数码管动态刷新
{
	TR0=0;
	display();
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TR0=1;
}

display.c

#include "display.h"

unsigned char code leddata[]={
	              0x3F, //0
	              0x06, //1
                  0x5B, //2
	              0x4F, //3
	              0x66, //4																																																																		
	              0x6D, //5
	              0x7D, //6
	              0x07, //7
	              0x7F, //8
	              0x6F, //9
	              0x77, //A																																																																							
	              0x7C, //B
	              0x39, //C
	              0x5E, //D
	              0x79, //E
	              0x71, //F
	              0x76, //H
	              0x38, //L
	              0x37, //n
                  0x3E, //u	
	              0x73, //P																																																																	
	              0x5C, //o
	              0x40, //-
	              0x00  //熄灭
                             };//数码管段码表

unsigned char LEDBuf[]={0,0,0,0,0,0};//缓冲区
unsigned char code PLACE_COOE[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//位码
/******************************************************************************************
函数名:display
功能:数码管显示函数
参数:无
返回值:无
******************************************************************************************/
void display()
{
	static unsigned char i=0;
	switch(i)
	{
		case 0:
			IO_DIG=0x00;//消隐
			IO_DIG=leddata[LEDBuf[0]];//段码
	        IO_PLACE=PLACE_COOE[0];//位码
           i++;
		  break;
		case 1:
			IO_DIG=0x00;//消隐
			IO_DIG=leddata[LEDBuf[1]];//段码
	        IO_PLACE=PLACE_COOE[1];//位码
            i++;
		  break;
		case 2:
			IO_DIG=0x00;//消隐
			IO_DIG=leddata[LEDBuf[2]];//段码
	        IO_PLACE=PLACE_COOE[2];//位码
            i++;
		  break;
		case 3:
			IO_DIG=0x00;//消隐
			IO_DIG=leddata[LEDBuf[3]];//段码
	        IO_PLACE=PLACE_COOE[3];//位码
            i++;
		  break;
		case 4:
			IO_DIG=0x00;//消隐
			IO_DIG=leddata[LEDBuf[4]];//段码
	        IO_PLACE=PLACE_COOE[4];//位码
            i++;
		  break;
		case 5:
			IO_DIG=0x00;//消隐
			IO_DIG=leddata[LEDBuf[5]];//段码
	        IO_PLACE=PLACE_COOE[5];//位码
            i=0;
		  break;
	}
}

display.h

#ifndef __DISPLAY_H__
#define __DISPLAY_H__

#include <reg51.h>

#define IO_DIG   P0 //段码IO
#define IO_PLACE P2 //位码IO

#define N 6 //数码管个数

unsigned char code leddata[];//变量声明
extern unsigned char LEDBuf[];

void display();//数码管显示函数声明

#endif

4.2.3按键模块

外部中断0:用于调节窗口变量wnd

void EX0_init()
{
	IT0=1;
	EX0=1;
}


void EX0_timer() interrupt 0 //按键key1控制窗口
{
	wnd++;
	if(wnd==4)
		wnd=0;
}

外部中断1:调节时分秒

void EX1_init()
{
	IT1=1;
	EX1=1;
}

void EX1_timer() interrupt 2 //调节时分秒
{
  switch(wnd)
	{
		case 0:;break;
        case 1:TR1=0;hour++;if(hour>=24) hour=0;break;
		case 2:TR1=0;min++;if(min>=60) min=0;break;
        case 3:TR1=0;sec++;if(sec>=60) sec=0;break;
	}
}

调节参数在数码管的显示:

void key_service()//不同窗口的数码管显示
{
	switch(wnd)
	{
		case 0:TR1=1;dis_service();break;
		case 1:dishour();break;
		case 2:dismin();break;
		case 3:dissec();break;
	}
}

void dishour()//调节时的窗口显示
{
	LEDBuf[0]=hour/10;
	LEDBuf[1]=hour%10;
	LEDBuf[2]=23;
	LEDBuf[3]=23;
	LEDBuf[4]=23;
    LEDBuf[5]=23;
}

void dismin()//调节分的窗口显示
{
	LEDBuf[0]=23;
	LEDBuf[1]=23;
	LEDBuf[2]=min/10;
	LEDBuf[3]=min%10;
	LEDBuf[4]=23;
    LEDBuf[5]=23;
}

void dissec()//调节秒的窗口显示
{
	LEDBuf[0]=23;
	LEDBuf[1]=23;
	LEDBuf[2]=23;
	LEDBuf[3]=23;
	LEDBuf[4]=sec/10;
    LEDBuf[5]=sec%10;
}

void dis_service()//正常显示的窗口显示
{
    LEDBuf[0]=hour/10;
	LEDBuf[1]=hour%10;
	LEDBuf[2]=min/10;
	LEDBuf[3]=min%10;
	LEDBuf[4]=sec/10;
    LEDBuf[5]=sec%10;
}

4.2.4主模块

#include <reg51.h>
#include "display.h"
#include "key.h"

void Timer0_Init();
void Timer1_Init();
void key_service();
void EX0_init();
void EX1_init();
void dis_service();
void dishour();
void dismin();
void dissec();

unsigned char sec=0;
unsigned char min=0;
unsigned char hour=0;
unsigned char wnd=0;
unsigned char i=0;

void main()
{
	Timer0_Init();
	Timer1_Init();
	EX0_init();
	EX1_init();
	EA=1;
	while(1)
	{
		key_service();
	}
}

五、结果及扩展

5.1结果

窗口0(正常显示时分秒)

bf5eb3f31208441181541f7b268c8373.png

窗口1(调节时):

0b1dcfed7e954155aaa5c509b867138c.png

窗口2(调节分):

259061a0df3c4757bdcff1a5b0ac0fec.png

窗口3(调节秒):

f26ea18c900343039841563b4703bb87.png

调节时分秒:

091c34127ab74abc9d848495a2b60982.png

5.2功能扩展

本次电子时钟,参数主要是时、分、秒

电子时钟的功能可以扩展:

1.功能可以进行扩展,参数可以有年、月、日、时、分、秒

调节年参数时,要考虑闰年和平年;调节月参数时,要考虑2月份的天数。

2.闹钟,到一定时间时,让蜂鸣器发出声响。

———————————————————————————————————————————

本次介绍了电子时钟,同时提供模块代码和仿真图,帮助大家理解相关编码思路。

hi!我是博主LED-执棋困局🔥,喜欢或期待更好作品的,可以关注一下我LED-执棋困局🙏🙏🙏,我们一起进步,另外欢迎大家的点评😊!!!

关注博主:点击支持——LED-执棋困局
———————————————————————————————————————————

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值