如何在51单片机实现电子万年历

51单片机制作万年历的基本功能部分,软件特性可以在proteus上仿真,使用51单片机定时器T0做万年历计时信号源,电子万年历计时系统在timer模块,本模块主要是将年/月/日/星期/时/分/秒等信息输出到lcd1602上显示,以及将年月日换算为星期信息。单片机采用12MHz晶振,中断1ms计时方式,误差低。下面直接上代码:

引用timer系统变量

extern time_t time;        // 电子万年历变量
extern u8 time_update;  // 更新显示等级,值越小等级越高,1为最高等级,0为最低

对外接口

用于初始化/去初始化电子万年历系统,计算星期信息,以及在lcd1602上显示更新等。

void clock_init(void);    // 万年历初始化
void clock_deinit(void);    // 万年历去初始化
u8 clock_week_calc(u16 y, u8 m, u8 d);    // 星期计算
void clock_display_update(void);    // 显示更新

初始化模块

主要是预置年/月/日/星期/时/分/秒/毫秒信息显示格式和初始值。

/*******************************************************************************
* 函 数 名         : clock_init
* 函数功能         : 万年历初始化
* 输    入         : void
* 输    出         : void
* 说    名         : none
*******************************************************************************/
void clock_init(void)    // 万年历初始化
{lcd1602_write_cmd(LCD1602_DISPLAY_CONTROL);  // 关闭光标和闪烁lcd1602_clean();lcd1602_set_pos(0, 1);lcd1602_write_num(4, time.year);lcd1602_write_data('-');lcd1602_write_num(2, time.month);lcd1602_write_data('-');lcd1602_write_num(2, time.day);lcd1602_set_pos(0, 0);lcd1602_write_num(2, time.hour);lcd1602_write_data(':');lcd1602_write_num(2, time.miunte);lcd1602_write_data(':');lcd1602_write_num(2, time.second);lcd1602_set_pos(11, 0);lcd1602_write_num(3, time.ms);lcd1602_write_str("ms");
}

lcd1602显示实例:

去初始化

清理显示屏。

/*******************************************************************************
* 函 数 名         : clock_deinit
* 函数功能         : 万年历去初始化
* 输    入         : void
* 输    出         : void
* 说    名         : none
*******************************************************************************/
void clock_deinit(void)    // 万年历去初始化
{lcd1602_write_cmd(LCD1602_DISPLAY_CONTROL);  // 关闭光标和闪烁lcd1602_clean();
}

星期计算

通过给定年/月/日,通过星期计算公式,完成年月日到星期的换算,计算公式可通过星期的产生和定义得出。返回0表示周天,返回1到6表示周一到周六。

code s8 week[7][4]={{"Sun"}, {"Mon"}, {"Tue"}, {"Wed"}, {"Thu"}, {"Fri"}, {"Sat"}};
/*******************************************************************************
* 函 数 名         : clock_week_calc
* 函数功能         : 星期计算
* 输    入         : y/m/d:年/月/日
* 输    出         : u8:星期数
* 说    名         : none
*******************************************************************************/
u8 clock_week_calc(u16 y, u8 m, u8 d)    // 星期计算
{u16 week_cnt = 0;u8 week_num;switch (m) {     // 从这一年的元旦算到该天为止( 含该天) 的天数case 12: week_cnt += 30;case 11: week_cnt += 31;case 10: week_cnt += 30;case  9: week_cnt += 31;case  8: week_cnt += 31;case  7: week_cnt += 30;case  6: week_cnt += 31;case  5: week_cnt += 30;case  4: week_cnt += 31;case  3: week_cnt += 28;case  2: week_cnt += 31;case  1: week_cnt += d; break;default: break;}if ((!(y % 4) && ((y % 100) || !(y % 400))) && (m > 2)) {    // 闰年补一天week_cnt++;}week_num = (y - 1 + (y - 1) / 4 - (y - 1) / 100 + (y - 1) / 400 + week_cnt) % 7;return week_num;
}

显示更新

由于lcd1602写入信息耗时较高,另一方面也并不是时时刻刻年/月/日/星期/时/分/秒/毫秒等信息都在更新或者说有变化,因此利用time_update记录当前需要更新的时间信息有哪些,可以有效提高cpu利用率和性能,在51单片机场景优势非常明显。注:年/月/日/星期/时/分/秒/毫秒更新方向是线性向下的,即:更新年份,必定也需要更新月/日/星期/时/分/秒/毫秒等其他信息。

/*******************************************************************************
* 函 数 名         : clock_display_update
* 函数功能         : 显示更新
* 输    入         : void
* 输    出         : void
* 说    名         : time_update需要及时清除
*******************************************************************************/
void clock_display_update(void)   // 显示更新
{switch (time_update) {        // 判断更新case 1: time_update = 0;  // 年更新lcd1602_set_pos(0, 1);lcd1602_write_num(4, time.year);case 2: time_update = 0;  // 月更新lcd1602_set_pos(5, 1);lcd1602_write_num(2, time.month);case 3: time_update = 0;  // 日更新lcd1602_set_pos(8, 1);lcd1602_write_num(2, time.day);lcd1602_set_pos(11, 1);  // 星期更新lcd1602_write_str(week[clock_week_calc(time.year, time.month, time.day)]);case 4: time_update = 0;  // 时更新lcd1602_set_pos(0, 0);lcd1602_write_num(2, time.hour);case 5: time_update = 0;  // 分更新lcd1602_set_pos(3, 0);lcd1602_write_num(2, time.miunte);case 6: time_update = 0;  // 秒更新lcd1602_set_pos(6, 0);lcd1602_write_num(2, time.second);case 7: time_update = 0;  // 毫秒更新lcd1602_set_pos(11, 0);lcd1602_write_num(3, time.ms);break;default: break;   // 无更新}
}

附录 - 基本功能(clock.h)

#ifndef __CLOCK_H__
#define __CLOCK_H__#include "include.h"
#include "timer.h"extern time_t time;        // 电子万年历变量
extern u8 time_update;  // 更新显示等级,值越小等级越高,1为最高等级,0为最低void clock_init(void);    // 万年历初始化
void clock_deinit(void);    // 万年历去初始化
u8 clock_week_calc(u16 y, u8 m, u8 d);    // 星期计算
void clock_display_update(void);    // 显示更新#endif

附录 - 基本功能(clock.c)

#include "clock.h"
#include "lcd1602.h"code s8 week[7][4]={{"Sun"}, {"Mon"}, {"Tue"}, {"Wed"}, {"Thu"}, {"Fri"}, {"Sat"}};/*******************************************************************************
* 函 数 名         : clock_init
* 函数功能         : 万年历初始化
* 输    入         : void
* 输    出         : void
* 说    名         : none
*******************************************************************************/
void clock_init(void)    // 万年历初始化
{lcd1602_write_cmd(LCD1602_DISPLAY_CONTROL);  // 关闭光标和闪烁lcd1602_clean();lcd1602_set_pos(0, 1);lcd1602_write_num(4, time.year);lcd1602_write_data('-');lcd1602_write_num(2, time.month);lcd1602_write_data('-');lcd1602_write_num(2, time.day);lcd1602_set_pos(0, 0);lcd1602_write_num(2, time.hour);lcd1602_write_data(':');lcd1602_write_num(2, time.miunte);lcd1602_write_data(':');lcd1602_write_num(2, time.second);lcd1602_set_pos(11, 0);lcd1602_write_num(3, time.ms);lcd1602_write_str("ms");
}/*******************************************************************************
* 函 数 名         : clock_deinit
* 函数功能         : 万年历去初始化
* 输    入         : void
* 输    出         : void
* 说    名         : none
*******************************************************************************/
void clock_deinit(void)    // 万年历去初始化
{lcd1602_write_cmd(LCD1602_DISPLAY_CONTROL);  // 关闭光标和闪烁lcd1602_clean();
}/*******************************************************************************
* 函 数 名         : clock_week_calc
* 函数功能         : 星期计算
* 输    入         : y/m/d:年/月/日
* 输    出         : u8:星期数
* 说    名         : none
*******************************************************************************/
u8 clock_week_calc(u16 y, u8 m, u8 d)    // 星期计算
{u16 week_cnt = 0;u8 week_num;switch (m) {     // 从这一年的元旦算到该天为止( 含该天) 的天数case 12: week_cnt += 30;case 11: week_cnt += 31;case 10: week_cnt += 30;case  9: week_cnt += 31;case  8: week_cnt += 31;case  7: week_cnt += 30;case  6: week_cnt += 31;case  5: week_cnt += 30;case  4: week_cnt += 31;case  3: week_cnt += 28;case  2: week_cnt += 31;case  1: week_cnt += d; break;default: break;}if ((!(y % 4) && ((y % 100) || !(y % 400))) && (m > 2)) {    // 闰年补一天week_cnt++;}week_num = (y - 1 + (y - 1) / 4 - (y - 1) / 100 + (y - 1) / 400 + week_cnt) % 7;return week_num;
}/*******************************************************************************
* 函 数 名         : clock_display_update
* 函数功能         : 显示更新
* 输    入         : void
* 输    出         : void
* 说    名         : time_update需要及时清除
*******************************************************************************/
void clock_display_update(void)   // 显示更新
{switch (time_update) {        // 判断更新case 1: time_update = 0;  // 年更新lcd1602_set_pos(0, 1);lcd1602_write_num(4, time.year);case 2: time_update = 0;  // 月更新lcd1602_set_pos(5, 1);lcd1602_write_num(2, time.month);case 3: time_update = 0;  // 日更新lcd1602_set_pos(8, 1);lcd1602_write_num(2, time.day);lcd1602_set_pos(11, 1);  // 星期更新lcd1602_write_str(week[clock_week_calc(time.year, time.month, time.day)]);case 4: time_update = 0;  // 时更新lcd1602_set_pos(0, 0);lcd1602_write_num(2, time.hour);case 5: time_update = 0;  // 分更新lcd1602_set_pos(3, 0);lcd1602_write_num(2, time.miunte);case 6: time_update = 0;  // 秒更新lcd1602_set_pos(6, 0);lcd1602_write_num(2, time.second);case 7: time_update = 0;  // 毫秒更新lcd1602_set_pos(11, 0);lcd1602_write_num(3, time.ms);break;default: break;   // 无更新}
}

如何在51单片机实现电子万年历相关推荐

  1. 基于51单片机的电子万年历的设计-源代码

    电子万年历的设计目录 电子万年历的设计 电子万年历的系统整体设计框图 所需要的元件 DS18B20模块 DS18B20的特点 DS18B20内部结构 DS18B20管脚排列 DS1302模块 SPI时 ...

  2. 基于51单片机的电子万年历设计

    基于51单片机的电子万年历 1)LCD1602显示时间.日期.星期.温度 2)按键可调整时间日期星期 3)整点报时 4)DS1302时钟芯片 5)DS18B20温度传感器 6)闹钟功能 7)判断闰年 ...

  3. 【002】基于51单片机的电子万年历proteus仿真设计

    一.资料内容(私信获取) (1).基于51单片机的电子万年历proteus仿真设计一份: (2).基于51单片机的电子万年历proteus仿真设计keli源代码一份: (3).基于51单片机的电子万年 ...

  4. 万年历设计单片机c语言,基于51单片机的电子万年历的设计

    基于51单片机的电子万年历的设计(论文9400字) 功能要求 1. 万年历能用数码管显示阳历年.月.日.星期.[小]时.分.秒并设置指定时间的闹铃. 2. 数字式温度计要求测温范围-50~100°C, ...

  5. 基于51单片机的电子万年历的设计

    (24条消息) 基于51单片机的电子万年历的设计说明书(完整word版本说明书+原理图+代码)资源-CSDN文库 摘 要 电子万年历是单片机系统的一个应用,由硬件和软件相配合使用.硬件由主控器.时钟电 ...

  6. 使用51单片机自制电子万年历(包含驱动、基本万年历、闹钟、日程、修改时间等)

    使用51单片机自制电子万年历(包含驱动.基本万年历.闹钟.日程.修改时间等) 归档51单片机制作电子万年历,以及proteus仿真电路图,本设计涵盖蜂鸣器.uart.timer.矩阵扫描.lcd160 ...

  7. 基于51单片机的电子钟万年历LCD1602显示

    本设计是51单片机的电子钟万年历LCD1602显示(proteus仿真+程序+报告+器件清单) 仿真图proteus 7.8 程序编译器:keil 4/keil 5 编程语言:C语言 编号C0002 ...

  8. 基于单片机的电子万年历设计与实现

    基于单片机的电子万年历设计与实现 <嵌入式与单片机>课程设计报告 摘要 万年历作为日常生活中重要的时间显示设备,在人们的外出旅游和日常生活中都发挥了重要的作用.本文针对目前的万年历产品中存 ...

  9. 如何在51单片机实现闹钟功能

    如何在51单片机实现闹钟功能 51单片机制作万年历过程中的闹钟部分,主要说明设计算法,软件特性可以在proteus上仿真.闹钟是人机交互的一部分,因此闹钟的实现与具体的人机交互方式息息相关,本系统采用 ...

最新文章

  1. 本地复制不能粘贴到服务上
  2. Spring Boot 2.x基础教程:使用MyBatis的XML配置方式
  3. 三十九、Scrapy-redis框架分布式部署
  4. SQL基础操作_8_基础概念
  5. java 减少内存_java中减少内存占用小技巧
  6. 木马开机启动的六种方法
  7. Android富文本处理
  8. SQL2008使用json.net实现XML与JSON互转
  9. Python学习day2 while循环格式化输出运算符
  10. 开发代码code中变量替换
  11. Oracle数据库imp
  12. mysql 5.7 slow_mysql 5.7 解决 set global slow_query_log=on;报错
  13. 抓linux肉鸡教程视频,抓肉鸡的教程和软件免费分享(2018一天抓1000只电脑肉鸡视频)...
  14. 不格式化U盘的情况下部署WinPE
  15. 我要写整个中文互联网界最牛逼的JVM系列教程 | 「JVM与Java体系架构」章节:虚拟机与Java虚拟机介绍
  16. OpenWrt之DNS 测试工具(nslookup、dig)
  17. 解决安装Visual Studio 2010 SP1时被NDP40-KB2468871.exe补丁卡死以及mscorsvw.exe进程CPU占用率高的问题...
  18. [初学Python]利用某网站的功能写一个磁力链转种子工具
  19. 数据分析师,你是车夫,还是拉车的驴子
  20. [转]一个人生活,如何摆脱孤独提升幸福感?

热门文章

  1. 原假设“截距为0”双侧检验P值是多少_参数假设检验
  2. 初次玩pyecharts:30行代码做一个可视化广东省各地天气温度排行图
  3. dell 摄像头黑屏
  4. 线程池ExecutorService中submit和execute区别
  5. 【宝物志】门店运营内容分享 第十二期
  6. IIS写权限漏洞和XFF刷票原理
  7. (10)DS18B20温度传感器
  8. 基于SSM的在线教育系统的设计与实现【附源码】
  9. 如何评价一个新技术——以 ChatGPT 为例
  10. unity字体效果-1分钟制作字体 荧光 效果(TextMeshPro)