热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于AT89X51的时钟与日期显示及按键控制

本文介绍了一种使用AT89X51单片机实现的时钟和日期显示系统,通过按键切换显示时间和日期。代码中包含了时间更新、日期计算以及按键扫描等功能。

本项目旨在利用AT89X51单片机实现一个简单的时间和日期显示系统,用户可以通过按键在时间显示和日期显示之间进行切换。以下是具体的实现代码:

#include 

// 数码管显示编码表
char display[] = {0X3F, 0X06, 0X5B, 0X4F, 0X66, 0X6D, 0X7D, 0X07, 0X7F, 0X6F, 0XF7, 0X7C, 0X39, 0X5E, 0X79, 0X71};

char hour = 0, minute = 0, secOnd= 0; // 初始化时间为00:00:00
char year = 21, mOnth= 1, day = 1; // 初始化日期为2021年1月1日

// 延时函数
void delay(unsigned int xms) {
unsigned int i, j;
for (i = xms; i > 0; i--) {
for (j = 240; j > 0; j--);
}
}

// 显示数字
void displayNumber(char value) {
P0 = display[value];
}

// 显示时间
void showTime() {
P2 = 0xFE;
displayNumber(hour / 10);
delay(1);
P2 = 0xFD;
P0 = display[hour % 10] | 0x80;
delay(1);
P2 = 0xFB;
displayNumber(minute / 10);
delay(1);
P2 = 0xF7;
P0 = display[minute % 10] | 0x80;
delay(1);
P2 = 0xEF;
displayNumber(second / 10);
delay(1);
P2 = 0xDF;
P0 = display[second % 10];
delay(1);
}

// 显示日期
void showDate() {
P2 = 0xFE;
displayNumber(year / 10);
delay(1);
P2 = 0xFD;
P0 = display[year % 10] | 0x80;
delay(1);
P2 = 0xFB;
displayNumber(month / 10);
delay(1);
P2 = 0xF7;
P0 = display[month % 10] | 0x80;
delay(1);
P2 = 0xEF;
displayNumber(day / 10);
delay(1);
P2 = 0xDF;
P0 = display[day % 10];
delay(1);
}

// 按键扫描
unsigned char scanKey() {
unsigned char keyValue;
P1 = 0x0F;
if (P1 != 0x0F) {
switch (P1) {
case 0x0E: // 第一列
P1 = 0xF0;
switch (P1) {
case 0x70: keyValue = 12; break;
case 0xB0: keyValue = 8; break;
case 0xD0: keyValue = 4; break;
case 0xE0: keyValue = 0; break;
}
break;
case 0x0D: // 第二列
P1 = 0xF0;
switch (P1) {
case 0x70: keyValue = 13; break;
case 0xB0: keyValue = 9; break;
case 0xD0: keyValue = 5; break;
case 0xE0: keyValue = 1; break;
}
break;
case 0x0B: // 第三列
P1 = 0xF0;
switch (P1) {
case 0x70: keyValue = 14; break;
case 0xB0: keyValue = 10; break;
case 0xD0: keyValue = 6; break;
case 0xE0: keyValue = 2; break;
}
break;
case 0x07: // 第四列
P1 = 0xF0;
switch (P1) {
case 0x70: keyValue = 15; break;
case 0xB0: keyValue = 11; break;
case 0xD0: keyValue = 7; break;
case 0xE0: keyValue = 3; break;
}
break;
}
}
return keyValue;
}

// 判断闰年
char isLeapYear(int year) {
if ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)))
return 29;
else
return 28;
}

// 获取月份天数
char getMonthDays(int year, char month) {
switch (month) {
case 4:
case 6:
case 9:
case 11:
return 30;
case 2:
return isLeapYear(year);
default:
return 31;
}
}

char tick = 1;

// 定时器0中断服务程序
void timer0ISR() interrupt 1 {
if (++tick == 20) {
tick = 0;
if (++secOnd== 60) {
secOnd= 0;
if (++minute == 60) {
minute = 0;
if (++hour == 24) {
hour = 0;
if (++day == getMonthDays(2000 + year, month) + 1) {
day = 1;
if (++mOnth== 13) {
mOnth= 1;
year++;
}
}
}
}
}
}
}

void main() {
char key = 0x55;
TMOD = 0x01; // T0模式1,16位定时器
TH0 = -50000 / 256;
TL0 = -50000 % 256;
ET0 = 1; // 允许T0中断
EA = 1; // 允许全局中断
TR0 = 1; // 启动T0

while (1) {
key = scanKey();
if (key == 1)
showTime();
else if (key == 2)
showDate();
}
}

以上代码实现了基本的时钟和日期显示功能,并通过按键进行界面切换。定时器0用于产生每秒一次的中断,以更新时间。按键扫描部分负责检测用户的输入并根据输入切换显示内容。


推荐阅读
  • 本文详细介绍了Java编程语言中的关键字及其用途,包括53个关键字和2个保留字。文章不仅解释了每个关键字的基本功能,还提供了实际应用场景中的使用示例。 ... [详细]
  • 本文详细介绍了MySQL表分区的概念、类型及其在实际应用中的实施方法,特别是针对Zabbix数据库的优化策略。 ... [详细]
  • 本文介绍了一种算法,用于在一个给定的二叉树中找到一个节点,该节点的子树包含最大数量的值小于该节点的节点。如果存在多个符合条件的节点,可以选择任意一个。 ... [详细]
  • 探讨如何利用Visual Basic (VB) 将十六进制或二进制字符串写入Windows注册表的方法。 ... [详细]
  • 本文探讨了BZOJ4029 [HEOI2015] 定价问题,通过使用贪心算法解决该问题。文章提供了详细的题目解析和代码实现,重点在于如何通过计算十进制下的最低有效位(lowbit)来简化问题。 ... [详细]
  • C#爬虫Fiddler插件开发自动生成代码
    哈喽^_^一般我们在编写网页爬虫的时候经常会使用到Fiddler这个工具来分析http包,而且通常并不是分析一个包就够了的,所以为了把更多的时间放在分析http包上,自动化生成 ... [详细]
  • 我们正在使用GNU Make来构建我们的系统,在makefile文件的末尾,我们通过一个名为Makedepends的包含来生成一系列的.d文件。然而,当文件被删除或移动时,依赖关系会中断,我们需要寻找一种方法来优雅地处理这种情况。 ... [详细]
  • Qt应用开发:创建基本窗口
    本文介绍如何使用Qt框架创建基础窗口的两种方法。第一种方法直接在main函数中创建并显示窗口;第二种方法通过定义一个继承自QWidget的类来实现更复杂的功能。 ... [详细]
  • 使用Python模拟登录教务系统抓取成绩并分析存储
    本文详细介绍如何使用Python编程语言模拟登录学校教务系统,抓取学生的成绩信息,并进行数据分析和可视化处理,最终将数据存储到MySQL数据库中。 ... [详细]
  • 本文详细介绍了中心方形数的概念及其计算方法,并提供了多种编程语言下的实现代码。 ... [详细]
  • POJ2226 二分图最小覆盖问题
    在一个大小为n×m的网格中,部分单元格为泥泞状态,其余为干净。目标是使用宽度固定为1但长度可变的木板覆盖所有泥泞单元格,且不覆盖任何干净单元格。木板允许重叠。本问题通过构建二分图并求其最小覆盖来解决。 ... [详细]
  • Oracle中打开10046Trace的各种方法10046trace的跟踪等级10046是一个Oracle的内部事件(event),通过设置这个事件可以得到Oracl ... [详细]
  • 正在学习操作系统开发,遇到一个内核在GRUB Legacy(0.97)中无法成功引导的问题。具体表现为输入内核命令后显示错误信息,尝试引导时GRUB挂起。 ... [详细]
  • 本文探讨了在使用 ClickOnce 部署方式时遇到的自动更新失败问题,包括本地安装与服务器安装的不同表现,并提供了详细的解决方案。 ... [详细]
  • 本文介绍如何使用Java实现AC自动机(Aho-Corasick算法),以实现高效的多模式字符串匹配。文章涵盖了Trie树和KMP算法的基础知识,并提供了一个详细的代码示例,包括构建Trie树、设置失败指针以及执行搜索的过程。 ... [详细]
author-avatar
mobiledu2502852753
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有