实时时钟DS1302原理详解和单片机编程

news2025/1/13 6:11:09

一、DS1302的功能

DS1302是美国DALLAS推出的一款高性能、低功耗的日历时钟芯片。

DS1302是一种串行接口的实时时钟,芯片内部具有可编程的日历时钟和31个字节的静态RAM,日历时钟可以自动进行闰年补偿,计时准确,接口简单,使用方便,工作电压范围宽(2.5~5.5V),芯片自身还具有对备用电池进行涓流充电功能,可有效延长备用电池的使用寿命。

DS1302用于数据记录,能实现数据与该数据出现的时间同时记录,因此广泛应用于测量系统中。

 

 二、DS1302硬件及引脚功能

 

各引脚功能为:

1、VCC1:主电源。 VCC2:备用电源。当VCC2大于VCC1+0.2V时由VCC2向DS1302供电否则由VCC1向DS1302供电。

2、SCLK:串行时钟输入端,控制数据输入与输出;

3、I/O :双向输入线;

4、CE:使能端,CE为高时允许读写DS1302数据,为低时禁止读写。

三、DS1302寄存器

时钟日历和控制寄存器如图所示:

如上图所示,时钟日历寄存器包含在7个读/写寄存器内,读/写寄存器中的数据是BCD码。

秒寄存器(81h、80h)的BIT7定义为时钟暂停标志(CH)。当该位置为1时,时钟振荡器停止,DS1302处于低功耗状态;当该位置为0时,时钟开始运行。

小时寄存器(85h、84h)的BIT7用于定义DS1302是运行于12小时模式还是24小时模式,当为1时,选择12小时模式,此时BIT5为AM/PM位,在24小时模式时此位为小时数据位。

控制寄存器(8Fh、8Eh)的BIT7是写保护位(WP),其它7位均为0。在任何对时钟或RAM读写操作之前,WP位必须为0。当WP位为1时,不能对任何时钟日历寄存器或RAM进行写操作。

    

 31个字节静态RAM寄存器如图所示

 

 突发模式配置寄存器如图所示

  四、DS1302通信时序

DS1302读写数据时序,图8为读一字节时序,图9为写一字节时序,数据的传输是从最低位开始(BIT0)。数据是以位(BIT)为单位依次写入或读出,读写数据操作中SCLK上升沿时执行写入数据,下降沿时执行读出数据。

 读数据:CE端从低到高的一个上升沿开始允许开始读数据,拉低CE端则禁止读写数据;开始的8个SCLK周期,写命令字节,数据的后8个SCLK 周期读出数据。

 

 写数据:CE端从低到高的一个上升沿开始允许开始写数据,拉低CE端则禁止读写数据;开始的8个SCLK周期,写命令字节,数据的后8个SCLK 周期写入数据。

 五、BCD码的转换

在DS1302中有关于时钟日历的寄存器数据存储格式为BCD码

BCD码介绍:

我们时钟日历寄存器使用的是8421码型的BCD码,BCD码还有5421码、2421码等,其中8421码型的BCD码最最常用;

BCD码是用四位二进制数表示一位十进制数的0-9这十个数简称BCD码;

      8421

8421码型BCD码最小值为0000(二进制),最大值为1001(二进制);9

一个字节的8421码型BCD码中的低四位用于表示十进制的个位,高四位用于表示十进制的十位,如10(十进制)的8421码型BCD码=0001 0000;

BCD码用程序转换实例:

例:把十进制数45转换为8421型BCD码

unsigned char data1, data2 = 45;  //声明2个无符号char型变量data1data2并且data2赋初值45

data1 = data2/10;  data2 = data2%10;  data2 = data2 + data1*16;  //data2最终等于69这个数

把69这个8421型BCD码换算回十进制数:

data1 = data2/16;  data2 = data2%16;  data2 = data2 + data1*10;  //data2最终等于45

 六、程序设计流程

写DS1302一字节数据
读DS1302一字节数据
BCD码转换
关闭写保护
设置DS1302时钟日历寄存器(初始显示时间)
设置写保护
关闭写保护
读取DS1302时钟日历
设置写保护
用数码管显示DS1302  时.分.秒

 

#include <reg52.h>
#include <intrins.h>
#define MAIN_Fosc		11059200UL	//宏定义主时钟HZ
/*====================================
 自定义类型名
====================================*/
typedef unsigned char INT8U;
typedef unsigned char uchar;

typedef unsigned int INT16U;
typedef unsigned int uint;

/*====================================
 硬件接口位声明
====================================*/
sbit TSCLK = P1^0;//时钟线 接到P10上用杜邦线
sbit TIO   = P1^1;//数据线,接到P11上
sbit TRST  = P1^2;//使能端,接到P12上
sbit DU  = P2^6;   //数码管段选
sbit WE  = P2^7;   //数码管位选
/*====================================
共阴极数码管段选码
====================================*/
uchar code table[]={ 
//0		1	 2     3     4     5     6     7     8
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
//9     A     B	   C	 D	   E	 F		-	 .	  关显示
0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x40, 0x80, 0x00
                   };

/*====================================
数码管位选码
====================================*/
				  //第1位	2位	  3位	 4位   5位	6位	  7位	8位
uchar code T_COM[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};//数码管位码

/*====================================
函数:void Delay_Ms(INT16U ms)
参数:ms,毫秒延时形参
描述:12T 51单片机自适应主时钟毫秒级延时函数
====================================*/
void Delay_Ms(INT16U ms)
{
     INT16U i;
	 do{
	      i = MAIN_Fosc / 96000; 
		  while(--i);   //96T per loop
     }while(--ms);
}

void Display(uchar Hour, Min, Sec)
{		
//------------------------------
	DU = 0;							
	P0 = table[Hour/10];		
	DU = 1;						
	DU = 0;							

	WE = 0;						
	P0 = T_COM[0];				   
	WE = 1;						
	WE = 0;						
	Delay_Ms(3);
//-------------------------------
	DU = 0;
	P0 = table[Hour%10]|0x80; 
	DU = 1;
	DU = 0;

	WE = 0;
	P0 = T_COM[1];			  
	WE = 1;
	WE = 0;
	Delay_Ms(3);
//------------------------------
	DU = 0;							
	P0 = table[Min/10];		
	DU = 1;						
	DU = 0;							

	WE = 0;						
	P0 = T_COM[2];				   
	WE = 1;						
	WE = 0;						
	Delay_Ms(3);
//-------------------------------
	DU = 0;
	P0 = table[Min%10]|0x80; 
	DU = 1;
	DU = 0;

	WE = 0;
	P0 = T_COM[3];			 
	WE = 1;
	WE = 0;
	Delay_Ms(3);
//------------------------------
	DU = 0;							
	P0 = table[Sec/10];		
	DU = 1;						
	DU = 0;							

	WE = 0;						
	P0 = T_COM[4];				   
	WE = 1;						
	WE = 0;						
	Delay_Ms(3);
//-------------------------------
	DU = 0;
	P0 = table[Sec%10]; 
	DU = 1;
	DU = 0;

	WE = 0;
	P0 = T_COM[5];			  
	WE = 1;
	WE = 0;
	Delay_Ms(3);

}

//写DS1302数据
void Write_DS1302_DAT(uchar cmd, uchar dat)
{
	uchar i;
	TRST = 0; //拉低使能端
	TSCLK = 0;//拉低数据总线
	TRST = 1; //拉高使能端,产生上升沿开始写数据
	for(i = 0; i < 8; i++)//每次写1位,写8次
	{
		TSCLK = 0;		  //拉低时钟总线
		TIO = cmd & 0x01; //写1位数据,从最低位开始写
		TSCLK = 1;		  //拉高时钟总线,产生上升沿数据被DS1302读走
		cmd >>=1;		  //右移一位
	}
	for(i = 0; i < 8; i++)//每次写1位,写8次
	{
		TSCLK = 0;		  //拉低时钟总线
		TIO = dat & 0x01; //写1位数据,从最低位开始写
		TSCLK = 1;		  //拉高时钟总线,产生上升沿数据被DS1302读走
		dat >>= 1;		  //右移一位
	}
}
//读DS1302数据
uchar Read_DS1302_DAT(uchar cmd)
{
	uchar i, dat;
	TRST = 0;  //拉低使能端
	TSCLK = 0; //拉低数据总线
	TRST = 1;  //拉高使能端,产生上升沿开始写数据
	for(i = 0; i < 8; i++)//每次写1位,写8次
	{
		TSCLK = 0;		 //拉低时钟总线
		TIO = cmd & 0x01;//写1位数据,从最低位开始写
		TSCLK = 1;		 //拉高时钟总线,产生上升沿数据被DS1302读走
		cmd >>=1;		 //右移一位
	}
	for(i = 0; i < 8; i++)//每次读1位,读8次
	{
		TSCLK = 0;		  //拉低时钟总线,产生下降沿,DS1302把数据放到TIO上
		dat >>= 1;		  //右移一位
		if(TIO)	dat |= 0x80;//读取数据,从最低位开始
		TSCLK = 1;			//拉高时钟总线,以备下一次产生下降沿
	}
	return dat;	//返回读出数据
}

//数据转BCD码
uchar Dat_Chg_BCD(uchar dat)
{
	uchar dat1, dat2;
	dat1 = dat / 10;
	dat2 = dat % 10;
	dat2 = dat2 + dat1 * 16;
	return dat2;
}

//BCD码转换为数据
uchar BCD_Chg_Dat(uchar dat)
{
	uchar dat1, dat2;
	dat1 = dat / 16;
	dat2 = dat % 16;
	dat2 = dat2 + dat1 * 10;
	return dat2;
}

void main()
{
	uchar i;
	uchar Sec, Min, Hour;
	Write_DS1302_DAT(0x8e, 0);//清除写保护
	Write_DS1302_DAT(0x80, Dat_Chg_BCD(30));//30秒(并且进行BCD码转换)
	Write_DS1302_DAT(0x82, Dat_Chg_BCD(15));//15分
	Write_DS1302_DAT(0x84, Dat_Chg_BCD(19));//19时
	Write_DS1302_DAT(0x8e, 0x80);//开写保护
	while(1)
	{
		Write_DS1302_DAT(0x8e, 0); //清除写保护
		Sec = BCD_Chg_Dat(Read_DS1302_DAT(0x81));//读秒寄存器(并且进行BCD码转换)
		Min	= BCD_Chg_Dat(Read_DS1302_DAT(0x83));//读分寄存器
		Hour = BCD_Chg_Dat(Read_DS1302_DAT(0x85));//读时寄存器
		Write_DS1302_DAT(0x8e, 0x80);//开写保护
		for(i = 0; i < 50; i++)	//循环显示时钟
			Display(Hour, Min, Sec);

	}
}

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

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

相关文章

中文版开源Llama 2同时有了语言、多模态大模型,完全可商用

可以说&#xff0c;AI 初创公司 LinkSoul.Al 的这些开源项目让海外开源大模型在国内的普及和推广速度与国际几乎保持了一致。 7 月 19 日&#xff0c;Meta 终于发布了免费可商用版本 Llama 2&#xff0c;让开源大模型领域的格局发生了巨大变化。 Llama 2 模型系列包含 70 亿、…

04-4_Qt 5.9 C++开发指南_时间日期与定时器

文章目录 1. 时间日期相关的类2. 源码2.1 可视化UI设计2.2 dialog.h2.3 dialog.cpp 1. 时间日期相关的类 时间日期是经常遇到的数据类型&#xff0c;Qt 中时间日期类型的类如下。 QTime:时间数据类型&#xff0c;仅表示时间&#xff0c;如 15:23:13。 QDate:日期数据类型&…

【工具使用】STM32CubeMX-基础定时器配置

一、概述 无论是新手还是大佬&#xff0c;基于STM32单片机的开发&#xff0c;使用STM32CubeMX都是可以极大提升开发效率的&#xff0c;并且其界面化的开发&#xff0c;也大大降低了新手对STM32单片机的开发门槛。     本文主要讲述STM32芯片的定时器的配置及其相关知识。 …

小白到运维工程师自学之路 第六十七集(Harbor企业镜像仓库部署)

一、概述 Harbor 是 VMware 公司开源的企业级 Docker Registry 项目&#xff0c;其目标是帮助用户迅速搭建一个企业级的 Docker Registry 仓库服务。它以Docker公司开源的Registry为基础&#xff0c;提供了管理 UI。基于角色的访问控制(Role Based AccessControl)、AD/LDAP集成…

微信开店小程序怎么做

微信开店小程序是一种在微信平台上运行的在线商店应用&#xff0c;它提供了丰富的功能和便捷的购物体验。下面将介绍微信开店小程序的功能以及带来的好处&#xff1a; 1. 商品展示与销售&#xff1a;微信开店小程序可以展示企业的商品信息&#xff0c;包括图片、价格、详细描述…

安装Win10操作系统时找不到任何驱动器的解决方法

安装Win10操作系统时找不到任何驱动器的解决方法 有时候在一台新电脑上使用U盘安装系统时提示&#xff1a;我们找不到任何驱动器。 如下图所示&#xff1a; 解决方法&#xff1a; 一、按F12&#xff08;不同电脑进入Bios的按键可能不同&#xff09;将电脑进入Bios画面&#x…

软件测试面试,这些坑你别踩,我已经替你踩过了

看看我写的软件测试面试时候的这些坑&#xff0c;你一定不能踩&#xff01;&#xff01;&#xff01; 第一个坑--测试用例编写没有思路&#xff0c;想起一条写一条。 分析&#xff1a; 该题目一般检查候选人编写测试用例的思路、覆盖度、深度。如果想起一条写一条&#xff0…

Linux基础与应用开发系列四:ARM-GCC与交叉编译

三个问题: ARM-GCC是什么?它与GCC有什么关系? 编译工具链和目标程序运行相同的架构平台&#xff0c;就叫本地编译 编译工具链和目标程序运行在不同的架构平台&#xff0c;叫做交叉编译 ARM-GCC是针对arm平台的一款编译器&#xff0c;它是GCC编译工具链的一个分支 虚拟机…

比亚迪与 Stingray达成合作,交互式车载KTV亮相,汽车也能卡拉OK

比亚迪公司与音乐媒体科技公司Stingray达成合作&#xff0c;计划从2023年开始&#xff0c;在全球多个市场推出车载KTV产品&#xff0c;成为新能源汽车的亮点。 根据比亚迪官方公众号发布的消息&#xff0c;比亚迪正在合作开发一款全新的娱乐系统。该系统计划支持多语言&#xf…

ESPFriends之ESP32模型部署训练历险记(一)

开发环境的部署搭建 超级小星星&#xff1a;时间过得可真快ESPFriends创客沙龙已经在武汉举办了两期&#xff0c;在这里有行业内的工程师、高校的学生以及极客&#xff0c;在这里我们交流分享自己的开发心得&#xff0c;提出遇到的“大坑”也可以得到小伙伴们的解决方案&#x…

SAP 请求合并

SAP 请求合并 由于公司请求管理要求比较高&#xff0c;经常需要将很多请求合并在一起传输&#xff0c;实际SAP是支持这个功能的&#xff0c;不仅可以将开发类的请求合并&#xff0c;还可以将开发和定制的合并在一起传输 1、合并请求 SE09 实用程序-重组-合并请求 看提示写的…

Qt--QPlugin插件

写在前面 Qt–动态链接库一文中提到&#xff0c;动态方式加载dll只能加载 extern "C“ 的导出函数&#xff0c;而无法加载类&#xff0c;因此可以使用Qt提供的插件来实现导出类的动态加载。 QPlugin是Qt插件框架的一部分&#xff0c;是一种轻量级的插件系统&#xff0c;…

K8S系列文章之 自动化运维利器 Ansible

Ansible-安装 第一步&#xff1a;安装我们的epel扩展源 yum -y install epel-release 我这里会报/var/run/yum.pid 已被锁定&#xff0c;如果没有直接进行下一步 [rootmaster home]# yum -y install epel-release 已加载插件&#xff1a;fastestmirror, langpacks /var/run/…

Bean的Aware接口

Aware 简介 Spring中提供了一些以Aware结尾的接口&#xff0c;实现了Aware接口的bean在被初始化之后&#xff0c;可以获取相应资源。比如BeanNameAware之类的以Aware结尾的接口&#xff0c;这个接口获取的资源就是以BeanName相关的。 通过Aware接口&#xff0c;可以对Spring相…

以产品经理的角度去讲解原型图---会议OA项目

目录 一.前言 二.原型图 2.1 原型图是什么 3.1 原型图的作用 三.演示讲解 3.1 项目背景 3.2 项目介绍 3.2.1 会议管理&#xff08;会议的发起&#xff0c;通知&#xff09; 3.2.2 投票管理&#xff08;会议的流程重大决策记录&#xff09; 3.2.3 会议室管理 3.2.4 系统管…

SDXL-Stable Diffusion改进版

文章目录 1. 摘要2. 算法&#xff1a;2.1 结构&#xff1a;2.2 微小的条件机制2.3 多宽高比训练2.4 改进自编码器2.5 所有组合放到一起2.6 主流方案比较 3. 未来工作4. 限制 论文&#xff1a; 《SDXL: Improving Latent Diffusion Models for High-Resolution Image Synthesis…

HCL MPLS L2VPN BGP lsp

目录 1 拓扑 2 配置步骤 2.1 配置接口IP 和路由协议 2.2 配置MPLS LDP 2.3 配置L2VPN PW(BGP) 2.4 验证L2VPN 使用EVE-NG 中 的H3C 镜像&#xff0c;配置bgp 后&#xff0c;OSPF 会失效&#xff0c;可能镜像有问题&#xff0c;使用HCL没有问题。 1 拓扑 2 配置步骤 2.1…

【Axure动态面板】利用动态面板实现树形菜单的制作

利用动态面板&#xff0c;简单制作高保真的树形菜单。 一、先看效果 https://1poppu.axshare.com 二、实现思路 1、菜单无非就是收缩和展开&#xff0c;动态面板有个非常好的属性&#xff1a;fit to content&#xff0c;这个属性的含义是&#xff1a;面板的大小可以根据内容多少…

vue3-ts-vite:vue 项目 配置 多页面应用

一、Vue项目&#xff0c;什么是多页面应用 Vue是一种单页面应用程序&#xff08;SPA&#xff09;框架&#xff0c;这意味着Vue应用程序通常只有一个HTML页面&#xff0c;而在该页面上进行动态的内容更改&#xff0c;而不是每次都加载新的HTML页面。 但是&#xff0c;有时候我…

C++动态内存管理 - new和delete

目录 开胃菜 - 浅析C/C的内存分段 内存分段 各段说明 new和delete的基础用法 深度剖析new 定位new 浅析delete malloc/free和new/delete的异同 开胃菜 - 浅析C/C的内存分段 这部分是计算机系统相关的知识&#xff0c;这里只是先浅谈一下&#xff0c;可能有些内容会有冲…