51单片机+DS1302设计一个电子钟(LCD1602显示时间)

一、前言

电子钟是一种能够准确显示时间的设备,广泛应用于家庭、办公场所和公共场所,为人们提供了方便和准确的时间信息。本项目设计一个基于51单片机的电子钟,使用DS1302作为RTC时钟芯片,LCD1602作为显示屏,并通过串口方式连接上位机进行时间设置和闹钟设置。

STC89C52作为主控芯片,具有较高的性能和稳定性,可完成对外设的控制和数据处理。DS1302是一款低功耗的实时时钟芯片,能够提供准确的时间计数和日期功能。LCD1602是一款常用的字符型液晶显示屏,具有两行16列的显示区域,能够清晰显示时间和其他相关信息。

通过串口连接上位机,用户可以方便地设置电子钟的时间和闹钟时间,实现个性化需求。电子钟带有一个蜂鸣器,可以根据设置的闹钟时间进行响铃,提醒用户。

image-20230913112300737

image-20230913112208076

电子钟具有以下功能:

(1)显示当前时间和日期:LCD1602显示屏将实时更新并显示当前的时间和日期信息。

(2)时间设置:通过串口连接上位机,用户可以进行时间的设置,包括小时、分钟和秒。

(3)日期设置:用户可以通过上位机设置当前的年、月和日。

(4)闹钟设置:用户可以设置闹钟的时间,包括小时和分钟。到达设定时间时,蜂鸣器将响铃提醒用户。

(5)整点报时:每到整点,蜂鸣器将发出短促的提示音,提醒用户当前时间。

(6)闹钟响铃:当闹钟时间到达时,蜂鸣器将持续响铃,直到用户停止。

(7)该项目将借助STC89C52单片机的控制能力和串口通信功能,结合DS1302时钟芯片和LCD1602显示屏,实现一个简单而实用的电子钟。用户可以根据自己的

(8)需求进行时间设置和闹钟设置,方便实用,并且具有较高的准确性和稳定性。

二、项目的设计思路

项目的设计思路分为硬件设计和软件设计两部分。

2.1 硬件设计思路

(1)主控芯片选择:选择STC89C52作为主控芯片,由于其较高的性能和稳定性,适合用于控制和数据处理。

(2)RTC时钟芯片选择:选择DS1302作为RTC时钟芯片,具有低功耗、精确计时和日期功能。

(3)显示屏选择:选择LCD1602作为显示屏,它具有两行16列的字符显示区域,能够清晰显示时间和其他相关信息。

(4)串口连接:设计串口连接电路,实现与上位机的通信,用于时间设置和闹钟设置。

(5)蜂鸣器:添加蜂鸣器模块,用于整点报时和闹钟响铃功能。

(6)按键输入:添加按键输入模块,用于用户操作,如切换设置模式、调整时间和设置闹钟。

2.2 软件设计思路

(1)初始化设置:在程序启动时,进行硬件初始化,包括配置主控芯片的引脚、初始化DS1302时钟芯片和LCD1602显示屏。

(2)时间获取与显示:通过DS1302时钟芯片获取当前的时间和日期,并将其显示在LCD1602显示屏上。

(3)串口通信:通过串口与上位机进行通信,接收上位机发送的时间设置和闹钟设置指令,并进行相应的处理

(4)时间设置:根据上位机发送的时间设置指令,更新DS1302时钟芯片的时间计数器。

(5)日期设置:根据上位机发送的日期设置指令,更新DS1302时钟芯片的日期计数器。

(6)闹钟设置:根据上位机发送的闹钟设置指令,设置闹钟时间,并将其保存在主控芯片的内部存储器中。

(7)整点报时:通过检测DS1302时钟芯片的小时计数器,当小时值变化时,触发蜂鸣器发出短促的提示音。

(8)闹钟响铃:通过比较当前时间和保存的闹钟时间,当达到闹钟时间时,触发蜂鸣器持续响铃,直到用户停止或设定的时间段结束。

三、项目硬件接线

(1)STC89C52与DS1302:

STC89C52的P2.0口连接到DS1302的SCLK(时钟)引脚,用于提供时钟信号。

STC89C52的P2.1口连接到DS1302的IO(数据)引脚,用于数据传输。

STC89C52的P2.2口连接到DS1302的RST(复位)引脚,用于对DS1302进行复位操作。

(2)STC89C52与LCD1602:

STC89C52的P0口连接到LCD1602的D0-D7引脚,用于传输字符数据和控制信号。

STC89C52的P2.3口连接到LCD1602的RS(寄存器选择)引脚,用于选择数据或命令寄存器。

STC89C52的P2.4口连接到LCD1602的RW(读写选择)引脚,用于选择读或写操作。

STC89C52的P2.5口连接到LCD1602的E(使能)引脚,用于启动传输。

(3)STC89C52与蜂鸣器模块:

STC89C52的P3.7口连接到蜂鸣器模块的信号引脚,用于触发蜂鸣器响铃。

(4)串口通信接口。在STC89C52单片机上,串口引脚如下:

UART接收线(RXD):连接至外部设备的发送线。

STC89C52的P3.0口(RXD)用于接收串口数据。

UART发送线(TXD):连接至外部设备的接收线。

STC89C52的P3.1口(TXD)用于发送串口数据。

四、项目代码

4.1 DS1302时钟读取、设置

下面代码实现了,STC89C52读取DS1302时钟信息打印到串口,以及设置闹钟、时间读取、打印到串口的功能。其中,采用了UART通信进行与上位机交互,可以接收上位机发送过来的时间字符串,并据此设置闹钟和时间。

#include <reg52.h>
#include <stdio.h>#define uchar unsigned char
#define uint unsigned int// 定义DS1302时钟寄存器地址
#define DS1302_SEC_REG 0x80
#define DS1302_MIN_REG 0x82
#define DS1302_HR_REG 0x84
#define DS1302_DAY_REG 0x86
#define DS1302_MONTH_REG 0x88
#define DS1302_YEAR_REG 0x8C// 定义DS1302控制寄存器命令
#define DS1302_CMD_WRITE 0x80
#define DS1302_CMD_READ 0x81// 定义串口波特率为9600
#define BAUDRATE 9600
#define FOSC 11059200L
#define TIMER_INTERVAL (65536 - FOSC / 12 / BAUDRATE)// 声明全局变量
uchar time_buffer[20]; // 存放时间字符串
uchar alarm_buffer[20]; // 存放闹钟时间字符串
uint i;
bit flag; // 标记是否接收到上位机的时间字符串// 初始化UART模块
void InitUart() {TMOD &= 0x0F;TMOD |= 0x20;TH1 = TIMER_INTERVAL / 256;TL1 = TIMER_INTERVAL % 256;PCON |= 0x80;SCON = 0x50;ES = 1;TR1 = 1;EA = 1;
}// 将单个字节发送到串口
void SendData(uchar dat) {SBUF = dat;while (!TI);TI = 0;
}// 将字符串发送到串口
void SendString(uchar *s) {while (*s != '\0') {SendData(*s++);}
}// 初始化DS1302时钟芯片
void InitDS1302() {uchar i;// 使能DS1302写保护功能DS1302_CE = 0;DS1302_SCL = 0;DS1302_CE = 1;Write_DS1302(DS1302_CMD_WRITE | 0x8e, 0x80);// 关闭时钟允许,准备写入数据Write_DS1302(DS1302_CMD_WRITE | 0x90, 0x00);// 写入年月日时分秒周Write_DS1302(DS1302_SEC_REG, 0x00);Write_DS1302(DS1302_MIN_REG, 0x30);Write_DS1302(DS1302_HR_REG, 0x11);Write_DS1302(DS1302_DAY_REG, 0x08);Write_DS1302(DS1302_MONTH_REG, 0x09);Write_DS1302(DS1302_YEAR_REG, 0x21);Write_DS1302(0x8e, 0x00);// 初始化闹钟时间for (i = 0; i < 20; i++) {alarm_buffer[i] = 0;}
}// 向DS1302写入数据
void Write_DS1302(uchar addr, uchar dat) {uchar i;DS1302_CE = 0;DS1302_SCL = 0;// 发送起始信号DS1302_CE = 1;DS1302_SCL = 1;DS1302_CE = 0;// 发送命令字节地址DS1302_WriteByte(addr);// 发送数据字节DS1302_WriteByte(dat);// 停止信号DS1302_SCL = 0;DS1302_CE = 1;// 延时至少1usfor (i = 0; i < 10; i++);
}// 向DS1302读取数据
uchar Read_DS1302(uchar addr) {uchar dat;uchar i;DS1302_CE = 0;DS1302_SCL = 0;// 发送起始信号DS1302_CE = 1;DS1302_SCL = 1;DS1302_CE = 0;// 发送命令字节地址DS1302_WriteByte(addr | 0x01);// 读取数据字节dat = DS1302_ReadByte();// 停止信号DS1302_SCL = 0;DS1302_CE = 1;// 延时至少1usfor (i = 0; i < 10; i++);return dat;
}// 读取DS1302时间并打印到串口
void ReadTime() {uchar sec, min, hour, day, month, year;sprintf(time_buffer, "Time: ");sec = Read_DS1302(DS1302_SEC_REG);min = Read_DS1302(DS1302_MIN_REG);hour = Read_DS1302(DS1302_HR_REG);day = Read_DS1302(DS1302_DAY_REG);month = Read_DS1302(DS1302_MONTH_REG);year = Read_DS1302(DS1302_YEAR_REG);sprintf(time_buffer + 6, "%02d:%02d:%02d %02d/%02d/%02d\r\n", hour, min, sec, day, month, year);SendString(time_buffer);
}// 向DS1302写入闹钟时间
void SetAlarm(uchar *str) {uint i = 0;// 将字符串转换为数字while (str[i] != '\0') {alarm_buffer[i] = str[i] - '0';i++;if (i > 19) // 防止溢出break;}// 写入闹钟时间Write_DS1302(DS1302_CMD_WRITE | 0x81, alarm_buffer[10] << 4 | alarm_buffer[11]);Write_DS1302(DS1302_CMD_WRITE | 0x83, alarm_buffer[8] << 4 | alarm_buffer[9]);Write_DS1302(DS1302_CMD_WRITE | 0x85, alarm_buffer[6] << 4 | alarm_buffer[7]);
}// 从串口接收数据中解析出时间信息
void ParseTime() {uchar i, j;uchar temp;for (i = 0; i < 20; i++) {time_buffer[i] = 0;}// 接收字符串格式为:hh:mm:ss dd/mm/yyfor (i = 0; i < 8; i++) {temp = 0;for (j = 0; j < 2; j++) {temp *= 10;temp += (SBUF - '0');while (!RI); // 等待接收完成RI = 0;}time_buffer[i] = temp;if (i == 2 || i == 4) {while (SBUF != ' '); // 跳过空格字符while (!RI); // 等待接收完成RI = 0;}}flag = 1; // 标记已经接收到字符串
}// 主函数
void main() {InitUart();InitDS1302();flag = 0;while (1) {if (flag) { // 接收到时间字符串,设置闹钟和时间SetAlarm(time_buffer);Write_DS1302(DS1302_CMD_WRITE | 0x80, time_buffer[6] << 4 | time_buffer[7]);Write_DS1302(DS1302_CMD_WRITE | 0x82, time_buffer[3] << 4 | time_buffer[4]);Write_DS1302(DS1302_CMD_WRITE | 0x84, time_buffer[0] << 4 | time_buffer[1]);flag = 0;}ReadTime(); // 读取当前时间并发送到串口}
}// UART接收中断函数
void UartIsr() interrupt 4 {if (RI) { // 接收到数据ParseTime(); // 解析时间字符串}RI = 0;
}

4.2 LCD1602显示时钟

基于STC89C52控制LCD1602显示时间字符串的实现代码。

#include <reg52.h>
#include <stdio.h>// 定义Data和Command寄存器选择端口
sbit LCD_RS = P2^0;  // RS引脚(寄存器选择)
sbit LCD_RW = P2^1;  // RW引脚(读写选择)
sbit LCD_EN = P2^2;  // EN引脚(使能)// 定义数据总线端口
#define LCD_DATA P0    void DelayMs(unsigned int ms) {unsigned int i, j;for (i = 0; i < ms; i++)for (j = 0; j < 120; j++);
}void WriteCommand(unsigned char cmd) {LCD_RS = 0;  // 选择指令寄存器LCD_RW = 0;  // 写模式LCD_EN = 0;  // 低电平使能LCD_DATA = cmd;  // 发送指令DelayMs(1);  // 延时等待指令写入LCD_EN = 1;  // 高电平使能DelayMs(1);  // 持续一段时间LCD_EN = 0;  // 结束使能
}void WriteData(unsigned char dat) {LCD_RS = 1;  // 选择数据寄存器LCD_RW = 0;  // 写模式LCD_EN = 0;  // 低电平使能LCD_DATA = dat;  // 发送数据DelayMs(1);  // 延时等待数据写入LCD_EN = 1;  // 高电平使能DelayMs(1);  // 持续一段时间LCD_EN = 0;  // 结束使能
}void LCDInit() {WriteCommand(0x38);  // 设置显示模式为2行、5x8点阵字符WriteCommand(0x0C);  // 显示器开,光标关闭WriteCommand(0x06);  // 光标右移,整屏不移动WriteCommand(0x01);  // 清除显示并设置光标回到初始位置
}void LCDDisplayTime(char* time) {int i;WriteCommand(0x80);  // 设置光标位置为第一行的起始位置for (i = 0; i < 16; i++) {WriteData(time[i]);  // 在第一行显示时间字符串}WriteCommand(0xC0);  // 设置光标位置为第二行的起始位置for (i = 0; i < 16; i++) {WriteData(time[16 + i]);  // 在第二行显示时间字符串}
}void main() {char time_buffer[32] = "Current Time: 00:00:00";  // 时间字符串unsigned char sec = 0, min = 0, hour = 0;  // 当前时间变量LCDInit();  // 初始化LCD显示器while (1) {// 更新时间变量sec++;if (sec >= 60) {sec = 0;min++;if (min >= 60) {min = 0;hour++;if (hour >= 24) {hour = 0;}}}// 格式化时间字符串sprintf(time_buffer + 14, "%02d:%02d:%02d", hour, min, sec);// 显示时间字符串LCDDisplayTime(time_buffer);DelayMs(1000);  // 延时1秒}
}

代码使用LCD_RSLCD_RWLCD_EN分别表示LCD1602的RS、RW和EN引脚。数据总线通过LCD_DATA定义,连接到P0端口。先初始化LCD显示器,在一个无限循环中更新时间变量并格式化时间字符串,最后在LCD上显示时间字符串。

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

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

相关文章

uniapp开发ios上线(在win环境下使用三方)

苹果 1、win环境下无法使用苹果os编译器所以使用第三方上传工具&#xff0c;以下示例为 初雪云 &#xff08;单次收费&#xff0c;一元一次&#xff09; 初雪云&#xff08;注册p12证书&#xff09;&#xff1a;https://www.chuxueyun.com/#/pages/AppleCertificate 苹果开发者…

Postman常见报错与解决方法,持续更新~

postman中文文档 基本操作&#xff1a;从控制台查看请求报错 如果 Postman 无法发送你的请求&#xff0c;或者如果它没有收到你发送请求的 API 的响应&#xff0c;你将收到一条错误消息。此消息将包含问题概述和指向控制台的链接&#xff0c;你可以在其中访问有关请求的详细信…

Visual Studio Code安装和设置中文

文章目录 Visual Studio Code安装Visual Studio Code设置中文 步骤如下: Visual Studio Code安装 1.下载安装包 VS Code的官网 下载链接中的“az764295.vo.msecnd.net” 替换为国内镜像地址“vscode.cdn.azure.cn”&#xff0c;下载速度直接飙升至几十 Mb/s。(在官网下载速度…

【OpenCV(3)】linux arm aarch 是 opencv 交叉编译与使用

文章目录 1、直接找github 别人编译好的2、自主编译参考 3使用CMake检查 参考 1、直接找github 别人编译好的 测试很多&#xff0c;找到一个可用的。 https://github.com/dog-qiuqiu/libopencv 它用了超级模块&#xff01; OpenCV的world模块也称为超级模块&#xff08;supe…

NovelD: A Simple yet Effective Exploration Criterion论文笔记

NovelD:一种简单而有效的探索准则 1、Motivation 针对稀疏奖励环境下的智能体探索问题&#xff0c;许多工作中采用各种内在奖励(Intrinsic Reward)设计来指导困难探索环境中的探索 &#xff0c;例如&#xff1a; ICM&#xff1a;基于前向动力学模型的好奇心驱动探索RND&…

【Qt-23】Qt charts绘制曲线图

一、QChart简介 QChart是Qt中专门用于绘制图表的模块&#xff0c;支持折线图、柱状图、饼图等常见类型。其主要组成部分有&#xff1a; QChart&#xff1a;整个图表的容器&#xff0c;管理图表中的所有数据和图形属性QChartView&#xff1a;继承自QGraphicsView&#xff0c;用于…

小波神经网络的时间序列预测——短时交通流量预测

大家好&#xff0c;我是带我去滑雪&#xff01; 小波神经网络&#xff08;Wavelet Neural Network&#xff0c;WNN&#xff09;结合了小波变换和神经网络的特性&#xff0c;是一种在信号处理和模式识别领域应用广泛的神经网络模型。它的设计灵感来自于小波变换的多尺度分析特性…

解决k8s通过traefik暴露域名失败并报错:Connection Refused的问题

我敢说本篇文章是网上为数不多的解决traefik暴露域名失败问题的正确文章。 我看了网上太多讲述traefik夸夸其谈的文章了&#xff0c;包含一大堆复制粘贴的水文和还有什么所谓“阿里技术专家”的文章&#xff0c;讲的全都是错的&#xff01;基本没有一个能说到点子上去&#xf…

Istio学习笔记-部署模型

参考&#xff1a;Istioldie 1.18 / 部署模型 当您将 Istio 用于生产环境部署时&#xff0c;需要确定一系列的问题。 网格将被限制在单个集群中还是分布在多个集群中&#xff1f; 是将所有服务都放置在单个完全连接的网络中&#xff0c;还是需要网关来跨多个网络连接服务&#…

优秀智慧园区案例 - 新华三未来工厂制造园,园区业务创新及零碳升级

目录 一、新华三未来工厂制造园建设背景 二、未来工厂制造园总体设计思路 三、未来工厂制造园建设内容 四、关键技术及创新点 五、应用效益与推广 关键词&#xff1a;智慧园区解决方案&#xff0c;智慧园区建设总体方案&#xff0c;智慧园区建设规划方案&#xff0c;智慧园…

uniapp的实战总结大全

&#x1f642;博主&#xff1a;冰海恋雨 &#x1f642;文章核心&#xff1a;uniapp部分总结 目录 ​编辑 目录 前言&#xff1a; 解决方案 1. 跨平台开发 2. Vue.js生态 3. 组件库 4. 自定义组件 5. Native能力 6. 插件生态 7. 性能优化 写法 1. 模板&#xf…

PyCharm鼠标控制字体缩放

File->Settings->Keymap 右边搜索栏输入increase(放大)&#xff0c;可以看到下面出现increase Font Size(放大字体尺寸)&#xff0c;双击。 双击后出现几个选项&#xff0c;选择Add Mouse Shortcut,会出现一个页面给录入动作。 按住Ctrl同时鼠标向上滚动&#xff0c;该动…

【NLP】大型语言模型,ALBERT — 用于自监督学习的 Lite BERT

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

什么是OpenCL?

什么是OpenCL&#xff1f; 1.概述 OpenCL(Open Computing Language 开放计算语言)是一种开放的、免版税的标准&#xff0c;用于超级计算机、云服务器、个人计算机、移动设备和嵌入式平台中各种加速器的跨平台并行编程。OpenCL是由Khronos Group创建和管理的。OpenCL使应用程序…

为什么打开idea时,没有启动页面,如何解决?

更新idea2021.2后&#xff0c;当双击idea打开时&#xff0c;发现没有启动界面&#xff0c;直接进入IDEA界面&#xff0c;中间等待时间&#xff0c;让人误以为没有打开idea成功&#xff0c;使得多次点击idea图标。 解决方案就是 在idea界面菜单栏中找到帮助&#xff08;Help)&a…

(论文阅读32/100)Flowing convnets for human pose estimation in videos

32.文献阅读笔记 简介 题目 Flowing convnets for human pose estimation in videos 作者 Tomas Pfister, James Charles, and Andrew Zisserman, ICCV, 2015. 原文链接 https://arxiv.org/pdf/1506.02897.pdf 关键词 Human Pose Estimation in Videos 研究问题 视频…

挂耳式运动耳机哪个品牌好?5款公认好用的运动耳机推荐

​在现代社会&#xff0c;耳机已经成为了人们生活中必不可少的数码设备。在运动的时候&#xff0c;佩戴耳机更是成为了很多人的标配。但是&#xff0c;市面上的运动耳机种类繁多&#xff0c;如何选择一款适合自己的呢&#xff1f;今天我为大家挑选了5款公认好用的运动耳机&…

PyTorch技术和深度学习——四、神经网络训练与优化

文章目录 1.神经网络迭代概念1&#xff09;训练误差与泛化误差2&#xff09;训练集、验证集和测试集划分3&#xff09;偏差与方差 2.正则化方法1&#xff09;提前终止2&#xff09;L2正则化3&#xff09;Dropout 3.优化算法1&#xff09;梯度下降2&#xff09;Momentum算法3)RM…

​软考-高级-系统架构设计师教程(清华第2版)【第4章 信息安全技术基础知识(P160~189)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第4章 信息安全技术基础知识&#xff08;P160~189&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

LeetCode(10)跳跃游戏 II【数组/字符串】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 45. 跳跃游戏 II 1.题目 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nu…