资讯详情

51单片机项目设计:基于51单片机时钟万年历

文章目录

  • 一、项目功能
  • 二、材料选择
  • 三、原理图设计
  • 四、PCB设计
  • 五、程序设计
视频链接: https://www.bilibili.com/video/BV1EF411z7im/ 资料链接: https://pan.baidu.com/s/1PkHsZd0ICn4OJIsMDl8BKA 提取码:p49y

实物购买链接:https://market.m.taobao.com/app/idleFish-F2e/widle-taobao-rax/page-detail?wh_weex=true&wx_navbar_transparent=true&id=662070040156&ut_sk=1.YS8KcP50tCcDANBMdqHJmYUj_21407387_1639229141078.copy.detail.662070040156.2054314811&forceFlush=1

一、项目功能

1.可显示当前时间、周期和日期 2.当前时间、周期和日期可以修改 3.环境温度可以获得并显示LCD 4.当时间到达蜂鸣器并按下按钮时,可以设置闹钟并关闭

二、材料选择

(1)主控选择:STC89C52RC STC89C52是耗低,性能高CMOS8位微控制器,8位K可编程系统Flash存储器。在单芯片上,有灵巧的8位CPU和可编程系统Flash,使得STC89C为众多嵌入式控制应用系统提供高灵活性、超有效性的解决方案。

在这里插入图片描述

(2)显示屏选择:LCD1602 LCD1602液晶显示广泛使用的字符型液晶显示模块。它是由字符型液晶显示屏制成的(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100和少量电阻、电容元件和结构件组装在一起PCB板上而成。不同厂家生产LCD1602芯片可能不同,但使用方法相同。为了降低成本,绝大多数制造商直接在板上制作裸片。

(3)时钟芯片选择:DS1302 DS1302是由美国DALLAS公司推出了具有涓细电流充电能力的低功耗实时钟芯片。可计时年、月、日、周、时、分、秒,具有闰年补偿等功能。

(4)温度传感器选择:DS18B20 DS18B20是一种常用的数字温度传感器,输出数字信号,体积小,硬件成本低,抗干扰能力强,精度高。 [1] DS18B20数字温度传感器接线方便,包装后可应用于管道、螺纹、磁铁吸附、不锈钢包装、各种型号LTM8877,LTM8874等等。

(5)外围设备:按键、蜂鸣器、开关、纽扣电池、电位器、三极管等。

三、原理图设计

(一)最小系统 电源、晶体振动、复位电路 (二)显示电路 数据线接到P0,注意要接1K上拉电阻 (三)时钟芯片电路 三个引脚接到单片机IO口控制 (4)按键电路 (5)温度传感器 (6)电源电路和电源指示

四、PCB设计

五、程序设计

/************************************************************************************** *项目:51单片机时钟万年历设计 *作者:化作尘 *版本:V1.1 *邮箱:2809786963@qq.com *时间:2020年12月1日16:43:51 *比利比利视频地址:https://www.bilibili.com/video/BV1VQ4y1M79K *注:闹钟按实物设计,不能模拟,使用内部eeprom ***************************************************************************************/  #include "reg52.h" ///本文件定义了单片机的一些特殊功能寄存器 #include "ds1302.h" #include "temp.h" #include "lcd.h"
#include "eeprom.h"

sbit k1 = P1^0;	  		//按键
sbit k2 = P1^1;			 
sbit k3 = P1^2;
sbit k4 = P1^3;

sbit lcdled = P2^4;	 		 //lcd背光
sbit beep = P1^4;			//蜂鸣器

unsigned int ti=0,alarm=0;       //修改第几个时间参数 、修改第几个闹钟参数
unsigned char alarm_hour=0x12,alarm_min=0x00;	 //闹钟时、分参数

enum Mode				//定义枚举、三种模式
{ 
        
	DISPLAYDATA,MODIFYDATA,SETALARMCLOCK,NONE,ALARMCLOCK
}mode;

enum Alarmswitch	 //定义闹钟开关
{ 
        
	OFF,ON
}alarmswitch;

/*********延时函数***********/		  
void delay(unsigned int t)	 //短延时
{ 
        
 	while(t--);
}
void delay_ms(unsigned int t)	//毫秒延时
{ 
        
	unsigned int a,b;
	for(a=0;a<t;a++)
	for(b=0;b<120;b++);
}

/********显示日期、时间、星期***********/
void display_data(void)
{ 
        
	LcdWriteCom(0x80);
	LcdWritestr("20");	
	LcdWriteData(TIME[6]/16+0x30);	  //年
	LcdWriteData(TIME[6]%16+0x30);
	LcdWriteData('-');
	LcdWriteData(TIME[4]/16+0x30);	  //月
	LcdWriteData(TIME[4]%16+0x30);
	LcdWriteData('-');
	LcdWriteData(TIME[3]/16+0x30);	  //日
	LcdWriteData(TIME[3]%16+0x30);

	LcdWritestr(" ");
	switch(TIME[5])					   //显示星期
	{ 
        		
		case 0:LcdWritestr("Mon"); break;
		case 1:LcdWritestr("Tue"); break;
		case 2:LcdWritestr("Wed"); break;
		case 3:LcdWritestr("Thu"); break;
		case 4:LcdWritestr("Fri"); break;
		case 5:LcdWritestr("Sat"); break;
		case 6:LcdWritestr("Sun"); break;
	}
	if(alarmswitch==ON)LcdWriteData('.');
	else LcdWriteData(' ');

	LcdWriteCom(0xC0);
	LcdWriteData(' ');
	LcdWriteData(TIME[2]/16+0x30);	  //时
	LcdWriteData(TIME[2]%16+0x30);
	LcdWriteData(':');
	LcdWriteData(TIME[1]/16+0x30);	  //分
	LcdWriteData(TIME[1]%16+0x30);
	LcdWriteData(':');
	LcdWriteData(TIME[0]/16+0x30);	  //秒
	LcdWriteData(TIME[0]%16+0x30);
	LcdWritestr(" ");
}

/*********显示温度***********/
void displaytemp(int temp) 	 //显示温度
{ 
        
   	float tp;  
	static char flag = 1;
	if(temp< 0)			
  	{ 
        
		LcdWriteCom(0xca);
		LcdWriteData('-'); 
		temp=temp-1;
		temp=~temp;
		tp=temp;
		temp=tp*0.0625*100+0.5;	
 
  	}
 	else
  	{ 
        			
		LcdWriteCom(0xca);
		LcdWriteData('+'); 
		tp=temp;
		temp=tp*0.0625*100+0.5;	
	}
		if(flag)
		{ 
        
			flag =0;
			temp = 2600;
		}
	if(temp==8500)
		return ;
	LcdWriteData(temp % 10000 / 1000 + 0x30);
	LcdWriteData(temp % 1000 / 100  + 0x30);
	LcdWriteData('.');
	LcdWriteData(temp % 100 / 10 + 0x30);
	LcdWriteData(temp % 10 + 0x30);
}


/******************************************************************************* * 函 数 名 : keypros * 函数功能 : 按键处理函数,判断按键K1是否按下 *******************************************************************************/
void keypros()		   //初始页面按键检测
{ 
        
	if(k1 == 0)			   //切换模式
	{ 
        
		delay(1000);   //消除抖动 一般大约10ms
		if(k1==0)	 //再次判断按键是否按下
		{ 
        
			mode+= 1;if(mode == 3)mode = DISPLAYDATA;
		}
		while(k1 == 0);
	}
	else if(k2 == 0)			  //蜂鸣器测试
	{ 
        
		delay(1000);   //消除抖动 一般大约10ms
		if(k2==0)	 //再次判断按键是否按下
		{ 
        
			beep = !beep;  
		}
		while(k2 == 0);
	}
	else if(k3 == 0)		   //背光灯测试
	{ 
        
		delay(1000);   //消除抖动 一般大约10ms
		if(k3==0)	 //再次判断按键是否按下
		{ 
        
			lcdled = !lcdled;  
		}
		while(k3 == 0);
	}
	else if(k4 == 0)			//背光灯测试
	{ 
        
		delay(1000);   //消除抖动 一般大约10ms
		if(k4==0)	 //再次判断按键是否按下
		{ 
        
			alarmswitch=!alarmswitch;  
		}
		while(k4 == 0);
	}		
}

/*************修改时间************/
void modify(void)
{ 
        
	static int time=0;
	time++;
	if(k1 == 0)			//切换模式
	{ 
        
		delay(1000);   //消除抖动 一般大约10ms
		if(k1==0)	 //再次判断按键是否按下
		{ 
        
			mode+= 1;if(mode == 3)mode = DISPLAYDATA;
		}

		while(k1 == 0);
	}
	else if(k2 == 0)		   //选择修改参数
	{ 
        
		delay(1000);   //消除抖动 一般大约10ms
		if(k2==0)	 //再次判断按键是否按下
		{ 
        
			ti++; 
			if(ti == 8)ti=0; 
		}
		while(k2 == 0);
	}
	else if(k3 == 0 ||k4 == 0)
	switch(ti)				   //选择进入修改参数
	{ 
        
		case 0:
						if(k4==0 | k3==0)
						{ 
        
							delay(1000);   //消除抖动 一般大约10ms
							if(k4==0 | k3 ==0)	 //再次判断按键是否按下
							{ 
        
							   TIME[0]=0;
							}
							while(k4 == 0 | k3==0);
						}
						
						break;    //?
		case 1:
						if(k3==0)
						{ 
        
							delay(1000);   //消除抖动 一般大约10ms
							if(k3 ==0)	 //再次判断按键是否按下
							{ 
        
							   TIME[1]++;
							   if(TIME[1]%16 == 0x0a)
							   { 
        
							   		TIME[1] += 16;
									TIME[1] &= 0xf0;
							   }if(TIME[1]==0x60)TIME[1]=0;
							}
							while(k3==0);
						}
						if(k4==0)
						{ 
        
							delay(1000);   //消除抖动 一般大约10ms
							if(k4 ==0)	 //再次判断按键是否按下
							{ 
        
							   TIME[1]--;
							   if(TIME[1]%16==0x0f && TIME[1]!=0xff)
							   { 
        
									TIME[1] &= 0xf9;
							   }
							   if(TIME[1]==0xff)TIME[1]=0x59;
							}
							while(k4==0);
						}
						break;    //?
		case 2:
						if(k3==0)
						{ 
        
							delay(1000);   //消除抖动 一般大约10ms
							if(k3 ==0)	 //再次判断按键是否按下
							{ 
        
							   TIME[2]++;
							   if(TIME[2]%16 == 0x0a)
							   { 
        
							   		TIME[2] += 16;
									TIME[2] &= 0xf0;
							   }if(TIME[2]==0x24)TIME[2]=0;
							}
							while(k3==0);
						}
						if(k4==0)
						{ 
        
							delay(1000);   //消除抖动 一般大约10ms
							if(k4 ==0)	 //再次判断按键是否按下
							{ 
        
							   TIME[2]--;
							   if(TIME[2]%16==0x0f && TIME[2]!=0xff)
							   { 
        
									TIME[2] &= 0xf9;
							   }
							   if(TIME[2]==0xff)TIME[2]=0x23;
							}
							while(k4==0);
						}
						break;    //?
		case 3:
						if(k3==0)
						{ 
        
							delay(1000);   //消除抖动 一般大约10ms
							if(k3 ==0)	 //再次判断按键是否按下
							{ 
        
							   TIME[3]++;
							   if(TIME[3]%16 == 0x0a)
							   { 
        
							   		TIME[3] += 16;
									TIME[3] &= 0xf0;
							   }if(TIME[3]==0x32)TIME[3]=0;
							}
							while(k3==0);
						}
						if(k4==0)
						{ 
        
							delay(1000);   //消除抖动 一般大约10ms
							if(k4 ==0)	 //再次判断按键是否按下
							{ 
        
							   TIME[3]--;
							   if(TIME[3]%16==0x0f && TIME[3]!=0xff)
							   { 
        
									TIME[3] &= 0xf9;
							   }
							   if(TIME[3]==0xff)TIME[3]=0x31;
							}
							while(k4==0);
						}
						break;	 //日
		case 4:
					
						if(k3==0)
						{ 
        
							delay(1000);   //消除抖动 一般大约10ms
							if(k3 ==0)	 //再次判断按键是否按下
							{ 
        
							   TIME[4]++;
							   if(TIME[4]%16 == 0x0a)
							   { 
        
							   		TIME[4] += 16;
									TIME[4] &= 0xf0;
							   }if(TIME[4]==0x13)TIME[4]=0;
							}
							while(k3==0);
						}
						if(k4==0)
						{ 
        
							delay(1000);   //消除抖动 一般大约10ms
							if(k4 ==0)	 //再次判断按键是否按下
							{ 
        
							   TIME[4]--;
							   if(TIME[4]%16==0x0f && TIME[4]!=0xff)
							   { 
        
									TIME[4] &= 0xf9;
							   }
							   if(TIME[4]==0xff)TIME[4]=0x12;
							}
							while(k4
        标签: y1三极管电流wx11电位器三极管2sk2654三极管1y1

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台