基于51单片机的DS12C887电子钟万年历带农历温度

news2024/11/22 22:59:19

基于51单片机的DS12C887电子钟万年历( proteus仿真+程序+讲解视频)

仿真图proteus 7.8及以上

程序编译器:keil 4/keil 5

编程语言:C语言

设计编号:S0028

资料下载链接(可点击):

讲解视频

基于51单片机的DS12C887万年历带农历温度显示仿真设计

这里写目录标题

  • 基于51单片机的DS12C887电子钟万年历( proteus仿真+程序+讲解视频)
    • 讲解视频
    • 主要功能:
    • 仿真图
    • 程序:
    • 资料清单:

主要功能:

结合实际情况,基于51单片机设计一个电子钟万年历。该系统应满足的功能要求为:

DS12C887时钟芯片,LED显示、独立键盘、农历显示、温度显示。

具体功能:

1、采用DS12C887记录日历和时间。

2、 通过数码管显示,可以显示新历年月日时分秒,农历和星期,带有温度显示。

3、可以按照实际,通过按键设置日期、时间。

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

仿真图

主图

img

开始仿真

img

开始显示程序设置的初始时间,三组数码管分别显示年月日,时钟分钟秒、农历日期和温度。可以通过按键调整时间。

设置键按下第一下设置分钟,第二下设置时钟,第三下设置星期,第四下设置日期,第五下设置月份,第六下设置年份,第七下退出设置。通过按键DOWN和按键UP调整数值加减。如果已经调整好日期时间,按OUT按键可以退出设置。

程序:

img

img

ds12c887初始化和调用

#include "main.h"
#include "ds12c887.h"



void DS12C887_write(uchar add,uchar dat)  //写
{
	DS12C887_CS=0;
    DS12C887_AS=1;
	DS12C887_DS=1;
	DS12C887_WR=1;
	DS12C887_DATA=add;
	DS12C887_AS=0;
	DS12C887_WR=0;
	DS12C887_DATA=dat;
	DS12C887_WR=1;
	DS12C887_AS=1;
	DS12C887_CS=1;	
} 

uchar DS12C887_read(uchar add)	//读
{
	uchar ds_date;
	DS12C887_AS=1;
	DS12C887_DS=1;
	DS12C887_WR=1;
	DS12C887_CS=0;
	DS12C887_DATA=add;
	DS12C887_AS=0;
	DS12C887_DS=0;
	DS12C887_DATA=0xff;
	ds_date=DS12C887_DATA;
	DS12C887_DS=1;
	DS12C887_AS=1;
	DS12C887_CS=1;
	return ds_date;		
}

void DS12C887_Gettime()	   //获取DS12C887时间
{

	time_year  =DS12C887_read(0x09);	//年	
	time_month =DS12C887_read(0x08);	//月
	time_day  = DS12C887_read(0x07);	//日
	time_week  =DS12C887_read(0x06);	//周
	time_hour  =DS12C887_read(0x04);	//是
	time_min  = DS12C887_read(0x02);	//分
	time_sec =  DS12C887_read(0x00);	//秒
}

void DS12C887_Settime() ///设置初始时间
{
	DS12C887_write(0x09,0x16);	//年22	0x16->22
	DS12C887_write(0x08,0x0C);	//月12	0x0C->12
	DS12C887_write(0x07,0x0C);	//日11	0x0B->11
	DS12C887_write(0x06,0x01);	//周1	
	DS12C887_write(0x04,0x17);	//时23					 
	DS12C887_write(0x02,0x3B);	//分59
	DS12C887_write(0x00,0x32);	//秒50
}  

void DS12C887_init()	//DS12C887初始化
{
	DS12C887_write(0x0a,0x20); //DS12CR887寄存器A功能设置,开启时钟振荡器
	DS12C887_write(0x0b,0x06); //寄存器B功能设置,不开启闹钟中断使能,数据模式为二进制,24小时模式。		
} 		   

阴历计算

 /*
 函数功能:输入BCD阳历数据,输出BCD阴历数据(只允许1901-2099年)
 调用函数示例:Conversion(c_sun,year_sun,month_sun,day_sun)
 如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);
 c_sun,year_sun,month_sun,day_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世
 纪,c_sun=1为19世纪
 调用函数后,原有数据不变,读c_moon,year_moon,month_moon,day_moon得出阴历BCD数据
 */
 
 /*子函数,用于读取数据表中农历月的大月或小月,如果该月为大返回1,为小返回0*/
// /* static*/ unsigned char /*bit*/ get_moon_day(uchar month_p,uint table_addr)
//   {
//   uchar temp;
//       switch (month_p){
//           case 1:{temp=year_code[table_addr]&0x08;
//                if (temp==0)return(0);else return(1);}
//           case 2:{temp=year_code[table_addr]&0x04;
//                if (temp==0)return(0);else return(1);}
//           case 3:{temp=year_code[table_addr]&0x02;
//                if (temp==0)return(0);else return(1);}
//           case 4:{temp=year_code[table_addr]&0x01;
//                if (temp==0)return(0);else return(1);}
//           case 5:{temp=year_code[table_addr+1]&0x80;
//                if (temp==0) return(0);else return(1);}
//           case 6:{temp=year_code[table_addr+1]&0x40;
//                if (temp==0)return(0);else return(1);}
//           case 7:{temp=year_code[table_addr+1]&0x20;
//                if (temp==0)return(0);else return(1);}
//           case 8:{temp=year_code[table_addr+1]&0x10;
//                if (temp==0)return(0);else return(1);}
//           case 9:{temp=year_code[table_addr+1]&0x08;
//                if (temp==0)return(0);else return(1);}
//           case 10:{temp=year_code[table_addr+1]&0x04;
//                if (temp==0)return(0);else return(1);}
//           case 11:{temp=year_code[table_addr+1]&0x02;
//                if (temp==0)return(0);else return(1);}
//           case 12:{temp=year_code[table_addr+1]&0x01;		  
//                if (temp==0)return(0);else return(1);}
//           case 13:{temp=year_code[table_addr+2]&0x80;
//                if (temp==0)return(0);else return(1);}
//       }
//	 return(0);
//   }


/*月份数据表-----------------------------------------------------------------------------*/
static unsigned char  code day_code1[9]={0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3};
static unsigned short code day_code2[3]={0x111,0x130,0x14e};

/*子函数,用于读取数据表中农历月的大月或小月,如果该月为大返回1,为小返回0------------------*/
static unsigned char get_moon_day(unsigned char month_p,unsigned short table_addr)
{
	switch (month_p)
	{
		case 1:
			if((year_code[table_addr]&0x08)==0)		return(0);
			else 									return(1); 
		case 2:
			if((year_code[table_addr]&0x04)==0)		return(0);
			else 									return(1);
		case 3:
			if((year_code[table_addr]&0x02)==0)		return(0);
			else 									return(1);
		case 4:
			if((year_code[table_addr]&0x01)==0)		return(0);
			else 								    return(1);
		case 5:
			if((year_code[table_addr+1]&0x80)==0)	return(0);
			else 									return(1);
		case 6:
			if((year_code[table_addr+1]&0x40)==0)	return(0);
			else 									return(1);
		case 7:
			if((year_code[table_addr+1]&0x20)==0)	return(0);
			else 									return(1);
		case 8:
			if((year_code[table_addr+1]&0x10)==0)	return(0);
			else 									return(1);
		case 9:
			if((year_code[table_addr+1]&0x08)==0)	return(0);
			else 									return(1);
		case 10:
			if((year_code[table_addr+1]&0x04)==0)	return(0);
			else 									return(1);
		case 11:
			if((year_code[table_addr+1]&0x02)==0)	return(0);
			else 									return(1);
		case 12:
			if((year_code[table_addr+1]&0x01)==0)	return(0);
			else 									return(1);
		case 13:
			if((year_code[table_addr+2]&0x80)==0)	return(0);
			else 									return(1);
	}
	return(0);
}



  /*
  函数功能:输入BCD阳历数据,输出BCD阴历数据(只允许1901-2099年)
  调用函数示例:Conversion(c_sun,year_sun,month_sun,day_sun)
  如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);
  c_sun,year_sun,month_sun,day_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世
  纪,c_sun=1为19世纪
  调用函数后,原有数据不变,读c_moon,year_moon,month_moon,day_moon得出阴历BCD数据
  */

 void Conversion(bit c,uchar year,uchar month,uchar day)
 {                         //c=0 为21世纪,c=1 为19世纪 输入输出数据均为BCD数据
//     uchar c_moon,year_moon,month_moon,day_moon;
	 uchar temp1,temp2,temp3,month_p;
     uint temp4,table_addr;
     bit flag2,flag_y;
//     temp1=year/16;   //BCD->hex 先把数据转换为十六进制   这段要屏蔽掉,不然数码管显示乱码
//     temp2=year%16;
//     year=temp1*10+temp2;
//     temp1=month/16;
//     temp2=month%16;
//     month=temp1*10+temp2;
//     temp1=day/16;
//     temp2=day%16;
//     day=temp1*10+temp2;
     //定位数据表地址
   if(c==0)
  {                   
      table_addr=(year+0x64-1)*0x3;
  }
   else 
  {
     table_addr=(year-1)*0x3;
  }
     //定位数据表地址完成
     //取当年春节所在的公历月份
     temp1=year_code[table_addr+2]&0x60; 
     temp1=_cror_(temp1,5);
     //取当年春节所在的公历月份完成
     //取当年春节所在的公历日
     temp2=year_code[table_addr+2]&0x1f; 
     //取当年春节所在的公历日完成
     // 计算当年春年离当年元旦的天数,春节只会在公历1月或2月
     if(temp1==0x1)
  {  
         temp3=temp2-1;  
     }  
     else
  {
         temp3=temp2+0x1f-1;        
     }
     // 计算当年春年离当年元旦的天数完成
     //计算公历日离当年元旦的天数,为了减少运算,用了两个表
     //day_code1[9],day_code2[3]
     //如果公历月在九月或前,天数会少于0xff,用表day_code1[9],
     //在九月后,天数大于0xff,用表day_code2[3]
     //如输入公历日为8月10日,则公历日离元旦天数为day_code1[8-1]+10-1
     //如输入公历日为11月10日,则公历日离元旦天数为day_code2[11-10]+10-1
     if (month<10)
  { 
         temp4=day_code1[month-1]+day-1;
     }
     else
  {
         temp4=day_code2[month-10]+day-1;
     }
     
  if ((month>0x2)&&(year%0x4==0))
  {  
 //如果公历月大于2月并且该年的2月为闰月,天数加1
         temp4+=1;
     }
     //计算公历日离当年元旦的天数完成
     //判断公历日在春节前还是春节后
     if (temp4>=temp3){ //公历日在春节后或就是春节当日使用下面代码进行运算
         temp4-=temp3;
         month=0x1;
         month_p=0x1;  //month_p为月份指向,公历日在春节前或就是春节当日month_p指向首月
         flag2=get_moon_day(month_p,table_addr); 
 //检查该农历月为大小还是小月,大月返回1,小月返回0
         flag_y=0;
         if(flag2==0)temp1=0x1d; //小月29天
         else temp1=0x1e; //大小30天
         temp2=year_code[table_addr]&0xf0;
         temp2=_cror_(temp2,4);  //从数据表中取该年的闰月月份,如为0则该年无闰月
         while(temp4>=temp1){
             temp4-=temp1;
             month_p+=1;
             if(month==temp2){
             flag_y=~flag_y;
             if(flag_y==0)month+=1;
             }
             else month+=1;
             flag2=get_moon_day(month_p,table_addr);
             if(flag2==0)temp1=0x1d;
             else temp1=0x1e;
         }
         day=temp4+1;
     }
     else{  //公历日在春节前使用下面代码进行运算
         temp3-=temp4;
         if (year==0x0){year=0x63;c=1;}
         else year-=1;
         table_addr-=0x3;
         month=0xc;
         temp2=year_code[table_addr]&0xf0;
         temp2=_cror_(temp2,4);
         if (temp2==0)month_p=0xc; 
         else month_p=0xd; //
         /*
         month_p为月份指向,如果当年有闰月,一年有十三个月,月指向13,
 无闰月指向12
         */
         flag_y=0;
         flag2=get_moon_day(month_p,table_addr);
         if(flag2==0)temp1=0x1d;
         else temp1=0x1e;
         while(temp3>temp1){
             temp3-=temp1;
             month_p-=1;
             if(flag_y==0)month-=1;
             if(month==temp2)flag_y=~flag_y;
             flag2=get_moon_day(month_p,table_addr);
             if(flag2==0)temp1=0x1d;
             else temp1=0x1e;
          }
         day=temp1-temp3+1;
     }
//     c_moon=c;                 //HEX->BCD ,运算结束后,把数据转换为BCD数据
//     temp1=year/10;
//     temp1=_crol_(temp1,4);
//     temp2=year%10;
//     year_moon=temp1|temp2;
//     temp1=month/10;
//     temp1=_crol_(temp1,4);
//     temp2=month%10;
//     month_moon=temp1|temp2;
//     temp1=day/10;
//     temp1=_crol_(temp1,4);
//     temp2=day%10;
//     day_moon=temp1|temp2;


	c_moon=c;
	year_moon=year;
	month_moon=month;
	day_moon=day;


}

资料清单:

下载地址见文章开头
img

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

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

相关文章

通信协议综述-第2讲 | 网络分层的真实含义是什么?

长时间从事计算机网络相关的工作,我发现,计算机网络有一个显著的特点,就是这是一个不仅需要背诵,而且特别需要将原理烂熟于胸的学科。很多问题看起来懂了,但是就怕往细里问,一问就发现你懂得没有那么透彻。 我们上一节列了之后要讲的网络协议。这些协议本来没什么稀奇,每…

微服务框架 SpringCloud微服务架构 分布式缓存 41 Redis 持久化 41.2 RDB 持久化【底层原理】

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 分布式缓存 文章目录微服务框架分布式缓存41 Redis 持久化41.2 RDB 持久化【底层原理】41.2.1 RDB41.2.2 总结41 Redis 持久化 41.2 RDB 持…

【IDEA】解决IDEA插件使用Lombok找不到符号问题

1.概述 今天合并了有冲突的代码,合并完毕后,发现运行的时候找不到符号。类似如下报错 java: 找不到符号* 符号: 方法 setData(java.lang.String)* 位置: 类型为com.fastjson.demo.lombok.

Vue渲染器(三):简单diff算法

渲染器&#xff08;三&#xff09;&#xff1a;简单diff算法 我们将介绍渲染器的核心Diff算法。简单来说就是当新旧vnode的子节点都是一组节点时&#xff0c;为了以最小的性能开销完成更新操作&#xff0c;需要比较两组子节点。 1.减少DOM操作的性能开销&#xff1a; 核心Di…

第46篇 进阶(六) 国际化

导语 在第2篇中讲述如何显示中文时&#xff0c;曾提到使用QTextCodec和tr()的方式直接显示中文&#xff0c;其实这只是一种临时的方法&#xff0c;方便我们快速完成程序&#xff0c;显示效果。当真正要发布一个程序时&#xff0c;最好的方式是在程序中使用英文字符串&#xff…

四、函数基础、函数种类、形实参和映射关系

四、函数基础、函数种类、形实参和映射关系 编程基本原则&#xff1a;高内聚、低耦合。 我总结&#xff1a; 模块自身&#xff0c;要求高内聚&#xff1a;模块中代码相关性变强&#xff0c;代码紧密联系程度变高&#xff0c;希望它能独立完成一个功能。模块之间&#xff0c;…

【20221213】【每日一题】零钱兑换II

给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带符号整数。 …

新课程导学杂志新课程导学杂志社新课程导学编辑部2022年第30期目录

前沿《新课程导学》投稿&#xff1a;cn7kantougao163.com 贵州四条线路入选“稻花香里说丰年”全国乡村旅游精品线路 邓小青; 1 基地 梯云村落&#xff0c;晒秋人家——用绚烂色调谱写秋意之诗 邓小青; 2-9 分享 走进“那”文化回归稻香梦聆听丰收声——2022年顶蛳…

Redis 7 新特性之 自定义Functions

Redis 7 新特性之 自定义Functions Redis Functions&#xff08;函数&#xff09;是用于管理服务端执行代码的API。在Redis 7中出现&#xff0c;旨在取代之前版本的EVAL函数&#xff0c;是Redis 7新特性之一。 Eval 脚本的缺点 Redis 7之前的版本通过Eval执行脚本&#xff0…

流媒体协议介绍(RTP/RTCP/RTSP/RTMP/MMS/HLS/HTTP/ HTTP-FLV(HDL) /SDP)

流媒体协议介绍&#xff08;RTP/RTCP/RTSP/RTMP/MMS/HLS/HTTP/ HTTP-FLV(HDL) /SDP&#xff09; 一、RTP&#xff1a;实时传输协议&#xff08;Real-time Transport Protocol&#xff09; RTP是一种基于包的传输协议&#xff0c;它用来传输实时数据。在网络上传输数据包的延迟…

艾美捷CD8α体内抗体参数说明化学性质

CD8a&#xff08;Ly 2.2&#xff09;存在于大多数胸腺细胞和包括大多数T抑制/细胞毒性细胞的成熟T淋巴细胞亚群的表面。CD8通过与T细胞受体复合物和蛋白酪氨酸激酶lck的结合参与T细胞活化。 艾美捷CD8α体内抗体基本参数&#xff1a; 中文名称&#xff1a;抗小鼠CD8a体内抗体-…

Kafka极客 - 15 重设消费者位移 Offset

文章目录1. 为什么要重设消费者组位移&#xff1f;2. 重设位移策略3. 消费者 API 方式设置4. 命令行方式设置1. 为什么要重设消费者组位移&#xff1f; 我们知道&#xff0c;Kafka 和传统的消息引擎在设计上是有很大区别的&#xff0c;其中一个比较显著的区别就是&#xff0c;…

怎么看xray发了那些数据包

怎么看xray发了那些数据包。版本说明&#xff1a;Xray 下载地址&#xff1a;https://github.com/chaitin/xray/releases 使用环境&#xff1a;windows、linux、macos皆可 工具说明&#xff1a;Xray扫描器是一款功能强大的安全评估工具。支持主动、被动多种扫描方式&#xff…

UNIAPP实战项目笔记51 登录用户名和密码输入框的数据验证功能

UNIAPP实战项目笔记51 登录账号用户名和密码输入框的数据验证功能 实际案例图片 账号验证 密码验证 登录成功跳转 显示登录和注册页面布局 账号密码的验证功能和登录验证提交 具体内容图片自己替换哈&#xff0c;随便找了个图片的做示例 具体位置见目录结构 完善布局页面和样式…

基于PHP和MySQL的新闻发布系统

关于世界杯⚽️ 国际足联世界杯&#xff08;FIFA World Cup&#xff09;&#xff0c;简称“世界杯”&#xff0c;是由全世界国家级别球队参与&#xff0c;象征足球界最高荣誉&#xff0c;并具有最大知名度和影响力的足球赛事。世界杯全球电视转播观众超过35亿 。世界杯每四年举…

【设计模式】简单工厂模式描述总结

简单工厂模式 定义&#xff1a;定义一个创建对象的接口&#xff0c;让子类决定实例化哪一个类。 类型&#xff1a;创建型模式 介绍&#xff1a; 在简单工厂模式中定义一个抽象产品类&#xff0c;抽象产品类声明公共的特性及属性&#xff0c;具体产品类继承抽象产品类后去实…

Educational Codeforces Round 121 (Rated for Div. 2) C. Monsters And Spells

翻译&#xff1a; Monocarp又在玩电脑游戏了。他是个巫师学徒&#xff0c;只会一个咒语。幸运的是&#xff0c;这个法术可以伤害怪物。 他目前所在的关卡包含&#x1d45b;个怪物。他们中的&#x1d456;-th在关卡开始后&#x1d458;&#x1d456;秒出现&#xff0c;并拥有ℎ…

Java石头剪刀布

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;JAVA开发者…

【iMessage苹果源码家庭推】tils扩大软件安装大概释放事变是由程序员筑造的,很轻易发生MemoryLeak控制

推荐内容IMESSGAE相关 作者推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者推荐内容3.日历推 *** 点击即可查看作者要求内容信息作者推荐…

[附源码]计算机毕业设计的小区宠物管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis MavenVue等等组成&#xff0c;B/S模式…