• 方案介绍
  • 附件下载
  • 相关推荐
申请入驻 产业图谱

基于普中51单片机开发板电子钟闹钟LCD1602显示12-24时制切换

07/07 11:37
728
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

设计资料获取联系方式.doc

共1个文件

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

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

程序编译器:keil 4/keil 5

编程语言:C语言

设计编号:P21

1. 主要功能:

1、用 LCD 1602 作为显示设备,设计时钟功能;

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

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

扩展功能:

具有闹钟功能,可以通过按键设定闹钟时间;

能显示年月日星期,设置时间考虑大小月限制和自动设置星期;

12/24小时制有对应的指示灯。

主要硬件 51单片机 DS1302 LCD1602 独立按键 LED 蜂鸣器

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

img

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

资料下载链接:

P21 时钟闹钟LCD1602 12-24小时制切换
链接: https://pan.baidu.com/s/1l-JULY9Xw4hCJkXDrII3ug?pwd=w4us
提取码: w4us

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

2. 实物图:

img

3. 仿真

打开仿真工程,双击proteus中的单片机,选择hex文件路径,然后开始仿真。

img

显示时间的情况下,按下切换键进入设置模式,设置的变量闪烁,默认先设置年份,通过按键加和按键减调整,通过下一个按键切换设置月份,设置月份时同样通过加减键调整。如此类推设置日期,星期,时分秒。

img

设置好时钟后按下切换按键设置闹钟。同样通过按键加减调整闹钟时间,通过下一个按键切换设置时钟/分钟。

按下12/24小时制切换可以切换时制。上午显示AM,下午显示PM,方便区分时间。

img

4. 程序代码

img

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

#include <reg51.h>
#include "lcd1602.h"
#include"ds1302.h" 
完整代码见文章后面下载链接
#define uchar unsigned char
#define uint unsigned int
//功能设计:调整时间、调整闹钟、正常


sbit key2=P3^3;//下一个设置点
sbit key3=P3^2;//加
sbit key4=P3^0;//减
sbit key5=P3^1;//12,24小时制切换

sbit beep=P2^5;//蜂鸣器
sbit led_12=P2^0;//12小时制
sbit led_24=P2^1;//24小时制

//===============================================================
uchar mode=0;//模式	  设置,工作
uchar beep_flag=0;
uchar t=0;
uchar fen=1,shi=0;//闹钟分钟和闹钟时间设置
uchar cixu=0,flag=0;//小模式
uchar moshi=0;//12,24控制

uchar hang1[]="2000/00/00       ";//日期
uchar hang2[]="00:00:00         ";//时间
uchar hang3[]="00:00            ";	  //闹钟  时+分
unsigned char cnt = 0,cnt1,cnt2;	
void Delay1(uint j)//延时函数
{
    uchar i;
    for(;j>0;j--)
    { 	
		for(i=0;i<27;i++);
    }
} 

void suan()//正常显示的计算
{	
	uchar i=0;
	hang1[2]=(TIME[6]>>4)+0x30;
	hang1[3]=(TIME[6]&0x0f)+0x30;
	hang1[5]=(TIME[4]>>4)+0x30;
	hang1[6]=(TIME[4]&0x0f)+0x30;
	hang1[8]=(TIME[3]>>4)+0x30;
	hang1[9]=(TIME[3]&0x0f)+0x30;
//	hang1[12]=TIME[5]+0x30;
	switch(TIME[5])
	{
		case 0://星期数据为0时显示
				hang1[11]='S';
				hang1[12]='U';
				hang1[13]='N';
			   break;
		case 1://星期数据为1时显示
				hang1[11]='M';
				hang1[12]='O';
				hang1[13]='N';
			   break;
		case 2://星期数据为2时显示
				hang1[11]='T';
				hang1[12]='U';
				hang1[13]='E';
			   break;	
		case 3://星期数据为3时显示 
				hang1[11]='W';
				hang1[12]='E';
				hang1[13]='D';
			   break;	
		case 4://星期数据为4时显示
				hang1[11]='T';
				hang1[12]='H';
				hang1[13]='U';
			   break;	
	   	case 5://星期数据为5时显示
				hang1[11]='F';
				hang1[12]='R';
				hang1[13]='I';
			   break;	
		case 6://星期数据为6时显示
				hang1[11]='S';
				hang1[12]='T';
				hang1[13]='A';
			   break;	
		}

	if(moshi==0)//小时
	{
		hang2[0]=(TIME[2]>>4)+0x30;
		hang2[1]=(TIME[2]&0x0f)+0x30;
		hang2[11]=' ';
		hang2[12]=' ';
	}
	else
	{
		i=(TIME[2]>>4)*10+(TIME[2]&0x0f);
		if(TIME[2]<=0x12)
		{
			hang2[0]=i/10+0x30;
			hang2[1]=i%10+0x30;
			hang2[11]='A';
			hang2[12]='M';
		}
		else
		{
			hang2[0]=(i-12)/10+0x30;
			hang2[1]=(i-12)%10+0x30;
			hang2[11]='P';
			hang2[12]='M';
		}
	}
	hang2[3]=(TIME[1]>>4)+0x30;//分钟
	hang2[4]=(TIME[1]&0x0f)+0x30;
	hang2[6]=(TIME[0]>>4)+0x30;
	hang2[7]=(TIME[0]&0x0f)+0x30;
	hang3[0]=shi/10+0x30;
	hang3[1]=shi%10+0x30;
	hang3[3]=fen/10+0x30;
	hang3[4]=fen%10+0x30;
}

void xian()//显示
{
	suan();//计算
	if(mode==0)//正常
	{		
		write_string(1,0,hang1);
		write_string(2,0,hang2);
	}
	else
	{
		switch(cixu)
		{
			case 0:		 //年
				if(flag)
				{
					hang1[2]=(TIME[6]>>4)+0x30;
					hang1[3]=(TIME[6]&0x0f)+0x30;
				}
				else
				{
					hang1[2]=' ';
					hang1[3]=' ';
				}
				break;
			case 1:		 //月
				if(flag)
				{
					hang1[5]=(TIME[4]>>4)+0x30;
					hang1[6]=(TIME[4]&0x0f)+0x30;
				}
				else
				{
					hang1[5]=' ';
					hang1[6]=' ';
				}
				break;
			case 2:		 //日
				if(flag)
				{
					hang1[8]=(TIME[3]>>4)+0x30;
					hang1[9]=(TIME[3]&0x0f)+0x30;
				}
				else
				{
					hang1[8]=' ';
					hang1[9]=' ';
				}
				break;
			case 3:		 //星期
				if(flag)
				{
					hang1[12]=TIME[5]+0x30;
				}
				else
				{
					hang1[12]=' ';
				}
				break;
			case 4:		 //时
				if(flag)
				{
					hang2[0]=(TIME[2]>>4)+0x30;
					hang2[1]=(TIME[2]&0x0f)+0x30;
				}
				else
				{
					hang2[0]=' ';
					hang2[1]=' ';
				}
				break;
			case 5:		 //分
				if(flag)
				{
					hang2[3]=(TIME[1]>>4)+0x30;
					hang2[4]=(TIME[1]&0x0f)+0x30;
				}
				else
				{
					hang2[3]=' ';
					hang2[4]=' ';
				}
				break;
			case 6:		 //秒
				if(flag)
				{
					hang2[6]=(TIME[0]>>4)+0x30;
					hang2[7]=(TIME[0]&0x0f)+0x30;
				}
				else
				{
					hang2[6]=' ';
					hang2[7]=' ';
				}
				break;
			case 7:		 //时,闹钟
				if(flag)
				{
					hang3[0]=shi/10+0x30;
					hang3[1]=shi%10+0x30;
				}
				else
				{
					hang3[0]=' ';
					hang3[1]=' ';
				}
				break;
			case 8:		 //分,闹钟
				if(flag)
				{
					hang3[3]=fen/10+0x30;
					hang3[4]=fen%10+0x30;
				}
				else
				{
					hang3[3]=' ';
					hang3[4]=' ';
				}				
		}
		if(cixu<7)	//显示结果
		{
			write_string(1,0,hang1);
			write_string(2,0,hang2);
		}
		else
		{
			write_string(1,0,"CLOCK:          ");
			write_string(2,0,hang3);
		}
	}

}

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


//主函数
void main()
{ 
	uchar i,j,k;
    int year,month; 
//	TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
//	TH0=0X3C;	//定时50ms
//	TL0=0Xb0;	
//	ET0=1;//打开定时器0中断允许
//	EA=1;//打开总中断
//	TR0=1;//打开定时器
	TMOD = 0X11;					 //初始化定时器
	TH0 = (65536-50000)/256;		 //50ms计时初值
	TL0 =(65536-50000)%256;
	TH1 = (65536-1000)/256; 		 //1ms计时初值
	TL1 =(65536-1000)%256;
	EA = 1; 						 //开总中断
	ET0 = 1;						 //开T0中断
	TR0=1;
	ET1 = 1;						 //开T1中断
	TR1=0;

	init_1602();//LCD初始化
	write_string(1,0,hang1);
	write_string(2,0,hang2);
//	Ds1302ReadTime();//启动DS1302
	TIME[0]=0;
	Ds1302Init();
	cixu=8;//不设置

	while(1)
	{
		if(moshi){
			led_12=0;//12小时制指示灯亮
			led_24=1;
		}else{
			led_12=1;
			led_24=0;//24小时制指示灯亮
		}
		
	 	if(key5==0)//12,24切换
		{
			Delay1(200);
			if(key5==0){
				moshi=!moshi;
			}	
			while(!key5);
		}
		//判断
		k=0;
		i=(shi/10<<4)+shi%10;
		j=(fen/10<<4)+fen%10;
		if((TIME[2]==i)&&(TIME[1]==j)&&(TIME[0]==1))//闹钟开始 时分 秒=1
		{
			beep_flag=1;
		}

		if((TIME[2]==i)&&(TIME[1]==j)&&(TIME[0]>58))//闹钟结束
		{
			beep_flag=0;
		}

		if(beep_flag){
			//响铃
			TR1=1;
		}else{
			TR1=0;//不响
		}
		
		//按键检测
		if(key2==0)//功能
		{
			Delay1(200);
			if(key2==0){
				if(beep_flag){//手动关闹钟
					beep_flag=0;
				}else{
					if(mode==0){
						mode=1;
						cixu=0;
					}else{
						if(cixu<8){
							cixu++;
							if(cixu==3){	
								cixu=4;//跳过星期设置
							}
						}else{
							mode=0;
		//					cixu=0;
						}
					}
				}
			}
			while(!key2);
		}
		if(!key3&&mode==1)//加
		{
			switch(cixu)
			{
				case 0:	//年
					i=(TIME[6]>>4)*10+(TIME[6]&0X0F);
					if(i<99)
						i++;
					TIME[6]=(i/10<<4)+i%10;
					Ds1302Init();
					break;
				case 1:	//月
					i=(TIME[4]>>4)*10+(TIME[4]&0X0F);
					if(i<12)
						i++;
					TIME[4]=(i/10<<4)+i%10;
					Ds1302Init();
					break;
				case 2:	//日
					i=(TIME[3]>>4)*10+(TIME[3]&0X0F);
					year=((TIME[6]>>4)*10+(TIME[6]&0X0F)+2000);
				    month=(TIME[4]>>4)*10+(TIME[4]&0X0F);
					if(i<MonthDays(year,month)){
							i++;
					}
					
					TIME[3]=(i/10<<4)+i%10;

					Ds1302Init();
					break;
				case 3:	//星期
					i=(TIME[5]>>4)*10+(TIME[5]&0X0F);
					if(i<7)
						i++;
					TIME[5]=(i/10<<4)+i%10;
					Ds1302Init();
					break;
				case 4:	//时
					i=(TIME[2]>>4)*10+(TIME[2]&0X0F);
					if(i<23)
						i++;
					TIME[2]=(i/10<<4)+i%10;
					Ds1302Init();
					break;
				case 5:	//分
					i=(TIME[1]>>4)*10+(TIME[1]&0X0F);
					if(i<59)
						i++;
					TIME[1]=(i/10<<4)+i%10;
					Ds1302Init();
					break;
				case 6:	//秒
					i=(TIME[0]>>4)*10+(TIME[0]&0X0F);
					if(i<59)
						i++;
					TIME[0]=(i/10<<4)+i%10;
					Ds1302Init();
					break;
				case 7:	//闹钟,时
					if(shi<23)
						shi++;
					break;
				case 8:	//闹钟,分
					if(fen<59)
						fen++;
			}
			while(!key3);
		}
		if(!key4&&mode==1)//减
		{
			switch(cixu)
			{
				case 0:	//年
					i=(TIME[6]>>4)*10+(TIME[6]&0X0F);
					if(i>0)
						i--;
					TIME[6]=(i/10<<4)+i%10;
					Ds1302Init();
					break;
				case 1:	//月
					i=(TIME[4]>>4)*10+(TIME[4]&0X0F);
					if(i>1)
						i--;
					TIME[4]=(i/10<<4)+i%10;
					Ds1302Init();
					break;
				case 2:	//日
					i=(TIME[3]>>4)*10+(TIME[3]&0X0F);
					
					if(i>1)
						i--;
					TIME[3]=(i/10<<4)+i%10;
					Ds1302Init();
					break;
				case 3:	//星期
					i=(TIME[5]>>4)*10+(TIME[5]&0X0F);
					if(i>1)
						i--;
					TIME[5]=(i/10<<4)+i%10;
					Ds1302Init();
					break;
				case 4:	//时
					i=(TIME[2]>>4)*10+(TIME[2]&0X0F);
					if(i>0)
						i--;
					TIME[2]=(i/10<<4)+i%10;
					Ds1302Init();
					break;
				case 5:	//分
					i=(TIME[1]>>4)*10+(TIME[1]&0X0F);
					if(i>0)
						i--;
					TIME[1]=(i/10<<4)+i%10;
					Ds1302Init();
					break;
				case 6:	//秒
					i=(TIME[0]>>4)*10+(TIME[0]&0X0F);
					if(i>0)
						i--;
					TIME[0]=(i/10<<4)+i%10;
					Ds1302Init();
					break;
				case 7:	//闹钟,时
					if(shi>0)
						shi--;
					break;
				case 8:	//闹钟,分
					if(fen>0)
						fen--;
			}
			while(!key4);
		}
	}
}

void Timer0() interrupt 1 //定时器0中断
{
	
	if(t<2)
		t++;
	else
	{
		t=0;
		flag=!flag;
		Ds1302ReadTime();//读取时间
		xian();

	}
	TH0=0X3C;	//定时50ms
	TL0=0Xb0;



5. 设计报告

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

img

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

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

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

1、程序

2、proteus仿真

3、功能要求

4、软硬件流程图

5、开题报告

6、设计报告

7、烧录工具

8、讲解视频

9、实物图

Altium Designer 安装破解

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

KEIL安装破解

Proteus元器件查找

Proteus安装

Proteus简易使用教程

单片机学习资料

相关数据手册

答辩技巧

设计报告常用描述

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

img

资料下载链接(可点击):
P21 时钟闹钟LCD1602 12-24小时制切换
链接: https://pan.baidu.com/s/1l-JULY9Xw4hCJkXDrII3ug?pwd=w4us

提取码: w4us

  • 设计资料获取联系方式.doc
    下载

相关推荐