基于51单片机电子钟闹钟数码管显示12-24时制切换( proteus仿真+程序+设计报告+讲解视频)

仿真图proteus8.17(有低版本)

程序编译器:keil 4/keil 5

编程语言:C语言

设计编号:P22

1主要功能:

1、用 7 段数码管作为显示设备,设计时钟功能;

2、可以分别调校小时、分钟和秒,复位后时间为00:00:00,并可设置为24 或 12 小时格式;

3、可以有其他扩展功能。

扩展功能:

具有闹钟功能,可以通过按键设定闹钟时间,默认闹钟时间是00:01;

12/24小时制有对应的指示灯,上午下午具有指示灯显示。

主要硬件 51单片机 DS1302 数码管 独立按键 LED

(目前仅完全适配普中51-实验板234,其他普中开发板型号需要接线)

img

需注意仿真中51单片机芯片是兼容的,AT89C51,AT89C52是51单片机的具体型号,内核是一样的。相同的原理图里,无论stc还是at都一样,引脚功能都是一样的,程序是兼容的,芯片可以替换为STC89C52/STC89C51/AT89C52/AT89C51等51单片机芯片。

资料下载链接:

P系列单片机设计下载链接(复制到浏览器打开)

https://docs.qq.com/doc/DS2pPenNRaHB6SlR1

以下为本设计资料展示图:

2.实物图:

显示的时间是09:01:13

img

普中实验板上的指示灯说明

img

3.仿真设计

打开仿真工程,双击proteus中的单片机,选择hex文件路径,然后开始仿真。开始仿真后数码管显示时间00:00:00。时间逐秒递增。

img

显示时间的情况下,按下设置键进入设置模式,时钟闪烁表示当前正在设置时钟,再按下设置键进入分钟设置模式,分钟闪烁,再按下设置键进入秒钟设置模式,秒钟闪烁。设置完秒钟再按设置退出设置模式,数码管正常显示。

未进入设置状态下,按键+作为切换按键,切换显示12/24小时制。12小时制下具有灯光指示是上午还是下午,以此实现AM/PM只是。

img

按下功能切换按键显示闹钟时间。闹钟时间显示下按下设置键进入闹钟设置模式,时钟闪烁表示当前正在设置闹钟时钟,再按下设置键进入闹钟分钟设置模式,闹钟分钟闪烁,再按下设置键进入闹钟秒钟设置模式,闹钟秒钟闪烁。设置完秒钟再按设置退出设置模式,数码管正常显示闹钟时间。

闹钟时间到,蜂鸣器闹铃,蜂鸣器响持续6s。

4.程序代码

使用keil4或者keil5编译,代码有注释,可以结合视频理解代码含义。

#include "reg51.h"			 //此文件中定义了单片机的一些特殊功能寄存器
#include"ds1302.h"

typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;

sbit beep=P2^5;//蜂鸣器	   
sbit led_clock=P2^0;
sbit led_data=P2^1;
sbit led_alarm=P2^6;

sbit key1=P3^0;//功能切换.时间/闹钟
sbit key2=P3^1;//选择时、分、秒(按第4次确认)
sbit key3=P3^2;//加
sbit key4=P3^3;//减 

完整代码见文章下载链接

sbit smg1=P2^2;	//74LS138
sbit smg2=P2^3;
sbit smg3=P2^4;


u8 mode=0;//模式。0时间1闹钟
u8 cixu=0;//设置模式。1时2分3秒

u16 time=0;//计时变量,1s
u8 beep_flag=0,beep_flag0=0;//蜂鸣器标志
u8 shi0=0,fen0=1,miao0=0;//闹钟
u8 code smgduan0[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//显示0~9,无小数点
u8 code smgduan1[11]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0x40};//显示0~9,有小数点
u8 flag=0;

void delay(u16 i)//延时
{
while(i--);
}

void display1()//显示时间
{

	if((cixu==3)&& flag)
	  {

	  }
	else
	  {

		P0=0;smg3=0;smg2=0;smg1=0;P0=smgduan0[ds1302_time[0]%10];delay(50); //当前显示是时钟
		P0=0;smg3=0;smg2=0;smg1=1;P0=smgduan0[ds1302_time[0]/10];delay(50);
	  }
	  P0=0;smg3=0;smg2=1;smg1=0;P0=0x40;delay(50);
	if((cixu==2)&& flag)
	  {

	  }
	else
	  {

	  P0=0;smg3=0;smg2=1;smg1=1;P0=smgduan0[ds1302_time[1]%10];delay(50);   //当前显示是分钟
	  P0=0;smg3=1;smg2=0;smg1=0;P0=smgduan0[ds1302_time[1]/10];delay(50);

	  }

	 P0=0;smg3=1;smg2=0;smg1=1;P0=0x40;delay(50);
	if((cixu==1)&& flag)
	  {

	  }
	else
	  {
		P0=0;smg3=1;smg2=1;smg1=0;P0=smgduan0[ds1302_time[2]%10];delay(50); //当前显示是秒钟
		P0=0;smg3=1;smg2=1;smg1=1;P0=smgduan0[ds1302_time[2]/10];delay(50);
	  }


}

void display2()//显示日期
{
if((cixu==1)&& flag)
  {

  }
else
  {
	P0=0;smg3=1;smg2=1;smg1=1;P0=smgduan0[2];delay(50);
	P0=0;smg3=1;smg2=1;smg1=0;P0=smgduan0[0];delay(50);
	P0=0;smg3=1;smg2=0;smg1=1;P0=smgduan0[ds1302_time[6]/10];delay(50);//
	P0=0;smg3=1;smg2=0;smg1=0;P0=smgduan1[ds1302_time[6]%10];delay(50);

  }

if((cixu==2)&& flag)
  {

  }
else
  {
	P0=0;smg3=0;smg2=1;smg1=1;P0=smgduan0[ds1302_time[4]/10];delay(50); //当前显示是月份
	P0=0;smg3=0;smg2=1;smg1=0;P0=smgduan1[ds1302_time[4]%10];delay(50);

  }

if((cixu==3)&& flag)
  {

  }
else
  {
	P0=0;smg3=0;smg2=0;smg1=1;P0=smgduan0[ds1302_time[3]/10];delay(50);  //当前显示是日期
	P0=0;smg3=0;smg2=0;smg1=0;P0=smgduan0[ds1302_time[3]%10];delay(50);

  }
}

void display3()//显示闹钟
{
if((cixu==1)&& flag)
  {

  }
else
  {

	P0=0;smg3=1;smg2=1;smg1=1;P0=smgduan0[shi0/10];delay(50); //当前显示是时钟
	P0=0;smg3=1;smg2=1;smg1=0;P0=smgduan0[shi0%10];delay(50);	
  }

if((cixu==2)&& flag)
  {

  }
else
  {

	  P0=0;smg3=1;smg2=0;smg1=0;P0=smgduan0[fen0/10];delay(50);   //当前显示是分钟
	  P0=0;smg3=0;smg2=1;smg1=1;P0=smgduan0[fen0%10];delay(50);	
  }

if((cixu==3)&& flag)
  {

  }
else
  {

  P0=0;smg3=0;smg2=0;smg1=1;P0=smgduan0[miao0/10];delay(50); //当前显示是秒钟
  P0=0;smg3=0;smg2=0;smg1=0;P0=smgduan0[miao0%10];delay(50);

  }
}
/*******************************************************************************
* 函 数 名         : Timer0Init
* 函数功能		   : 定时器0初始化
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Timer0Init()
{
	TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
	TH0=0Xfc;	//给定时器赋初值,定时1ms
	TL0=0X18;	
	ET0=1;//打开定时器0中断允许
	EA=1;//打开总中断
	TR0=1;//打开定时器			
}
/*******************************************************************************
* 函 数 名         : MonthDays
* 函数功能		   : 得到当月的天数
* 输    入         : 年月日
* 输    出         : 月份天数
*******************************************************************************/
int MonthDays(int year, int month) { //区分闰年大小月
    int days;  
  
    if (month == 2) { // 二月份  
        if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) { // 闰年2月29天,其他年份28天  
            days = 29;  
        } else {  
            days = 28;  
        }  
    } else if (month == 4 || month == 6 || month == 9 || month == 11) { // 四、六、九、十一月份各30天  
        days = 30;  
    } else { // 其他月份各31天  
        days = 31;  
    }  
  
    return days;  
}  


/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	
	uchar k=0;
	Ds1302Init();
	Timer0Init();  //定时器0初始化
	beep=0;
	mode=0;

	while(1)
	{

	  if(mode==0){
	  	display1();//显示时间
		led_clock=0; //对应的灯亮
		led_data=1;
		led_alarm=1;
	  }

	  
	  if(mode==1){
	  	display2();//显示日期
		led_clock=1; //对应的灯亮
		led_data=0;
		led_alarm=1;
	  }
	
	  if(mode==2){
	  	 display3();//显示闹钟
		led_clock=1; //对应的灯亮
		led_data=1;
		led_alarm=0;
	  }
	

	  if(!key1 &&(k!=1))	//功能切换
	  {
	  	k=1;cixu=0;
		if(mode<2)
			mode++;
		else
			mode=0;
	  }
	  if(!key2 &&(k!=2))//选择
	  {
	  	if(cixu<3)
			cixu++;
		else
			cixu=0;
	  	k=2;
	  }
	  if(!key3 &&(k!=3))		//加
	  {
	  	k=3;
		if(mode==0)//时间
		{
		  switch(cixu)
		  {
		  case 1:
		  	if(ds1302_time[2]<23)
				ds1302_time[2]++;
				Ds1302Init();
				break;
		  case 2:
		  	if(ds1302_time[1]<59)
				ds1302_time[1]++;
				Ds1302Init();
				break;
		  case 3:
		  	if(ds1302_time[0]<59)
				ds1302_time[0]++;
				Ds1302Init();
		  }
		}
		if(mode==1)//日期
		{
		  switch(cixu)
		  {
		  case 1:
		  	if(ds1302_time[6]<50)
				ds1302_time[6]++;
				Ds1302Init();
				break;
		  case 2:
		  	if(ds1302_time[4]<12)
				ds1302_time[4]++;
				Ds1302Init();
				break;
		  case 3:
		  	if(ds1302_time[3]<MonthDays((ds1302_time[6]+2000),ds1302_time[4]))
				ds1302_time[3]++;
				Ds1302Init();
		  }
		}
		if(mode==2)//闹钟
		{
		  switch(cixu)
		  {
		  case 1:
		  	if(shi0<23){
				shi0++;
			}else{
				shi0=0;
			}

				break;
		  case 2:
		  	if(fen0<59){
				fen0++;
			}else{
				fen0=0;
			}

				break;
		  case 3:
		  	if(miao0<59){
				miao0++;
			}else{
				miao0=0;
			}
		  }
		}
	  }
	  if(!key4 &&(k!=4))		//减
	  {
	  	k=4;
		if(mode==0)//时间
		{
		  switch(cixu)
		  {
		  case 1:
		  	if(ds1302_time[2]>0)
				ds1302_time[2]--;
				Ds1302Init();
				break;
		  case 2:
		  	if(ds1302_time[1]>0)
				ds1302_time[1]--;
				Ds1302Init();
				break;
		  case 3:
		  	if(ds1302_time[0]>0)
				ds1302_time[0]--;
				Ds1302Init();
		  }
		}
		if(mode==1)//日期
		{
		  switch(cixu)
		  {
		  case 1:
		  	if(ds1302_time[6]>0)
				ds1302_time[6]--;
				Ds1302Init();
				break;
		  case 2:
		  	if(ds1302_time[4]>0)
				ds1302_time[4]--;
				Ds1302Init();
				break;
		  case 3:
		  	if(ds1302_time[3]>0)
				ds1302_time[3]--;
				Ds1302Init();
		  }
		}
		if(mode==2)//闹钟
		{
		  switch(cixu)
		  {
		  case 1:
		  	if(shi0>0){
				shi0--;
			}else{
				shi0=23;
			}
				
				break;
		  case 2:
		  	if(fen0>0){
				fen0--;
			}else{
				fen0=59;
			}

				break;
		  case 3:
		  	if(miao0>0){
				miao0--;
			}else{
				miao0=59;
			}

		  }
		}
	  }
//	  if(!key5)	//停止响铃
//	   {
//		beep_flag=0;
//	   }
	  if(key1 && key2 && key3 && key4)//按键清零
	  	k=0;
	  if((ds1302_time[2]==shi0)&&(ds1302_time[1]==fen0)&&(ds1302_time[0]<15))//判断响铃
	  {
	  	 beep_flag=1;
	  }else{
	  	beep_flag=0;
	  }
	}		
}



5.设计报告

6138字设计报告,内容包括硬件设计、软件设计、软硬件框图、调试、结论等

img

6.设计资料内容清单&&下载链接

资料设计资料包括仿真,程序代码、讲解视频、功能要求、设计报告、软硬件设计框图等。

img

0、常见使用问题及解决方法–必读!!!!

1、程序

2、proteus仿真

3、功能要求

4、软硬件流程图

5、开题报告

6、设计报告

7、烧录工具

8、讲解视频

9、实物图

Altium Designer 安装破解

KEIL+proteus 单片机仿真设计教程

KEIL安装破解

Proteus元器件查找

Proteus安装

Proteus简易使用教程

单片机学习资料

相关数据手册

答辩技巧

设计报告常用描述

鼠标双击打开查找嘉盛单片机51 STM32单片机课程毕业设计.url

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐