基于51单片机万年历设计—显示温度农历

基于51单片机万年历设计

(仿真+程序+原理图+设计报告)

功能介绍

具体功能:

本系统采用单片机+DS1302时钟芯片+LCD1602液晶+18b20温度传感器+按键+蜂鸣器设计而成。

1.可以显示年月日、时分秒、星期、温度值。

2.DS18B20测温;

3.按键可设置时间、闹钟,切换农历查看;

​演示视频:

基于51单片机万年历设计—显示温度农历 

添加图片注释,不超过 140 字(可选)

程序

#include <reg52.h>	         //调用单片机头文件
/***公众号:木子单片机****/
#define uchar unsigned char  //无符号字符型 宏定义	变量范围0~255
#define uint  unsigned int	 //无符号整型 宏定义	变量范围0~65535
#include "eeprom52.h"
#include "nongli.h"bit flag_200ms ;
bit flag_100ms ;
sbit beep = P3^7;	  //蜂鸣器定义
bit flag_beep_en;
uint clock_value;     //用作闹钟用的sbit dq   = P3^1;	  //18b20 IO口的定义uint temperature ;    //温度变量
uchar flag_nl;        //农历 阳历显示标志位uchar menu_1,menu_2;uchar key_time,flag_value;      //用做连加的中间变量
bit key_500ms  ;
uchar n_nian,n_yue,n_ri;		//农历显示的函数#include "ds1302.h"
#include "lcd1602.h"/******************把数据保存到单片机内部eeprom中******************/
void write_eeprom()
{SectorErase(0x2000);byte_write(0x2000, fen1);byte_write(0x2001, shi1);byte_write(0x2002, open1);byte_write(0x2058, a_a);	
}/******************把数据从单片机内部eeprom中读出来*****************/
void read_eeprom()
{fen1  = byte_read(0x2000);shi1  = byte_read(0x2001);open1  = byte_read(0x2002);a_a      = byte_read(0x2058);
}/**************开机自检eeprom初始化*****************/
void init_eeprom()
{read_eeprom();		//先读if(a_a != 1)		//新的单片机初始单片机内问eeprom{fen1  = 3;shi1  = 8;open1  = 1;a_a = 1;write_eeprom();	   //保存数据}	
}/***********************18b20初始化函数*****************************/
void init_18b20()
{bit q;dq = 1;				//把总线拿高delay_uint(1);	    //15usdq = 0;				//给复位脉冲delay_uint(80);		//750usdq = 1;				//把总线拿高 等待delay_uint(10);		//110usq = dq;				//读取18b20初始化信号delay_uint(20);		//200usdq = 1;				//把总线拿高 释放总线
}/*************写18b20内的数据***************/
void write_18b20(uchar dat)
{uchar i;for(i=0;i<8;i++){					 //写数据是低位开始dq = 0;			 //把总线拿低写时间隙开始 dq = dat & 0x01; //向18b20总线写数据了delay_uint(5);	 // 60usdq = 1;			 //释放总线dat >>= 1;}	
}/*************读取18b20内的数据***************/
uchar read_18b20()
{uchar i,value;for(i=0;i<8;i++){dq = 0;			 //把总线拿低读时间隙开始 value >>= 1;	 //读数据是低位开始dq = 1;			 //释放总线if(dq == 1)		 //开始读写数据 value |= 0x80;delay_uint(5);	 //60us	读一个时间隙最少要保持60us的时间}return value;		 //返回数据
}/*************读取温度的值 读出来的是小数***************/
uint read_temp()
{uint value;uchar low;			   //在读取温度的时候如果中断的太频繁了,就应该把中断给关了,否则会影响到18b20的时序init_18b20();		   //初始化18b20write_18b20(0xcc);	   //跳过64位ROMwrite_18b20(0x44);	   //启动一次温度转换命令delay_uint(50);		   //500usinit_18b20();		   //初始化18b20write_18b20(0xcc);	   //跳过64位ROMwrite_18b20(0xbe);	   //发出读取暂存器命令EA = 0;low = read_18b20();	   //读温度低字节value = read_18b20();  //读温度高字节EA = 1;value <<= 8;		   //把温度的高位左移8位value |= low;		   //把读出的温度低位放到value的低八位中value *= 0.625;	       //转换到温度值 小数return value;		   //返回读出的温度 带小数
}/******************1ms 延时函数*******************/
void delay_1ms(uint q)
{uint i,j;for(i=0;i<q;i++)for(j=0;j<120;j++);
}/******************写星期函数*******************/
void write_week(uchar hang,uchar add,uchar week)//写星期函数
{if(hang==1)   write_com(0x80+add);elsewrite_com(0x80+0x40+add);	  switch(week){case 1:write_data('M');//星期数为1时,显示write_data('O');write_data('N');break;case 2:write_data('T');//星期数据为2时显示write_data('U');write_data('E');break;case 3:write_data('W');//星期数据为3时显示write_data('E');write_data('D');break;case 4:write_data('T');//星期数据为4是显示write_data('H');write_data('U');break;case 5:write_data('F');//星期数据为5时显示write_data('R');write_data('I');break;case 6:write_data('S');//星期数据为6时显示write_data('T');write_data('A');break;case 0:write_data('S');//星期数据为7时显示write_data('U');write_data('N');break;}
}/*************时钟显示***************/
void init_1602_ds1302()
{write_sfm2_ds1302(1,1,shi);		   //显示时write_sfm2_ds1302(1,4,fen);		   //显示分write_sfm2_ds1302(1,7,miao);	   //显示秒write_week(2,12,week);
//	write_sfm1(1,14,week);			   //显示星期write_sfm3_18B20(1,11,temperature);	   //显示温度if(flag_nl == 0)  //显示阳历{write_sfm2_ds1302(2,2,nian);   //显示年write_sfm2_ds1302(2,5,yue);	   //显示月	write_sfm2_ds1302(2,8,ri);	   //显示日 	}else 			 //显示农历{write_sfm2_ds1302(2,2,n_nian);	//显示年write_sfm2_ds1302(2,5,n_yue);	//显示月	write_sfm2_ds1302(2,8,n_ri);	//显示日 }}									   /*************定时器0初始化程序***************/
void init_time0()	  
{EA   = 1;	 	  //开总中断TMOD = 0X01;	  //定时器0、工作方式1ET0  = 1;		  //开定时器0中断 TR0  = 1;		  //允许定时器0定时
}/*************闹钟报警函数***************/
void menu_dis()
{static uchar mm,value;if(flag_100ms == 1)		  //100ms执行一次{flag_100ms = 0;if(open1 == 1)	//如果闹钟打开{if((miao == 0) && (fen == fen1) && (shi == shi1)) {		flag_beep_en = 1;	//有报警 打开蜂鸣器响的标志位				}		if(flag_beep_en == 1)	//闹钟以被打开{clock_value++;if(clock_value <= 30)	 beep = ~beep;	   //蜂鸣器叫3秒else if(clock_value > 30){beep = 1;		    //蜂鸣器停1秒if(clock_value > 40){clock_value = 0;}}//  1 分钟后自动关闭闹钟value ++;if(value >= 10){value = 0;mm++;if(mm >= 60){mm = 0;flag_beep_en = 0;beep = 1;	}}					}}	}
}/********************独立按键程序*****************/
uchar key_can;	 //按键值void key()	 //独立按键程序
{static uchar key_new;key_can = 20;                   //按键值还原P3 |= 0x78;                     //对应的按键IO口输出为1if((P3 & 0x78) != 0x78)		//按键按下{delay_1ms(1);	     	//按键消抖动if(((P3 & 0x78) != 0x78) && (key_new == 1)){						//确认是按键按下key_new = 0;switch(P3 & 0x78){case 0x70:  key_can = 4;  break;	 //得到按键值case 0x68:  key_can = 3;  break;	 //得到按键值case 0x58:  key_can = 2;  break;	 //得到按键值case 0x38:  key_can = 1;  break;	 //得到按键值}
//			write_sfm2(1,0,key_can);				 //显示按键值}			}else key_new = 1;	
}/**********************设置函数************************/
void key_with()
{if(key_can == 1)	//设置键{menu_1++;if(menu_1 == 1)	  //设置时间{menu_2 = 1;write_string(1,0,"    :  :    W:  ");			write_string(2,0," 20  -  -       ");	}if(menu_1 == 2)	  //设置闹钟{menu_2 = 1;write_string(1,0,"   set clock    ");			write_string(2,0,"    Y  00:00      ");	}if(menu_1 > 2)    //回到正常显示{menu_1 = 0;write_guanbiao(1,2,0);	 //关闭光标init_1602_dis_csf();      //初始化液晶显示		}}if(key_can == 2)	//选择键{flag_200ms = 1;if(menu_1 == 1)		  //设置时间{menu_2 ++;if(menu_2 > 7)menu_2 = 1;}if(menu_1 == 2)		 //设置闹钟{menu_2 ++;if(menu_2 > 3)menu_2 = 1;				}}if(menu_1 == 1){if(menu_2 == 1)		  //设置时{if(key_can == 3)	//加{shi+=0x01;if((shi & 0x0f) >= 0x0a)shi = (shi & 0xf0) + 0x10;if(shi >= 0x24)shi = 0;}		if(key_can == 4)	//减{if(shi == 0x00)shi = 0x24;if((shi & 0x0f) == 0x00)shi = (shi | 0x0a) - 0x10;shi -- ; }	  				}if(menu_2 == 2)		  //设置分{if(key_can == 3)	//加{fen+=0x01;if((fen & 0x0f) >= 0x0a)fen = (fen & 0xf0) + 0x10;if(fen >= 0x60)fen = 0;}		if(key_can == 4)	//减	  {if(fen == 0x00)fen = 0x5a;if((fen & 0x0f) == 0x00)fen = (fen | 0x0a) - 0x10;fen -- ;}	}if(menu_2 == 3)		  //设置秒{if(key_can == 3)	//加{miao+=0x01;if((miao & 0x0f) >= 0x0a)miao = (miao & 0xf0) + 0x10;if(miao >= 0x60)miao = 0;}	if(key_can == 4)	//减	  {if(miao == 0x00)miao = 0x5a;if((miao & 0x0f) == 0x00)miao = (miao | 0x0a) - 0x10;miao -- ;			}}if(menu_2 == 4)		  //设置星期{if(key_can == 3)	//加{week+=0x01;if((week & 0x0f) >= 0x0a)week = (week & 0xf0) + 0x10;if(week >= 0x08)week = 1;}		if(key_can == 4)	//减	  {if(week == 0x01)week = 0x08;if((week & 0x0f) == 0x00)week = (week | 0x0a) - 0x10;week -- ;}	}if(menu_2 == 5)		  //设置年{if(key_can == 3)	//加{nian+=0x01;if((nian & 0x0f) >= 0x0a)nian = (nian & 0xf0) + 0x10;if(nian >= 0x9a)nian = 1;}		if(key_can == 4)	//减	  {if(nian == 0x01)nian = 0x9a;if((nian & 0x0f) == 0x00)nian = (nian | 0x0a) - 0x10;nian -- ;		}	}if(menu_2 == 6)		  //设置月{if(key_can == 3)	//加{yue+=0x01;if((yue & 0x0f) >= 0x0a)yue = (yue & 0xf0) + 0x10;if(yue >= 0x13)yue = 1;}		if(key_can == 4)	//减	  {if(yue == 0x01)yue = 0x13;if((yue & 0x0f) == 0x00)yue = (yue | 0x0a) - 0x10;yue -- ;					}	}if(menu_2 == 7)		  //设置日{if(key_can == 3)	//加{ri+=0x01;if((ri & 0x0f) >= 0x0a)ri = (ri & 0xf0) + 0x10;if(ri >= 0x32)ri = 0;			}		if(key_can == 4)	//减	  {if(ri == 0x01)ri = 0x32;if((ri & 0x0f) == 0x00)ri = (ri | 0x0a) - 0x10;ri -- ;			}	}write_sfm2_ds1302(1,2,shi);	   //显示时write_sfm2_ds1302(1,5,fen);	   //显示分write_sfm2_ds1302(1,8,miao);	   //显示秒write_sfm1(1,14,week);	   //显示星期					write_sfm2_ds1302(2,3,nian);	   //显示年write_sfm2_ds1302(2,6,yue);	   //显示月write_sfm2_ds1302(2,9,ri);	   //显示日switch(menu_2)	   // 光标显示{case 1:  write_guanbiao(1,2,1);  break;case 2:  write_guanbiao(1,5,1);  break;case 3:  write_guanbiao(1,8,1);  break;case 4:  write_guanbiao(1,14,1);  break;case 5:  write_guanbiao(2,3,1);  break;case 6:  write_guanbiao(2,6,1);  break;case 7:  write_guanbiao(2,9,1);  break;}write_time();	   //把时间写进去}	
/***************设置闹钟*********************/if(menu_1 == 2){if(menu_2 == 1)		  //设置闹钟开关{if(key_can == 3)	{open1 = 1;	  //闹钟开}		if(key_can == 4)	{open1 = 0;	  //闹钟关}	  				}if(menu_2 == 2)		  //设置闹钟时{if(key_can == 3)	//加{shi1+=0x01;if((shi1 & 0x0f) >= 0x0a)shi1 = (shi1 & 0xf0) + 0x10;if(shi1 >= 0x24)shi1 = 0;}		if(key_can == 4)	//减	  {if(shi1 == 0x00)shi1 = 0x5a;if((shi1 & 0x0f) == 0x00)shi1 = (shi1 | 0x0a) - 0x10;shi1 -- ;}	}if(menu_2 == 3)		  //设置秒{if(key_can == 3)	//加{fen1+=0x01;if((fen1 & 0x0f) >= 0x0a)fen1 = (fen1 & 0xf0) + 0x10;if(fen1 >= 0x60)fen1 = 0;}	if(key_can == 4)	//减	  {if(fen1 == 0x00)fen1 = 0x5a;if((fen1 & 0x0f) == 0x00)fen1 = (fen1 | 0x0a) - 0x10;fen1 -- ;			}}if(open1 == 1)write_string(2,4,"Y");	else write_string(2,4,"N");	write_sfm2_ds1302(2,7,shi1);	   //显示闹钟时write_sfm2_ds1302(2,10,fen1);	   //显示闹钟分switch(menu_2)	   // 光标显示{case 1:  write_guanbiao(2,4,1);  break;case 2:  write_guanbiao(2,7,1);  break;case 3:  write_guanbiao(2,10,1);  break;}	write_eeprom();     //保存闹钟时间}			
}/*****************主函数********************/

硬件设计

使用元器件:

单片机:STC89C52;

(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)

蜂鸣器;电池座;

直插电解电容;直插瓷片电容;

LCD1602液晶显示器;

DC电源插座;排针4-Pin;

PNP 三极管;色环电阻;

按键6X6X5MM;12MHZ晶振;

自锁开关;DS18B20;

导线:若干;

添加图片注释,不超过 140 字(可选)

流程图:

 

设计资料

01仿真图

本设计使用proteus7.8和proteus8.9两个版本设计!具体如图!

添加图片注释,不超过 140 字(可选)

02原理图

本系统原理图采用Altium Designer19设计,具体如图!

添加图片注释,不超过 140 字(可选)

03程序

本设计使用软件keil5版本编程设计!具体如图!

添加图片注释,不超过 140 字(可选)

04设计报告

一万字设计报告,具体如下!

添加图片注释,不超过 140 字(可选)

05设计资料

        资料获取请关注同名公众号,全部资料包括仿真源文件 、AD原理图、程序(含注释)、任务书、开题报告、设计报告、流程图、实物图、元件清单、实物演示视频等。具体内容如下,全网最全! !

 

可以关注下方公众号!

点赞分享一起学习成长。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/853915.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《书生·浦语大模型实战营》第4课 学习笔记:XTuner 微调 LLM:1.8B、多模态、Agent

文章大纲 1. 大模型微调简介2 快速上手2.1 环境安装2.2 前期准备2.2.1 数据集准备2.2.2 模型准备2.2.3 配置文件选择2.2.4 小结 2.3 配置文件修改2.4 模型训练2.4.1 常规训练2.4.2 使用 deepspeed 来加速训练2.4.3 训练结果2.4.4 小结 2.5 模型转换、整合、测试及部署2.5.1 模型…

【QT5】<重点> QT串口编程

目录 前言 一、串口编程步骤 0. 添加串口模块 1. 自动搜索已连接的串口 2. 创建串口对象 3. 初始化串口 4. 打开串口 5. 关闭串口 6. 发送数据 7. 接收数据 二、简易串口助手 1. 实现效果 2. 程序源码 3. 实现效果二 前言 本篇记录QT串口编程相关内容&#xff0…

登录MySQL方式

登录MySQL方式 方式一&#xff1a;通过MySQL自带的客户端 MySQL 客户端输入命令即可 方式二&#xff1a;通过window自带的客户端 从命令端&#xff08;cmd&#xff09;进入 mysql -h localhost -P 3306 -u root -p Enter password:密码登录方式&#xff1a; mysql -h 主…

深入理解指针(四)

目录 1. 回调函数是什么? ​2. qsort使用举例 2.1冒泡排序 2.2使用qsort函数排序整型数据 ​2.3 使用qsort排序结构数据(名字) 2.4 使用qsort排序结构数据(年龄) 3. qsort函数的模拟实现 1. 回调函数是什么? 回调函数就是⼀个通过函数指针调⽤的函数。 如果你把函数…

混淆矩阵-召回率、精确率、准确率

混淆矩阵 1 混淆矩阵2 混淆矩阵指标2.1 准确率2.2 精确率2.3 召回率2.4 特异度2.4 假正率2.5 假负率2.6 F1 分数 3 总结 1 混淆矩阵 混淆矩阵是一种用于评估分类模型性能的重要工具。它通过矩阵形式清晰地展示了模型对样本进行分类的结果&#xff0c;帮助我们理解模型在不同类…

【嵌入式】CAN总线详解

【嵌入式】CAN总线详解 一、CAN总线简介 CAN总线是一种控制器局域网总线&#xff0c;每一个挂载在CAN局域网的设备&#xff0c;都可以利用CAN去发送信息&#xff0c;也可以接收局域网的各种信息&#xff0c;每个设备都是平等的&#xff0c;共享CAN的资源。广泛应用于汽车、嵌…

LabVIEW程序的常见加密方式

LabVIEW程序的加密对于保护知识产权和敏感数据至关重要。本文将详细介绍LabVIEW程序常用的加密方式&#xff0c;包括VI加密、代码保护、文件加密和通信加密等&#xff0c;帮助开发者选择合适的加密方法来确保程序的安全性和完整性。 LabVIEW程序的常见加密方式 VI加密&#xf…

【宠粉赠书】科研绘图神器:MATLAB科技绘图与数据分析

小智送书第二期~ 为了回馈粉丝们的厚爱&#xff0c;今天小智给大家送上一套科研绘图的必备书籍——MATLAB科技绘图与数据分析。下面我会详细给大家介绍这套图书&#xff0c;文末留有领取方式。 图书介绍 《MATLAB科技绘图与数据分析》是一本综合性强、内容丰富的书籍&#x…

Mybatis做批量操作

动态标签foreach&#xff0c;做过批量操作&#xff0c;但是foreach只能处理记录数不多的批量操作&#xff0c;数据量大了后&#xff0c;先不说效率&#xff0c;能不能成功操作都是问题&#xff0c;所以这里讲一讲Mybatis正确的批量操作方法&#xff1a; 在获取opensession对象…

哈喽GPT-4o——对GPT-4o 提示词的思考与看法

目录 一、提示词二、常用的提示词案例1、写作助理2、改写为小红书风格3、英语翻译和改写4、论文式回答5、主题解构6、提问助手7、Nature风格润色8、结构总结9、编程助手10、充当终端/解释器 大家好&#xff0c;我是哪吒。 最近&#xff0c;ChatGPT在网络上广受欢迎&#xff0c…

PDFFactoryFinePrint软件安装包下载+详细安装教程

简介&#xff1a; pdfFactory Pro(虚拟打印机)是一个无须 Acrobat 创建 Adobe PDF 文件的打印机驱动程序。 pdffactory pro虚拟打印机提供了比其他程序提供得更简单、更有效率和更少的花费的创建 PDF 文件的解决方案。用于需要安全的 PDF(法律文档、公司信息等)和其他高级功能…

js实现一个数据结构——栈

栈的概念就不再赘述&#xff0c;无可厚非的先进后出&#xff0c;而JS又是高级语言&#xff0c;数组中的方法十分丰富&#xff0c;已经自带了push pop方法进行入栈出栈的操作。 1.基本实现 class Stack {constructor() {this.items [];}// 入栈push(item) {this.items.push(i…

List 列表

文章目录 一、什么是 List 列表1.1 创建 List 列表的方式1.2 列表的新增函数方法1.3 列表的删除函数方法1.4 修改列表数据的方法1.5 列表的查询函数方法1.6 列表的排序和反序1.7 列表的复制 一、什么是 List 列表 List 列表&#xff1a;该数据类型定义的变量可以理解为是一个数…

【Java】已解决java.lang.NoClassDefFoundError异常

文章目录 一、问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决java.lang.NoClassDefFoundError异常 一、问题背景 java.lang.NoClassDefFoundError 是 Java 运行时环境&#xff08;JRE&#xff09;在尝试加载某个类时&#xff0c;但没有找到…

基于51单片机贪吃蛇小游戏

基于51单片机贪吃蛇小游戏 &#xff08;仿真&#xff0b;程序&#xff09; 功能介绍 具体功能&#xff1a; 1.用74HC573驱动点阵显示游戏画面&#xff1b; 2.上电后贪吃蛇会自动寻食&#xff1b; 3.按下四个按键中的任何一个就手动寻食了&#xff1b; ​演示视频&#xf…

库的制作 与 使用 (Linux下)

目录 动静态库的制作 前置知识 库的基本构造 问题 分析 要给什么文件 如何更好的让别人使用 库的生成 静态库的生成 makefile参考 动态库的生成 makefile参考&#xff08;包含动态库和静态库生成&#xff09; 库的使用 法一&#xff1a;放入系统路径 弊端 法二…

半导体芯片结构以及译码驱动

一.半导体芯片结构 可能并不是只有一个芯片&#xff0c;有多个芯片就需要片选线了。 二.半导体存储芯片的译码驱动 主要有两种方式&#xff1a;线选法和重合法 线选法&#xff1a;每一个存储单元都用一根字选择线选中&#xff0c;直接选中存储单元的各位。&#xff08;一维…

《人生海海》读后感

麦家是写谍战的高手&#xff0c;《暗算》《风声》等等作品被搬上荧屏后&#xff0c;掀起了一阵一阵的收视狂潮。麦家声名远扬我自然是知道的&#xff0c;然而我对谍战似乎总是提不起兴趣&#xff0c;因此从来没有拜读过他的作品。这几天无聊时在网上找找看看&#xff0c;发现了…

C++11完美转发(引用折叠、万能引用)

完美转发是指在函数模板中&#xff0c;完全依照模板的参数的类型&#xff0c;将参数传递给函数模板中调用的另外一个函数。 函数模板在向其他函数传递自身形参时&#xff0c;如果相应实参是左值&#xff0c;它就应该被转发为左值&#xff1b;如果相 应实参是右值&#xff0c;它…

大数据入门实践一:mac安装Hadoop,Hbase,FLume

一、安装Hadoop 安装hadoop参考此文&#xff0c;关键点是安装JDK和Hadoop的配置&#xff0c;为避免引用文章变收费&#xff0c;我把关键信息摘录如下&#xff1a; jdk安装和配置就不说了(我本机安装了1.8/15/17/21&#xff0c;以17为主&#xff09;&#xff0c;hadoop安装过程…