基于80C51单片机的电子钟设计与仿真

news2024/11/15 11:00:14

点击链接获取Keil源码与Project Backups仿真图:
https://download.csdn.net/download/qq_64505944/87761539?spm=1001.2014.3001.5503
在这里插入图片描述

源码获取
主要内容:
电子钟是一种利用数字电路来显示秒、分、时的计时装置,与传统的机械钟相比,它具有走时准确、显 示直观、无机械传动装置等优点,因而得到广泛应用。同时电子钟可以集成诸多功能,如秒表、温度测量、水平检测等功能。
基本要求:
1、能够实现展示当前时间
2、秒数误差控制在1秒以内
3、输出形式采用数字显示
4、给出范围,设定时间时不可超出范围使其完成循环

主要参考资料:
[1]余发山 王福忠.《单片机原理及应用技术》.中国矿业大学出版社.2008
[2]彭伟.《单片机C语言程序设计实训》电子工业出版社.2010.
[3]杨凌霄.《微型计算机原理与应用》.中国电力出版社2003
[4]李朝青.单片机原理及接口技术(简明修订版).杭州:北京航空航天大学出版社,1998
[5]李广弟.单片机基础[M].北京:北京航空航天大学出版社,1994
[6]阎石.数字电子技术基础(第三版). 北京:高等教育出版社,1989
[7]DS18B20数据手册

          完 成 期 限		: 2022 年  12  月 23 日 
      	指导教师签名		:                        
          课程负责人签名	:                        

摘要
本课程设计完成了数字电子钟的设计,数字电子钟是一种用数字显示秒、分、时的计时装置,由于数字集成电路技术的发展和采用了先进的石英技术,它使数字钟具有走时准确、性能稳定、携带方便等优点。数字钟已成为人们日常生活中必不可少的必需品,广泛用于个人家庭以及办公室等公共场所,给人们的生活带来极大的方便。在这里我们将已学过的比较零散的数字电路的知识有机的、系统的联系起来用于实际,来培养我们的综合分析和设计电路的能力。

关键词:电子钟;门电路及单次按键;琴键开关

目录
摘要 - 2 -
目录 - 3 -
1 设计要求 - 4 -
1.1 作品介绍 - 4 -
1.2 基本功能 - 5 -
1.3 扩展功能 - 5 -
2 工作原理 - 5 -
2.1 硬件设计原理 - 5 -
2.1.1 LCD1602液晶显示屏原理 - 6 -
2.1.2 LED模块原理 - 7 -
2.1.3 按键原理 - 7 -
2.1.4 单片机核心模块的时钟电路原理 - 8 -
2.2 软件设计原理 - 8 -
2.2.1 LCD1602液晶显示屏驱动 - 9 -
2.1.2 DS18B20数字温度器驱动 - 10 -
2.1.3 按键消抖与长按检测 - 11 -
3.使用说明 - 11 -
(1) 功能切换: - 11 -
(2) 时间校准: - 11 -
4.软件设计 - 12 -
5. 实验仿真 - 12 -
6.心得体会 - 13 -
7. 参考文献 - 13 -
附录:keil源码 - 14 -

1 设计要求
1.1作品介绍
电子钟是一种利用数字电路来显示秒、分、时的计时装置,与传统的机械钟相比,它具有走时准确、显 示直观、无机械传动装置等优点,因而得到广泛应用。同时电子钟可以集成诸多功能,如秒表、温度测量、水平检测等功能。
本次单片机课程设计使用普中科技的A2开发板,如图1所示,板载单片机型号为AT89C52,采用C语言对其进行编程。
在这里插入图片描述

图1 普中A2开发板与课设成品展示图
1.2 基本功能
1、电子钟可显示时、分、秒;
2、可手动校时,待校时的时间闪烁;
1.3 扩展功能
1、可当作秒表使用;
2、可测量当前环境温度;
3、通过LCD1602液晶屏显示数据及特殊图形;

2 工作原理
2.1 硬件设计原理
硬件设计基于普中A2开发板,LCD1602接口、DS18B2O、独立按键模块、LED模块与单片机核心模块的电路连线如开发板原理图所示,开发板原理图见附件1,模块的逻辑关系如下图所示。

2.1.1 LCD1602液晶显示屏原理
在这里插入图片描述

图2 LCD1602液晶屏
LCD1602液晶屏实物图片如图2所示,LCD1602液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图形。它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成,其电气特性如图3所示。

显示容量 16×2个字符
芯片工作电压 4.5~5.5V
工作电流 2.0mA(5.0V)
模块最佳的工作电压 5.0V
字符尺寸 2.95mm×4.35mm(宽×高)
图3 LCD1602电气特性

在这里插入图片描述

图3 LCD1602接口

由图3所示的LCD1602接口图可知,LCD1602液晶屏由板载5V电压供电;VO引脚连接可调电阻,因此可以通过调节电阻阻值大小控制背光亮度;LCD RS、LCD WR、LCD EN分别连接单片机的P2.6、P2.5、P2.7,控制数据与命令的传输;LCD D0~LCD D7连接单片机P0口,作为单片机与模块之间的数据传送通道。
2.1.2 LED模块原理
在这里插入图片描述

图7 LED模块
由图7可知,LED模块由8位共阳极发光二极管,串联限流排阻,阴极连接单片机P2口组成。当单片机P2口的某一位输出低电平时,该位二极管点亮。
2.1.3 按键原理
在这里插入图片描述

图8 独立按键模块
由图8可知,4位独立按键K1K4分别连接单片机P3.1P3.3,只有按键按下时读引脚才可以得到高电平1。因此可以通过对引脚值电平进行分析,进而判断有无按键按下。
2.1.4 单片机核心模块的时钟电路原理
在这里插入图片描述

图9 单片机核心模块
单片机时钟信号的产生采用内部震荡方式,外接12MHZ晶振,得到频率为12MHZ的时钟信号。在AT89C52芯片内部有一个高增益反相放大器,其输入端为芯片引脚XTAL1,输出端为引脚XTAL2。把放大器与作为反馈元件的晶体振荡器和陶瓷电容相连,就构成了自激振荡器。
2.2 软件设计原理
电子钟上电后,延时10ms后等待外围设备状态稳定,初始化LCD1602,在用户自定义RAM区写入字符模型数据,在开机初始界面显示字模图形。启动计数器T0,每20ms进入中断一次,为其它功能的实现提供基准时间,如进行计时,进行温度数据的读取,在主函数中会循环检测按键,判定是否有按键按下,若有按键按下则进行相应操作,如功能切换,时间调整等。
时间计数值为长整型数据存储,对其进行相应的操作可以得到时分秒,从00:00:00至23:59:59循环计数。秒表每10ms计数一次,对计数值进行处理,将其在液晶屏上显示。对DS18B20数字温度器读寄存器得到的温度值进行分析与处理则可得到当前的温度。
2.2.1 LCD1602液晶显示屏驱动
在这里插入图片描述

图10 LCD1602操作时序
LCD1602读/写数据/命令的时序如图10所示,单片机与其通讯应满足其要求,查找芯片手册中对应的寄存器地址与操作提示可以实现LCD1602的功能。
2.1.2 DS18B20数字温度器驱动

在这里插入图片描述

图11 DS18B20操作时序
主机和从机通信使用单总线,即使用单线进行数据的发送和接收。首先需要判断总线上是否存在设备,确定有设备存在后在进行读/写操作,查找芯片手册中的寄存器地址与操作提示可以设置温度检测精度与温度值读取。
2.1.3 按键消抖与长按检测
在这里插入图片描述

图12 按键抖动示意图
当按键按下时,与按键相连线上的电压会波动,如图12所示,可能会在5V TTL电平阈值附近波动,如果程序只是对电平跳变进行计数,则可能会在按键按下一次时记录很多次,因此我们需要对按键进行消抖,同时对低电平时间进行计数,进而判断是短按还是长按。

3.使用说明
使用K1、K2、共2个按键
(1)功能切换:
单击K1,用于切换时间
(2)时间校准:
长按K2 进入/退出时间调整菜单,当菜单为时间调整时,单击K3 切换选择时/分/秒进行调整,待调整的时间会闪烁,单击K1,当前调整的时间值+1,单击K2则-1。时间调整完毕后,长按K2保存当前时间值,LED灯闪烁一次时,则表示校时成功。

菜单描述

4.软件设计

在这里插入图片描述

5.实验仿真
在这里插入图片描述

6.心得体会
在课程设计,将理论用于实践,实践又将丰富理论,对单片机的掌握更加深刻,收获颇丰。在制作过程中也遇到了许多问题,如LCD1602因为操作时序不正确导致无响应,因为清屏指令不合适造成屏幕闪烁明显;对读取DS18B20的高8位和低8位数据进行整合处理时遇到的难题;按键单击与长按复用功能的实现,消抖的细节处理等。通过查找CSDN与B站上的资源,与同学交流,问题最后得到了解决。但由于自己能力有限,做出来的成品只能尽自己所能做到最好。
单片机的型号千千万万,随着时代的发展,单片机更新迭代,只有掌握了基本的单片机原理与学习方法,有了坚实的基础才可以对任何单片机的开发水到渠成,应一步一步慢慢来。
国产MCU的崛起仍是我们的期望,期待那一天的到来,等到那一天我们发现国产MCU也可以在国际上掷地有声。

  1. 参考文献
    [1]余发山 王福忠.《单片机原理及应用技术》.中国矿业大学出版社.2008
    [2]彭伟.《单片机C语言程序设计实训》电子工业出版社.2010.
    [3]杨凌霄.《微型计算机原理与应用》.中国电力出版社2003
    [4]李朝青.单片机原理及接口技术(简明修订版).杭州:北京航空航天大学出版社,1998
    [5]李广弟.单片机基础[M].北京:北京航空航天大学出版社,1994
    [6]阎石.数字电子技术基础(第三版). 北京:高等教育出版社,1989
    [7]DS18B20数据手册

附录:keil源码

#include <reg51.h>

sbit key1 = P1^0;
bit flag1s = 0;
bit KeySta = 1;
unsigned char hour = 20;
unsigned char minute = 30;
unsigned char second = 00;
unsigned char mode = 0;
void FreshTime();
void TimeInit();
void IntInit();
void InitLedBuff();
void keyscan();
  
unsigned char code LedChar[] = {  //¹²ÒõÊýÂë¹ÜÏÔʾ×Ö·ûת»»±í
    0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
    0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00,0x40};
unsigned char LedBuff[8] = {  //ÊýÂë¹ÜÏÔʾ»º³åÇø
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};

void main()
{
  TimeInit();
  IntInit();
  InitLedBuff();
  while(1)//ÏÔʾÄÚÈÝ´¦Àí
  {
    if(flag1s&&!mode) //ʱ¼äÏÔʾģʽ
    {
      flag1s = 0;
      FreshTime();
    }
    else if(mode == 1)  //У׼·ÖÖÓ
    {
      LedBuff[0] = 17;
      LedBuff[1] = 17;
      LedBuff[4] = 17;
      LedBuff[5] = 17;
			LedBuff[6] = 17;
			LedBuff[7] = 17;//²»ÏÔʾ
      LedBuff[2] = minute/10;
      LedBuff[3] = minute%10;
    }
    else if(mode == 2)  //У׼Сʱ
    {
      LedBuff[2] = 17;
      LedBuff[3] = 17;
      LedBuff[4] = 17;
			LedBuff[6] = 17;
			LedBuff[7] = 17;
      LedBuff[5] = 17;//²»ÏÔʾ
      LedBuff[0] = hour/10;
      LedBuff[1] = hour%10;
    }
    else if(mode == 3)  //У׼Íê³ÉÖØÐÂÏÔʾ
    {
      InitLedBuff();
      mode = 0;
    }
    keyscan();
  }
}

void InitLedBuff()//³õʼ»¯Ê±¼äµ½ÏÔʾ»º³åÇø
{
  LedBuff[0] = hour/10;
  LedBuff[1] = hour%10;
  LedBuff[2] = minute/10;
  LedBuff[3] = minute%10;
  LedBuff[4] = second/10;
  LedBuff[5] = second%10;
	LedBuff[6] = 18;
	LedBuff[7] = 18;
}
void FreshTime()//Ë¢ÐÂʱ¼äµ½ÏÔʾ»º³åÇø
{
  second++;
  if(second == 60)//½øλ
  {
    second = 0;
    minute++;
    
    if(minute == 60)//½øλ
    {
      minute = 0;
      hour++;
      if(hour == 24)
        hour = 0;
      LedBuff[0] = hour/10;
      LedBuff[1] = hour%10;
    }  
		LedBuff[2] = minute/10;
    LedBuff[3] = minute%10;
  }
  LedBuff[4] = second/10;
  LedBuff[5] = second%10;
	LedBuff[6] = 18;
	LedBuff[7] = 18;
}

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

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

相关文章

SpringBatch之实际操作

文章目录 1 SpringBatch操作1.1 SpringBatch介绍1.2 依赖配置相关1.2.1 pom.xml1.2.2 mysql 依赖库表1.2.3 启动配置1.2.4 数据库配置 1.3 示例Demo1.3.1 简单执行1.3.2 报错 1.4 流程控制1.4.1 多步骤任务1.4.2 Flow用法1.4.3 并发执行1.4.4 任务决策1.4.5 任务嵌套 1.5 数据操…

Illustrator如何使用图层与蒙版之实例演示?

文章目录 0.引言1.绘制可爱冰淇淋图标2.霓虹渐变立体文字海报3.炫彩花纹背景 0.引言 因科研等多场景需要进行绘图处理&#xff0c;笔者对Illustrator进行了学习&#xff0c;本文通过《Illustrator CC2018基础与实战》及其配套素材结合网上相关资料进行学习笔记总结&#xff0c;…

电影推荐算法2

模型创建 title _ count, title _ set, genres2int, features, targets _ values, ratings, users, movies, data, movies _ orig, users _ orig pickle.load (open (‘preprocess.p’, mode ‘rb’)) 加载数据后定义神经网络的模型结构&#xff1a; 1&#xff09;定义参数…

u盘文件名乱码的恢复方法

文件名全部变乱码了怎么恢复&#xff1f;U盘数据恢复方法 电脑里的目录文件名乱码了&#xff0c;这是什么状况呢&#xff1f;好端端的电脑突然就成这个样子了&#xff0c;真是令人摸不着头脑&#xff0c;对于这样的状况&#xff0c;多半是文件类型引起的&#xff0c;那么接下来…

Python:Python进阶:Python整数与 Numpy的数据溢出

numpy数据溢出 1.python 3 的整数上限和 python 2 的整数上限1.1 python 2的整数范围1.2 python 3 的整数范围 2. numpy数值表示2.1 那么numpy支持的数据类型和 python有什么不同了2.2 如何解决整数溢出问题 总结 实验一&#xff1a;使用 numpy库来表示正数 import numpy as n…

redis(4)

1)使用StringTemplateRedis操作String类型 1)判断redis中是否拥有key所对应的值&#xff0c;如果有返回true&#xff0c;没有那么直接返回false redisTemplate.hasKey(key); 2)如果redis中有key那么直接取出key所对应的值 redisTemplate.opsForValue().get(key) 3)删除单个key值…

2023.05.07 学习周报

文章目录 摘要文献阅读1.题目2.现存问题和解决方法3.本文贡献及相关工作4.GRU5.模型5.1 SESSION-PARALLEL MINI-BATCHES5.2 SAMPLING ON THE OUTPUT5.3 RANKING LOSS 6.实验6.1 准备6.2 基线6.3 优化6.4 结果 7.结论 数学建模1.综合评价模型的一般步骤2.层次分析法3.主成分分析…

【Java】中的多线程线程锁

多线程 文章目录 多线程线程的创建和启动sleep()stop() 线程的休眠和中断线程的优先级线程的礼让和加入yield()stop() 线程锁和线程同步synchronized 关键字 死锁概念 wait & notify methodThreadLocal的使用定时器 Timer守护线程再谈集合类parallelStreamforEachOrdered()…

怎么将三张图片合成一张图片?

怎么将三张图片合成一张图片&#xff1f;遇到这个问题&#xff0c;我们其实有很多方法来处理。我们首当其冲想到的是其中最常见的&#xff0c;可以使用我们手机的APP来处理&#xff0c;比如某秀秀等。但是此方法比较适合于尺寸比较小的图片进行合并&#xff0c;如果图片比较大的…

Dockerfile创建镜像文件

Dockerfile Docker镜像原理 Linux文件系统有bootfs和rootfs两部分组成 Docker镜像由特殊文件系统叠加 最底端bootfs,使用宿主机bootfs 第二次时rootfs,被称为基础镜像 向上可以叠加其他镜像文件 同一文件系统能将多层整合成一层&#xff0c;隐藏了多层存在 镜像可以放置…

智能优化算法:鱼鹰优化算法-附代码

智能优化算法&#xff1a;鱼鹰优化算法 文章目录 智能优化算法&#xff1a;鱼鹰优化算法1. 鱼鹰优化算法1.1 初始化1.2 阶段一&#xff1a;定位和捕鱼&#xff08;探索阶段&#xff09;1.3 阶段二&#xff1a;把鱼带到合适的位置&#xff08;开发阶段&#xff09; 2.实验结果3.…

RISC-V U-Boot 启动 Linux 内核的参数

RISC-V U-Boot 启动 Linux 内核的参数 U-Boot (the Universal Boot Loader简写U-Boot) flyfish U-Boot 启动Linux内核的参数举例说明 RISC-V U-Boot 启动 Linux 内核的参数方式一 文本操作earlyprintksunxi-uart,0x02500000clk_ignore_unusedconsolettyS0,115200init/sbin/i…

go-resiliency源码解析之-batcher

go-resiliency源码解析之-batcher 源代码地址 &#xff1a; https://github.com/eapache/go-resiliency/blob/master/batcher/batcher.go 1.batcher定义 创建一个batch对象需要2个参数: Timeout:超时,这是一个batch对象收集输入参数的时间。 work函数变量&#xff1a;在ti…

使用Jumpserver+Frp集中管理远程内网服务器

我们设想这样一种情况&#xff0c;我们是一家小公司&#xff0c;在全国有几个小分支办公机构&#xff0c;每个机构有一台服务器&#xff0c;由于公司财务紧张&#xff0c;买不起专线&#xff0c;用的也是普通家用宽带&#xff0c;SD-WAN设备说实话也挺贵的&#xff0c;那么我们…

Docker部署MySQL主从复制架构

文章目录 1、准备工作2、下拉镜像&#xff0c;启动容器3、编辑 MySQL 主节点配置4、编辑 MySQL 从节点配置5、通过 Navicat 配置主节点6、通过 Navicat 配置从节点7、最终测试 1、准备工作 云服务器&#xff08;虚拟机也可以&#xff09;安装Docker&#xff0c;参考该文章第1小…

Telnet 【实验】

1 什么是Telnet&#xff1f; Telnet是进行远程登录的标准协议&#xff0c;它是当今Internet上应用最广泛的协议之一。它把用户正在使用的终端或计算机变成网络某一远程主机的仿真终端&#xff0c;使得用户可以方便地使用远程主机上的软、硬件资源。 为什么需要telnet&#xf…

python自动化程序操作浏览器在后台访问网站

目录 1、简介2、详细步骤3、驱动3.1、ChromeDriver3.2、GeckoDriver3.3、Microsoft WebDriver3.4、下载链接 4、完整代码 ⭐在当今信息化的时代&#xff0c;访问网站已经成为人们生活中必不可少的一部分。 1、简介 对于某些需要批量访问网站的任务&#xff0c;手动访问既费时又…

Java - Thread、ThreadLocal、ThreadLocalMap

一、概念 用处每个线程需要持有自己单独的数据&#xff0c;数据在同线程中被多个地方共享&#xff0c;但多线程中不共享。原理创建 ThreadLocal 对象用来存取值&#xff0c;操作的是 CurrentThread 里的 ThreadLocalMap&#xff0c;由于每个 Thread 中都有自己的 ThreadLocalM…

Codeforces Round 870 (Div. 2)

Codeforces Round 870 (Div. 2) A. Trust Nobody 题意&#xff1a; 给你一个数组a&#xff0c;a[i]表示第i个人认为至少有a[i]个人说谎&#xff0c;请你找到正确的说谎人数 思路&#xff1a; 我们认为说谎人数有x人&#xff0c;那么数组a中大于x的元素都是说谎&#xff0c;…

rosbag相关操作

一些很好用的网站 时间戳在线转换网页 旋转矩阵、四元数、绕轴旋转、欧拉角在线转换网页 四元数、欧拉角可视化在线转换网页 一、按时间截取bag 使用如下代码&#xff1a; rosbag filter 原始包名.bag 截取后的包名.bag "t.to_sec() > 开始时间 and t.to_sec() <…