单片机学习 15-ds1302时钟实验

news2024/11/24 6:00:01

DS1302 时钟实验

​ 在前面章节,我们介绍了如何使用单片机 IO 口模拟 IIC 总线、单总线时序。这一章我们来学习 DS1302 时钟芯片,该芯片是 3 线 SPI 接口,所以需要使用 51单片机的 3 个 IO 口模拟 SPI 时序与 DS1302 时钟芯片通信,将时钟日历数据读取出来。开发板上集成了 1 个 DS1302 时钟模块,可使用它设计一个多功能电子时钟。本章要实现的功能是:系统运行时,数码管上显示电子时钟时分秒,格式为“XX-XX-XX”。

DS1302时钟芯片介绍

DS1302简介

​ DS1302是DALLAS公司推出的涓流充电时钟芯片,内含有一个实时时钟/日历和31字节静态RAM,通过简单的串行接口与单片机进行通信。实时时钟/日历电路提供秒、分、时、日、周、月、年的信息,每月的天数和闰年的天数可自动调整。时钟操作可通过AM/PM指示决定采用24或12小时格式。DS1302与单片机之间能简单地采用同步串行的方式进行通信,仅需用到三根通信线:①RES复位②I/O数据线③SCLK串行时钟。时钟/RAM的读/写数据以一个字节或多达31个字节的字符组方式通信。DS1302工作时功耗很低保持数据和时钟信息时功率小于1mW。

​ DS1302由DS1202改进而来增加了以下的特性:双电源管脚用于主电源VCC2和备份电源VCC2供应,Vcc1为可编程涓流充电电源,附加七个字节存储器。它广泛应用于电话、传真、便携式仪器以及电池供电的仪器仪表等产品领域下面。

​ 主要的性能指标:
​ ★实时时钟具有能计算2100年之前的秒、分、时、日、星期、月、年的能力,还有闰年调整的能力;
​ ★31个8位暂存数据存储RAM;
​ ★串行I/O口方式使得管脚数量最少;
​ ★宽范围工作电压2.0~5.5V;
​ ★工作在2.0V时,电流小于300nA;
​ ★读/写时钟或RAM数据时有两种传送方式单字节传送和多字节传送字符组
方式;
​ ★8脚DIP封装或可选的8脚SOIC封装根据表面装配;
​ ★简单3线接口;
​ ★与TTL兼容Vcc=5V;
​ ★可选工业级温度范围-40~+85;
下面来看下DS1302芯片的管脚及功能。

1,VCC2:主电源引脚
2,X1、X2:DS1302 外部晶振引脚,通常需外接 32.768K 晶振
3,GND:电源地
4,CE:使能引脚,也是复位引脚(新版本功能变)。
5,I/O:串行数据引脚,数据输出或者输入都从这个引脚
6,SCLK:串行时钟引脚
7,VCC1:备用电源

DS1302使用

​ 操作DS1302的大致过程,就是将各种数据写入DS1302的寄存器,以设置它当前的时间的格式。然后使DS1302开始运作,DS1302时钟会按照设置情况运转,再用单片机将其寄存器内的数据读出。再用液晶显示,就是我们常说的简易电子钟。所以总的来说DS1302的操作分2步,第一步读取时间,第二步将时间显示出来(显示部分属于液晶显示的内容,不属于DS1302本身的内容),但是在讲述操作时序之前,我们要先看看寄存器,
DS1302有一个控制寄存器、12个日历、时钟寄存器和31个RAM。
(1)控制寄存器
​ 控制寄存器用于存放DS1302的控制命令字,DS1302的RST引脚回到高电平后写入的第一个字节就为控制命令。它用于对DS1302读写过程进行控制,格式如下:

上图是DS1302的寄存器样式,我们看到:

1、第7位永远都是1;

2、第6位,1表示RAM,寻址内部存储器地址;0表示CK,寻址内部寄存器;

3、第5到第1位,为RAM或者寄存器的地址;

4、最低位,高电平表示RD,即下一步操作将要“读”;低电平表示W,即下一步操作将要“写”。(与AT24C02寄存器类似,这点要理解好)。

​ 比如要读秒寄存器则命令为 1000 0001,反之写为 1000 0000,要注意其含义。
(2) 日 历/ 时 钟 寄 存 器
​ DS1302 共有 12 个寄存器,其中有 7 个与日历、时钟相关,存放的数据为 BCD码形式。格式如下:

​ 下面对几个寄存器做下说明:

​ **秒 寄 存 器 :**低四位为秒的个位,高的次三位为秒的十位。最高位 CH 为DS1302 的运行标志,当 CH=0 时,DS1302 内部时钟运行,反之 CH=1 时停止;

​ **小 时 寄 存 器 :**时寄存器。最高位为 12/24 小时的格式选择位,该位为 1 时表示 12 小时格式。当设置为 12 小时显示格式时,第 5 位的高电平表示下午(PM);而当设置为 24 小时格式时,第 5 位位具体的时间数据。

​ **写 保 护 寄 存 器 :**当该寄存器最高位 WP 为 1 时,DS1302 只读不写,所以要在往 DS1302 写数据之前确保 WP 为 0。

​ **慢 充 电 寄 存 器 ( 涓 细 电 流 充 电 ) 寄 存 器 :**我们知道,当 DS1302 掉电时,可以马上调用外部电源保护时间数据。该寄存器就是配置备用电源的充电选项的。其中高四位(4 个 TCS)只有在 1010 的情况下才能使用充电选项;低四位的情况与 DS1302 内部电路有关。

​ 前面我们提到在日历/时钟寄存器中都是以 BCD 码存放数据,那么 BCD 码是什么呢?BCD 码是通过 4 位二进制码来表示 1 位十进制中的 0~9 这 10 个数码。如下所示:

​ 所以从 DS1302 中读取出来的时钟数据均为 BCD 码格式,需转换为我们习惯的10进制,转换方法在源程序里,后面我们会介绍。
(3)DS1302的读写时序
​ 在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位(位0)开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。其时序图如下所示:

​ 上图就是DS1302的三个时序:复位时序,单字节写时序,单字节读时序;

​ CE(RST):复位时序,即在RST引脚产生一个正脉冲,在整个读写器件,RST要保持高电平,一次字节读写完毕之后,要注意把RST返回低电平准备下次读写周期;

​ 单字节读时序:注意读之前还是要先对寄存器写命令,从最低位开始写;可以看到,写数据是在SCLK的上升沿实现,而读数据在SCLK的下降沿实现。所以,在单字节读时序中,写命令的第八个上升沿结束后紧接着的第八个下降沿就将要读寄存器的第一位数据读到数据线上了!这个就是DS1302操作中最特别的地方。当然读出来的数据也是最低位开始。

​ 单字节写时序:两个字节的数据配合16个上升沿将数据写入即可。写命令的第八个上升沿结束后接着的第九个上升沿继续将要读寄存器的第一位数据写入。

​ 程序注意事项:
★要记得在操作DS1302之前关闭写保护(将wp设置为0,下次开启再设置为1);

★注意用延时来降低单片机的速度以配合器件时序;

★DS1302读出来的数据是BCD码形式,要转换成我们习惯的10进制,转换方法在源程序里;

★读取字节之前,将IO设置为输入口,读取完之后,要将其改回输出口;

★在写程序的时候,建议实现开辟数组(内存空间)来集中放置DS1302的一系列数据,方便以后扩展键盘输入。

硬件设计

本实验使用到硬件资源如下:
(1)动态数码管
(2)DS1302
动态数码管电路在前面章节都介绍过,这里就不再重复。下面我们来看下开发板上DS1302时钟模块电路,如下图所示:

​ 从上图中可以看出,该电路是独立的,DS1302芯片的控制管脚接至J3端子上,芯片的VCC1脚外接了一个纽扣电池BT1,以保证系统断电后时钟仍然可以运行,在芯片的X1、X2管脚处外接了一个32.768KHZ晶振,为时钟运行提供一个稳定的时钟频率,C2和C3为旁路电容,目的是消除晶振起振时产生的电感干扰。

​ 由于该模块电路是独立的,所以DS1302芯片的控制管脚J3端子可以使用任意单片机管脚连接,为了与我们例程程序配套,这里使用单片机的P3.4管脚与时钟芯片的I/O脚连接,使用单片机的P3.5管脚与时钟芯片的CE脚连接,使用单片机的P3.6管脚与时钟芯片的SCLK脚连接。

软件设计

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l5y5H5wq-1688028515642)(C:\Users\10789\AppData\Roaming\Typora\typora-user-images\image-20220711214631846.png)]

本章所要实现的功能是:数码管上显示电子时钟时分秒,格式为“XX-XX-XX”。
程序框架如下:
(1)编写数码管显示功能
(2)编写 DS1302 时钟读写功能
(3)编写主函数

ds1302.h:

#ifndef _ds1302_H
#define _ds1302_H

#include"public.h"

sbit DS1302_RST=P3^5;
sbit DS1302_IO=P3^4;
sbit DS1302_CLK=P3^6;

extern u8 gDS1302_TIME[7];

void ds1302_write_byte(u8 addr,u8 dat);
u8 ds1302_read_byte(u8 addr);
void ds1302_init(void);
void ds1302_read_time(void);
#endif

ds1302.c:

#include "ds1302.h"
#include "intrins.h"
//---DS1302 写入和读取时分秒的地址命令---//
//---秒分时日月周年 最低位读写位;-------//
u8 gREAD_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
u8 gWRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
//---DS1302 时钟初始化 2021 年 5 月 20 日星期四 13 点 51 分 47 秒。---//
//---存储顺序是秒分时日月周年,存储格式是用 BCD 码---//
u8 gDS1302_TIME[7] = {0x47, 0x51, 0x13, 0x20, 0x04, 0x05, 0x21};
/********************************************************************
***********
* 函 数 名 : ds1302_write_byte
* 函数功能 : DS1302 写单字节
* 输 入 : addr:地址/命令
		 dat:数据
* 输 出 : 无
*********************************************************************
**********/
void ds1302_write_byte(u8 addr,u8 dat)
{
u8 i=0;
DS1302_RST=0;
_nop_();
DS1302_CLK=0;//CLK 低电平
_nop_();
DS1302_RST=1;//RST 由低到高变化
_nop_();
for(i=0;i<8;i++)//循环 8 次,每次写 1 位,先写低位再写高位
{
DS1302_IO=addr&0x01;
addr>>=1;
DS1302_CLK=1;
_nop_();
DS1302_CLK=0;//CLK 由低到高产生一个上升沿,从而写入数据
_nop_();
}
for(i=0;i<8;i++)//循环 8 次,每次写 1 位,先写低位再写高位
{
DS1302_IO=dat&0x01;
dat>>=1;
DS1302_CLK=1;
_nop_();
DS1302_CLK=0;
_nop_();
}
DS1302_RST=0;//RST 拉低
_nop_();
}
/********************************************************************
***********
* 函 数 名 : ds1302_read_byte
* 函数功能 : DS1302 读单字节
* 输 入 : addr:地址/命令
* 输 出 : 读取的数据
*********************************************************************
**********/
u8 ds1302_read_byte(u8 addr)
{
u8 i=0;
u8 temp=0;
u8 value=0;
DS1302_RST=0;
_nop_();
DS1302_CLK=0;//CLK 低电平
_nop_();
DS1302_RST=1;//RST 由低到高变化
_nop_();
for(i=0;i<8;i++)//循环 8 次,每次写 1 位,先写低位再写高位
{
DS1302_IO=addr&0x01;
addr>>=1;
DS1302_CLK=1;
_nop_();
DS1302_CLK=0;//CLK 由低到高产生一个上升沿,从而写入数据
_nop_();
}
for(i=0;i<8;i++)//循环 8 次,每次读 1 位,先读低位再读高位
{
temp=DS1302_IO;
value=(temp<<7)|(value>>1);//先将 value 右移 1 位,然后 temp 左移 7 位,
最后或运算
DS1302_CLK=1;
_nop_();
DS1302_CLK=0;
_nop_();
}
DS1302_RST=0;//RST 拉低
_nop_();
DS1302_CLK=1;//对于实物中,P3.4 口没有外接上拉电阻的,此处代码需要添加,使数
据口有一个上升沿脉冲。
_nop_();
DS1302_IO = 0;
_nop_();
DS1302_IO = 1;
_nop_();
return value;
}
/********************************************************************
***********
* 函 数 名 : ds1302_init
* 函数功能 : DS1302 初始化时间
* 输 入 : 无
* 输 出 : 无
*********************************************************************
**********/
void ds1302_init(void)
{
u8 i=0;
ds1302_write_byte(0x8E,0X00);
for(i=0;i<7;i++)
{
ds1302_write_byte(gWRITE_RTC_ADDR[i],gDS1302_TIME[i]);
}
ds1302_write_byte(0x8E,0X80);
}
/********************************************************************
***********
* 函 数 名 : ds1302_read_time
* 函数功能 : DS1302 读取时间
* 输 入 : 无
* 输 出 : 无
*********************************************************************
**********/
void ds1302_read_time(void)
{
u8 i=0;
for(i=0;i<7;i++)
{
gDS1302_TIME[i]=ds1302_read_byte(gREAD_RTC_ADDR[i]);
}
}

​ 各函数功能在代码内有详细注释,大家可以参考注释理解。程序开头定义了3个数组:gREAD_RTC_ADDR、gWRITE_RTC_ADDR和gDS1302_TIME。gREAD_RTC_ADDR和gWRITE_RTC_ADDR数组内存储的是DS1302写入和读取时分秒的地址命令,这个可以对照前面介绍的寄存器看。TIME数组是用来存储初始化时间,每个数据对应含义在代码内已做注释。在使用中主要调用ds1302init()函数和ds1302readtime()函数来初始化DS1302时钟数据以及读取DS1302时钟数据。

​ 在初始化时钟数据时,首先要禁止写保护即关闭写保护功能,然后将所需设置的时钟数据写入到对应的时钟寄存器地址内,最后打开写保护功能,以防止意外修改DS1302内部寄存器。对于读取时钟数据其实很简单,只要从对应的时钟寄存器地址内读取数据即可,然后将读取的数据存储到一个缓存数组中,方便数据的处理与显示,这个操作在后面main.c文件内会有。

main.c:

/********************************************************************
******************
实验名称:DS1302 时钟实验
接线说明:
实验现象:下载程序后,数码管上显示电子时钟时分秒,格式为“XX-XX-XX”
注意事项:
*********************************************************************
******************/
#include "public.h"
#include "smg.h"
#include "ds1302.h"
/********************************************************************
***********
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*********************************************************************
**********/
void main()
{
u8 time_buf[8];
ds1302_init();//初始化 DS1302
while(1)
{
ds1302_read_time();
time_buf[0]=gsmg_code[gDS1302_TIME[2]/16];
time_buf[1]=gsmg_code[gDS1302_TIME[2]&0x0f];
time_buf[2]=0x40;
time_buf[3]=gsmg_code[gDS1302_TIME[1]/16];
time_buf[4]=gsmg_code[gDS1302_TIME[1]&0x0f];
time_buf[5]=0x40;
time_buf[6]=gsmg_code[gDS1302_TIME[0]/16];
time_buf[7]=gsmg_code[gDS1302_TIME[0]&0x0f];
smg_display(time_buf,1);
}
}

​ 主函数代码非常简单,首先调用外设头文件,然后初始化DS1302并设定好初始时间,进入while循环,读取DS1302时钟数据存储至全局变量数组gDS1302_TIME中,最后将读取的数据转换为数码管可显示的段码数据并调用数码管显示函数显示时间。

细心的朋友可能发现,在处理DS1302读取的数据时,取高低位是使用除16和取余16,并非之前的除10和取余10。这是因为写入进DS1302时是BCD码,读取出的数据也是BCD码,而BCD码即是4位表示一个十进制数,类似于一个字节的十六进制数据的高4位和低4位一样,所以这里是除16和取余16。

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

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

相关文章

maven打包本地jar到项目中

在maven项目中&#xff0c;我们的项目依赖一般取自local的repository或者远程的repository&#xff0c;比如下面这个配置&#xff1a; maven <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> &l…

蓝桥杯专题-试题版-【矩阵乘法】【连号区间数】【闰年判断】【时间转换】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

爱普生L3515打印不出东西,打印后机器工作进纸后出来空白纸张

环境&#xff1a; 爱普生L3515彩色喷墨打印机 问题描述&#xff1a; 爱普生L3515突然打印不出东西&#xff0c;打印后机器工作进纸&#xff0c;出来空白纸张 解决方案&#xff1a; 1.检查是否没有墨水了&#xff0c;开始以为没了&#xff0c;加了满了 2.测试打印机还是打不…

【AUTOSAR】BMS开发实际项目讲解(十五)----电池管理系统架构与系统组件定义

系统架构 /System Architecture 系统结构框图 / System Structure Diagram 系统安全架构图 系统组件定义 / System Components Definition 系统组件定义表 组件需求定义/system components requirement definition系统组件需求定义表 ID 名称 ASIL 描述 SPFM LFM PMHF …

将英文版的Visual Studio 2019 切换为简体中文显示

一、需求说明 在使用Visual Studio 2019集成IDE环境下进行开发工作时;需要将IDE的环境修改为中文环境进行开发工作,中文界面对于不太熟悉Visual Studio 2019 环境的人来说是十分友好的。 二、需求分析 目前安装的Visual Studio 2019集成IDE环境是全英文的界面,需要切换为简…

hash冲突是什么?

哈希&#xff08;散列&#xff09;原理及使用 哈希&#xff08;散列&#xff09;原理及避免哈希冲突 哈希&#xff08;散列&#xff09;原理及使用哈希冲突常见哈希函数解决哈希冲突方案实现一个开散列哈希表 当我们在一堆数据中查找一个元素时&#xff0c;使用普通方法得到的时…

ChatGPT: 交互式AI助手为互联网用户带来全新体验

目录 概述&#xff1a; 优势&#xff1a; 挑战&#xff1a; 未来发展方向&#xff1a; 概述&#xff1a; 在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;正以惊人的速度改变着我们的生活方式和体验方式。AI 的应用范围越来越广泛&#xff0c;从语音助手到…

Linux 内存详解,即top、free、vmstat、meminfo、Buffer和Cache的介绍

Linux 内存详解&#xff0c;即top、free、vmstat、meminfo、Buffer和Cache的介绍_用作内核缓存的内存量_zzhongcy的博客-CSDN博客 1、top linux下的任务管理器 top命令是Linux下常用的性能分析工具&#xff0c;能够实时显示系统中各个进程的资源占用状况&#xff0c;类似于Win…

C#项目练习系列--1.倒计时器

C#项目练习系列--1.倒计时器 实操感想代码 实操 总体实现功能&#xff1a;选定计时时间—点击开始计时—进度条和剩余时间显示—提示时间到。 软件版本&#xff1a;VS2019 1.新建工程 选择c#&#xff0c;windows窗体应用&#xff0c;.NET Framework版本选择4或4以下时最后…

SpringBoot+WebSocket+Session共享

前言 WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端 一、为什么需要WebSocket HTTP 是基于请求响应式的&#xff0c;即通信只能由客户端发起&#xff0c;服务端做出响应&#xff0c;无状态&…

Spring Boot 中的 PropertySource 是什么,原理,如何使用

Spring Boot 中的 PropertySource 是什么&#xff0c;原理&#xff0c;如何使用 介绍 在 Spring Boot 中&#xff0c;PropertySource 是一个非常重要的概念。它允许您在应用程序中定义属性&#xff0c;并将这些属性注入到 Spring 环境中。在本文中&#xff0c;我们将介绍 Spr…

GO富集绘图绘制方法,零基础教程,替换数据直接作图,完成版R语言脚本

速绘 丨 GO富集气泡图 本期分享一个快速绘制GO富集结果图的方法&#xff0c;主要使用R语言tidyverse包&#xff0c;只需导入数据即可一步出图&#xff0c;可以自定义显示的数目、颜色、筛选参数&#xff0c;从此以后绘制GO富集图只需1秒。 前言介绍 下面是一个GO富集分析的结果…

Python 控制 AWG70001

0. 实验准备 泰克 AWG70001 一台电脑 一根网线 使用网线连接 AWG70001 和电脑&#xff0c;并且配置 IP 在同一网段下 1. 环境要求 vxi11 numpy struct matplotlib 没有的库可以使用下面的命令安装 pip install vxi11 pip install numpy pip install struct pip install matp…

Android中构建多视图 RecyclerView的正确打开方式

Android中构建多视图 RecyclerView的正确打开方式 简介 漂亮的UI能极大提高用户留存率&#xff0c;相反糟糕的UI将导致App安装率下降。 UI体验对用户留存率有特别大的影响&#xff0c;较差的体验app我可能用不了2s就要卸载掉。 你需要学习内容如下&#xff1a; 使用单个R…

STM32F407开发板DS18B20应用案例

【1】DS18B20介绍 DS18B20是一种数字温度传感器&#xff0c;由Maxim Integrated公司生产。它采用单总线接口&#xff0c;能够在广泛的温度范围内测量温度&#xff0c;并通过数字方式输出温度值&#xff0c;具有较高的精度和稳定性。 以下是DS18B20温度传感器的主要特点和操作…

拯救者Lenovo Legion Y9000X IAH7 2022款(82TF)原装出厂Windows11系统恢复原厂OEM系统

Lenovo联想拯救者笔记本电脑 Legion Y9000X IAH7 2022款(82TF)出厂状态原装Win11系统&#xff0c;恢复原厂系统 系统自带所有驱动、出厂主题壁纸LOGO、Office办公软件、联想电脑管家等预装程序 所需要工具&#xff1a;16G或以上的U盘 文件格式&#xff1a;ISO 文件大小&am…

人类最新版去水印+外卖CPS小程序源码+独立后台微擎模块

最新版去水印外卖CPS小程序源码 本版本为目前最新版本 修复上个版本后台用户列表加载失败问题 新增轮播图跳转小程序 新增外卖CPS系统

layui学习

官网&#xff1a;Layui镜像站-经典开源模块化前端 UI 框架(官方文档完整镜像) 下载&#xff1a;可以在首页进行下载 快速入门Layui | 枫桥夜泊 如果不知道样式在哪个模块下&#xff0c;引入总的核心样式文件&#xff1b;如果知道样式在哪个模块下&#xff0c;直接引入module…

线程间通信

1、需求 现在两个线程操作一个初始值为0的变量实现一个线程对变量增加1&#xff0c;一个线程对变量减少1交替&#xff0c;来10轮 2、多线程编程模板中 1&#xff09;判断 2&#xff09;干活 3&#xff09;通知 线程间通信&#xff1a; 1.生产者消费者 2.通知等待唤醒机制 3…

Aski AI: 基于人工智能的在线AI工具平台

【产品介绍】 Aski AI是一个基于人工智能的在线AI工具平台&#xff0c;它可以帮助用户快速、准确、全面地解决各种问题。无论是学习、工作、生活、娱乐还是其他领域&#xff0c;只要输入你的问题&#xff0c;Aski AI就会为你提供最合适的答案。此外还提供AI文章写作&#xff0c…