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

一、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.mfbz.cn/a/64162.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

React Dva项目 简单引入models中的所有JS文件

我们前面接触的 Dva项目 models目录下的文件还要一个一个引入 其实体验并不是很好 而且如果项目很大那就比较麻烦了 我们可以在 models 下创建一个 index.js 文件 编写代码如下 const context require.context("./", false, /\.js$/); export default context.key…

SNAP插件sen2Three去云操作

1.先把这篇文章看了 2.去官网下载Sen2Three 3.这时候可以大概看看Sen2Three的官方文档&#xff0c;我们知道了需要用anaconda2环境 4.我是已经安装有anaconda3,所以需要两个并存&#xff0c;此时可以参考这篇文章 5.这是ananconda2的链接&#xff0c;直接下载安装即可&#xff…

Delphi Professional Crack,IDE插件开发和扩展IDE

Delphi Professional Crack,IDE插件开发和扩展IDE 构建具有强大视觉设计功能的单源多平台本机应用程序。 Delphi帮助您使用Object Pascal为Windows、Mac、Mobile、IoT和Linux构建和更新数据丰富、超连接、可视化的应用程序。Delphi Professional适合个人开发人员和小型团队构建…

20230807在WIN10下使用python3将TXT文件转换为DOCX(在UTF8编码下转换为DOCX有多一行的瑕疵)

20230807在WIN10下使用python3将TXT文件转换为DOCX&#xff08;在UTF8编码下转换为DOCX有多一行的瑕疵&#xff09; 2023/8/7 12:58 https://translate.google.com/?slen&tlzh-CN&opdocs 缘起&#xff0c;由于google的文档翻译不支持SRT/TXT格式的字幕&#xff0c;因此…

Transformer学习笔记

Transformer学习笔记 前言前提条件相关介绍Transformer总体架构编码器&#xff08;Encoder&#xff09;位置编码&#xff08;Positional Encoding&#xff09;get_attn_pad_mask函数&#xff08;Padding Mask&#xff09;EncoderLayerMultiHeadAttentionScaledDotProductAttent…

webpack基础知识七:说说webpack proxy工作原理?为什么能解决跨域?

一、是什么 webpack proxy&#xff0c;即webpack提供的代理服务 基本行为就是接收客户端发送的请求后转发给其他服务器 其目的是为了便于开发者在开发模式下解决跨域问题&#xff08;浏览器安全策略限制&#xff09; 想要实现代理首先需要一个中间服务器&#xff0c;webpac…

Llama 2 云端部署与API调用【AWS SageMaker】

Meta 刚刚发布了 Llama 2 大模型。如果你和我们一样&#xff0c;你一定会迫不及待地想要亲自动手并用它来构建。 推荐&#xff1a;用 NSDT设计器 快速搭建可编程3D场景。 使用任何类型的 LLM 进行构建的第一步是将其托管在某处并通过 API 使用它。 然后你的开发人员可以轻松地将…

HTML5注册页面

分析 注册界面实际上是一个表格&#xff08;对齐&#xff09;&#xff0c;一行有两个单元格。 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevic…

致远OA协同管理软件无需登录getshell

一个男子汉&#xff0c;老守在咱村那个土圪崂里&#xff0c;又有什么意思&#xff1f;人就得闯世事&#xff01;安安稳稳活一辈子&#xff0c;还不如痛痛快快甩打几下就死了&#xff01;即使受点磨难&#xff0c;只要能多经一些世事&#xff0c;死了也不后悔&#xff01; 漏洞…

NodeJS原型链污染ctfshow_nodejs

文章目录 NodeJS原型链污染&ctfshow_nodejs前言0x01.原型与原型链0x02.prototype和__proto__分别是什么&#xff1f;0x03.原型链继承不同对象的原型链* 0x04.原型链污染原理0x05.merge()导致原型链污染0x06.ejs模板引擎RCEejs模板引擎另一处rce 0x07.jade模板引擎RCE【ctfs…

使用RecyclerView构建灵活的列表界面

使用RecyclerView构建灵活的列表界面 1. 引言 在现代移动应用中&#xff0c;列表界面是最常见的用户界面之一&#xff0c;它能够展示大量的数据&#xff0c;让用户可以浏览和操作。无论是社交媒体的动态流、商品展示、新闻列表还是任务清单&#xff0c;列表界面都扮演着不可或…

Vue2 第二十节 vue-router (四)

1.全局前置路由和后置路由 2.独享路由守卫 3.组件内路由守卫 4.路由器的两种工作模式 路由 作用&#xff1a;对路由进行权限控制 分类&#xff1a;全局守卫&#xff0c;独享守卫&#xff0c;组件内守卫 一.全局前置路由和后置路由 ① 前置路由守卫&#xff1a;每次路由…

开箱报告,Simulink Toolbox库模块使用指南(二)——MATLAB Fuction模块

文章目录 前言 MATLAB Fuction模块 采样点设置 FFT 求解 分析和应用 总结 前言 见《开箱报告&#xff0c;Simulink Toolbox库模块使用指南&#xff08;一&#xff09;——powergui模块》 MATLAB Fuction模块 MATLAB Fuction模块是在Simulink建模仿真或生成代码时&#x…

Vue中监听路由参数变化的几种方式

目录 一. 路由监听方式&#xff1a; 通过 watch 进行监听 1. 监听路由从哪儿来到哪儿去 2. 监听路由变化获取新老路由信息 3. 监听路由变化触发方法 4. 监听路由的 path 变化 5. 监听路由的 path 变化, 使用handler函数 6. 监听路由的 path 变化&#xff0c;触发method…

无锚框原理 TOOD:Task-aligned One-stage Object Detection

无锚框原理 TOOD&#xff1a;Task-aligned One-stage Object Detection 一 摘要二 引言TOOD设计 三 具体设计Task-aligned Head任务对齐的预测器 TAP预测对齐 TAL 任务对齐学习Task-aligned Sample Assignment多任务损失 一 摘要 一阶段目标检测通常通过优化两个子任务来实现&…

CSS中所有选择器详解

文章目录 一、教学视频二、基础选择器1.标签选择器2.类选择器3.id选择器4.通配符选择器 三、复合选择器1.交集选择器2.并集选择器 四、属性选择器1.[属性]2.[属性属性值]3.[属性^属性值]4.[属性$属性值]5.[属性*属性值] 五、关系选择器1.父亲>儿子2.祖先 后代3.兄弟4.兄~弟 …

Mermaid系列之FlowChart流程图

一.欢迎来到我的酒馆 介绍mermaid下&#xff0c;Flowchat流程图语法。 目录 一.欢迎来到我的酒馆二.什么是mermiad工具三.在vs code中使用mermaid四.基本语法 二.什么是mermiad工具 2.1 mermaid可以让你使用代码来创建图表和可视化效果。mermaid是一款基于javascript语言的图表…

Vue2 第二十一节 Vue UI组件库

移动端常用UI组件 1. Vant https://youzan.github.io/vant 2. Cube UI https://didi.github.io/cube-ui 3. Mint UI http://mint-ui.github.io PC端常用UI组件 1. Element UI https://element.eleme.cn 2. IView UI https://www.iviewui.com 一. Element UI 的引入和使…

我国洪涝灾害分布图

声明&#xff1a;来源网络&#xff0c;仅供学习&#xff01;

Apache Paimon 学习笔记

本博客对应于 B 站尚硅谷教学视频 尚硅谷大数据Apache Paimon教程&#xff08;流式数据湖平台&#xff09;&#xff0c;为视频对应笔记的相关整理。 1 概述 1.1 简介 Flink 社区希望能够将 Flink 的 Streaming 实时计算能力和 Lakehouse 新架构优势进一步结合&#xff0c;推…
最新文章