物联网实战--驱动篇之(七)RTC时钟(DS1302)

目录

一、RTC简介

二、DS1302介绍

三、初始化

四、字节读写

五、功能函数


一、RTC简介

        实时时钟,简称RTC,这个在STM32的外设里也有,不过STM32F1系列的RTC实际上只有一个计数器功能,如果需要年月日要自己写软件计算 ,比较麻烦,这时候就可以使用带有年月日的RTC芯片了,常用的有DS1302,可以自己计算闰年,具体资料可以看这里。DS1302Z_(JSMSEMI(杰盛微))DS1302Z中文资料_价格_PDF手册-立创电子商城

二、DS1302介绍

        主要是看下DS1302的通讯方式和寄存器,它的通讯方式有点类似于IIC,也是时钟线+数据线,不过还多了个复位(片选)线,时序也是不一样的,没有IIC那么多信号。寄存器看下图:

        其中年份是00~99,也就是2000~2099年了,数据格式是BCD码。

        下面先从头文件开始:

        主要定义了时间结构体、引脚结构体和IO相关函数,寄存器的地址根据手册定义。

三、初始化

        首先初始化时钟、数据和复位3个引脚,其中数据脚有时候需要作为输入,具体代码如下:


/*		 
================================================================================
描述 : 硬件初始化
输入 : 
输出 :  
================================================================================
*/
void drv_ds1302_init(GPIO_TypeDef* port_clk, uint32_t pin_clk,GPIO_TypeDef* port_io, uint32_t pin_io,GPIO_TypeDef* port_rst, uint32_t pin_rst,Ds1302RtcStruct *rtc_initpara)
{g_sDs1302Drv.port_clk=port_clk;g_sDs1302Drv.pin_clk=pin_clk;g_sDs1302Drv.port_io=port_io;g_sDs1302Drv.pin_io=pin_io;g_sDs1302Drv.port_rst=port_rst;g_sDs1302Drv.pin_rst=pin_rst; GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = pin_clk;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(port_clk, &GPIO_InitStruct);	GPIO_InitStruct.GPIO_Pin = pin_io;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(port_io, &GPIO_InitStruct);	GPIO_InitStruct.GPIO_Pin = pin_rst;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(port_rst, &GPIO_InitStruct);	DS1302_RST_0; 	DS1302_CLK_0;delay_us(5);drv_ds1302_set_wp(false);drv_ds1302_write(0x90, 0xA7);//充电寄存器drv_ds1302_set_wp(true);drv_ds1302_set_hour_format(true);//24h制if(drv_ds1302_read(0x81)&0x80)//查询DS1302时钟是否启动,如果时钟停止走动:启动时钟+初始化时钟{		printf("DS1302 stop!\n");drv_ds1302_set_time(rtc_initpara);drv_ds1302_start();}}/*		 
================================================================================
描述 : 数据脚读写转换
输入 : 
输出 :  
================================================================================
*/
void drv_ds1302_set_io_mode(bool is_out)
{if(is_out){GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = g_sDs1302Drv.pin_io;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(g_sDs1302Drv.port_io, &GPIO_InitStruct);			}else{GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = g_sDs1302Drv.pin_io;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(g_sDs1302Drv.port_io, &GPIO_InitStruct);}
}

        如果时钟没断电过就不用再次启动了。

四、字节读写

        下面是最基本的字节读写函数,时序具体参考手册。


/*		 
================================================================================
描述 : 写字节
输入 : 
输出 :  
================================================================================
*/
void drv_ds1302_write(u8 reg_addr, u8 reg_data)
{DS1302_RST_0;DS1302_CLK_0;delay_us(2);DS1302_RST_1;delay_us(5);for(u8 i=0; i<8; i++){if(reg_addr&0x01)DS1302_IO_1;else DS1302_IO_0;DS1302_CLK_1;delay_us(5);DS1302_CLK_0;reg_addr=reg_addr>>1;}for(u8 i=0; i<8; i++){if(reg_data&0x01)DS1302_IO_1;else DS1302_IO_0;DS1302_CLK_1;delay_us(5);DS1302_CLK_0;reg_data=reg_data>>1;}	DS1302_RST_0;delay_us(5);
}/*		 
================================================================================
描述 : 读字节
输入 : 
输出 :  
================================================================================
*/
u8 drv_ds1302_read(u8 reg_addr)
{DS1302_RST_1;delay_us(5);for(u8 i=0; i<8; i++){if(reg_addr&0x01)DS1302_IO_1;else DS1302_IO_0;DS1302_CLK_1;delay_us(5);DS1302_CLK_0;reg_addr=reg_addr>>1;}drv_ds1302_set_io_mode(0);u8 value=0;for(u8 i=0; i<8; i++){value=value>>1;if(DS1302_IO_READ()>0)value|=0x80; DS1302_CLK_1;delay_us(5);DS1302_CLK_0;}	drv_ds1302_set_io_mode(1);DS1302_RST_0;	delay_us(5);return value;	
}

        每次读写复位脚都要拉高才能进行,数据是低位先传输。

五、功能函数

        有了基本的读写函数后,就可以根据寄存器地址进行功能设置了。比如下面的启动和停止:

/*		 
================================================================================
描述 : 停止
输入 : 
输出 :  
================================================================================
*/
void drv_ds1302_stop(void)
{drv_ds1302_set_wp(false);u8 ret=drv_ds1302_read(0x81);ret=ret|0x80;drv_ds1302_write(0x80,ret);drv_ds1302_set_wp(true);
}/*		 
================================================================================
描述 : 启动
输入 : 
输出 :  
================================================================================
*/
void drv_ds1302_start(void)
{drv_ds1302_set_wp(false);u8 ret=drv_ds1302_read(0x81);ret=ret&0x7F;drv_ds1302_write(0x80,ret);drv_ds1302_set_wp(true);
}

时间格式设置:

/*		 
================================================================================
描述 : 设置时间格式
输入 : 
输出 :  
================================================================================
*/
void drv_ds1302_set_hour_format(bool is_24h)
{drv_ds1302_set_wp(false);if(is_24h){u8 ret=drv_ds1302_read(0x85);ret=ret&0x7F;drv_ds1302_write(0x84,ret);		printf("ds1302 set 24h\n");}else{u8 ret=drv_ds1302_read(0x85);ret=ret|0x80;drv_ds1302_write(0x84,ret);		printf("ds1302 set 12h\n");}drv_ds1302_set_wp(true);
}

时间设置:

/*		 
================================================================================
描述 : 时间设置
输入 : 
输出 :  
================================================================================
*/
void drv_ds1302_set_time(Ds1302RtcStruct *rtc_initpara)
{if(rtc_initpara==NULL)return;printf("drv_ds1302_set_time=20%02x-%02x-%02x  %02x:%02x:%02x\n", rtc_initpara->rtc_year, rtc_initpara->rtc_month, rtc_initpara->rtc_date,rtc_initpara->rtc_hour, rtc_initpara->rtc_minute, rtc_initpara->rtc_second	);drv_ds1302_set_wp(false);drv_ds1302_write(DS1302_SEC_ADDR,rtc_initpara->rtc_second);drv_ds1302_write(DS1302_MIN_ADDR,rtc_initpara->rtc_minute);drv_ds1302_write(DS1302_HOUR_ADDR,rtc_initpara->rtc_hour);drv_ds1302_write(DS1302_DATE_ADDR,rtc_initpara->rtc_date);drv_ds1302_write(DS1302_MONTH_ADDR,rtc_initpara->rtc_month);drv_ds1302_write(DS1302_YEAR_ADDR,rtc_initpara->rtc_year);drv_ds1302_set_wp(true);
}

时间读取:


/*		 
================================================================================
描述 : 时间读取
输入 : 
输出 :  
================================================================================
*/
void drv_ds1302_get_time(Ds1302RtcStruct *rtc_initpara)
{if(rtc_initpara==NULL)return;rtc_initpara->rtc_second=drv_ds1302_read(0x81);rtc_initpara->rtc_minute=drv_ds1302_read(0x83);rtc_initpara->rtc_hour=drv_ds1302_read(0x85);rtc_initpara->rtc_date=drv_ds1302_read(0x87);rtc_initpara->rtc_month=drv_ds1302_read(0x89);rtc_initpara->rtc_year=drv_ds1302_read(0x8D);
//	printf("drv_ds1302_get_time=20%02x-%02x-%02x  %02x:%02x:%02x\n", rtc_initpara->rtc_year, rtc_initpara->rtc_month, rtc_initpara->rtc_date,
//																																rtc_initpara->rtc_hour, rtc_initpara->rtc_minute, rtc_initpara->rtc_second	);	
}

设置类的都要先解锁写保护才能进行相应操作。

整体来讲,DS1302用起来不复杂,时序有搞清楚,寄存器弄对来就没问题了。

代码链接:https://download.csdn.net/download/ypp240124016/89117651

本项目的交流QQ群:701889554

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

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

相关文章

数字IC/FPGA(时钟简介)

本文主要介绍以下几点&#xff1a; 什么是时钟什么是外部时钟和内部时钟时钟偏斜skew、时钟延迟delay和时钟抖动jitter的定义、三者的区别时钟抖动、时钟偏斜、时钟延迟会引起或不会引起什么情况布线方式的影响&#xff0c;正偏差和负偏差的好处和坏处什么是同步电路什么是异步…

二叉树经典OJ题(2)

一、根据二叉树创建字符串 . - 力扣&#xff08;LeetCode&#xff09; class Solution { public://前序遍历&#xff1a;根 左 右//左子树为空&#xff0c;右子树不为空的时候&#xff0c;不能省略左//左不为空&#xff0c;右子树为空的时候&#xff0c;可以省略右//都为空&am…

【springCloud】版本学习

Spring Cloud介绍 官网地址&#xff1a;https://spring.io/projects/spring-cloud Spring Cloud 是一个基于 Spring Boot 的微服务架构解决方案&#xff0c;它提供了一系列工具和模式来帮助开发者构建分布式系统。Spring Cloud 的组件和模式包括配置管理、服务发现、断路器、…

【Linux】tcpdump P3 - 过滤和组织返回信息

文章目录 基于TCP标志的过滤器格式化 -X/-A额外的详细选项按协议(udp/tcp)过滤低详细输出 -q时间戳选项 本文继续展示帮助你过滤和组织tcpdump返回信息的功能。 基于TCP标志的过滤器 可以根据各种TCP标志来过滤TCP流量。这里是一个基于tcp-ack标志进行过滤的例子。 # tcpdump…

vue源码解析——diff算法/双端比对/patchFlag/最长递增子序列

虚拟dom——virtual dom&#xff0c;提供一种简单js对象去代替复杂的 dom 对象&#xff0c;从而优化 dom 操作。virtual dom 是“解决过多的操作 dom 影响性能”的一种解决方案。virtual dom 很多时候都不是最优的操作&#xff0c;但它具有普适性&#xff0c;在效率、可维护性之…

《由浅入深学习SAP财务》:第2章 总账模块 - 2.7 总账模块报表 -2.7.2 对外报表:现金流量表

2.7.2 对外报表&#xff1a;现金流量表 现金流量表包括直接法和间接法。使用SAP出具现金流量表&#xff0c;一般只能出具直接法报表。间接法是指按照净利润倒推出现金流量的发生额&#xff0c;由于其中存在人为“分析”的因素&#xff0c;很难直接通过科目的加加减减得出所需要…

Fiddler工具的操作和功能时-----定位到步骤图(助力抓包)

前言&#xff1a; 继续上一篇&#xff0c;已经对fiddler的安装、配置和代理的问题进行了讲解&#xff1a; Fiddle配置代理&#xff0c;保手机模拟器访问外部网络-CSDN博客 本章&#xff0c;讲对一些fiddler的操作进行一系列讲解&#xff01;Fiddler作为一款网络调试工具&…

Java复习第十七天学习笔记(转发、重定向,GET,POST),附有道云笔记链接

【有道云笔记】十七 4.3 转发、重定向、Get、POST、乱码 https://note.youdao.com/s/GD5TRksQ 一、转发 转发&#xff1a;一般查询了数据之后&#xff0c;转发到一个jsp页面进行展示 req.setAttribute("list", list); req.getRequestDispatcher("student_lis…

浅谈函数 fscanf/sscanf 和 fprintf/sprintf

目录 一&#xff0c;fprintf 的介绍和使用1. 函数介绍2. 函数使用 二&#xff0c;fscanf 的介绍和使用1. 函数介绍2. 函数使用 三&#xff0c;sprintf 的介绍和使用1. 函数介绍2. 函数使用 四&#xff0c;sscanf 的介绍和使用1&#xff0c;函数介绍2&#xff0c;函数使用 五&am…

关于MCU产品开发参数存储的几种方案

关于MCU产品开发参数存储的几种方案 Chapter1 关于MCU产品开发参数存储的几种方案Chapter2 单片机参数处理[保存与读取]Chapter3 嵌入式设备参数存储技巧Chapter4 STM32硬件I2C的一点心得(AT24C32C和AT24C64C) Chapter1 关于MCU产品开发参数存储的几种方案 原文链接 在工作中…

【系统分析师】计算机网络

文章目录 1、TCP/IP协议族1.1 DHCP协议1.2 DNS协议1.3网络故障诊断 2、网路规划与设计2.1逻辑网络设计2.2物理网络设计2.3 分层设计 3、网络接入3.1 接入方式3.2 IPv6地址 4、综合布线技术5、物联网5.1物联网概念与分层5.2 物联网关键技术 6、云计算7、网络存储技术&#xff08…

C语言中局部变量和全局变量是否可以重名?为什么?

可以重名 在C语言中, 局部变量指的是定义在函数内的变量, 全局变量指的是定义在函数外的变量 他们在程序中的使用方法是不同的, 当重名时, 局部变量在其所在的作用域内具有更高的优先级, 会覆盖或者说隐藏同名的全局变量 具体来说: 局部变量的生命周期只在函数内部,如果出了…

AI来了,Spring还会远吗?(Spring AI初体验)

目录 一、创建项目二、first demo1、application.properties2、ChatController3、结果 三、个人思考 一、创建项目 官方文档的Getting Started 最低要求&#xff1a;JDK17 阿里云的Server URL&#xff08;https://start.aliyun.com/&#xff09;搜不到Spring AI&#xff0c;…

数据库:SQL分类之DQL详解

1.DQL语法 select 字段列表 from 表名列表 where 条件列表 group by 分组字段列表 having 分组后条件列表 order by 排序字段列表 limit 分页参数 基本查询 条件查询&#xff08;where&#xff09; 聚合函数&#xff08;count、max、min、avg、sum &#xff09; 分组查询&…

C语言100道练习题打卡(1)

1 有1&#xff0c;2&#xff0c;3&#xff0c;4四个数字&#xff0c;能组成多少个互不相同且不重复的三位数&#xff0c;都是多少 #include<stdio.h> //有1&#xff0c;2&#xff0c;3&#xff0c;4四个数字&#xff0c;能组成多少个互不相同且不重复的三位数&#xff…

分享一些有趣的 Linux 命令

1、sl 会显示一辆火车穿过你的终端屏幕 2、cmatrix 在终端中显示类似于《黑客帝国》电影中的绿色数字雨效果 3、fortune 显示一个随机的名人名言或者笑话 4、cowsay 让一头牛说出你输入的话 5、toilet 在终端中将输入的文本以艺术字体的形式呈现 6、figlet 类似于 toile…

ssm051网上医院预约挂号系统+jsp

网上医院预约挂号系统设计与实现 摘 要 如今的信息时代&#xff0c;对信息的共享性&#xff0c;信息的流通性有着较高要求&#xff0c;因此传统管理方式就不适合。为了让医院预约挂号信息的管理模式进行升级&#xff0c;也为了更好的维护医院预约挂号信息&#xff0c;网上医院…

Vue入门:天不生Vue,前端万古如长夜 - Vue从入门到放弃

目录 &#x1f44b; Vue环境搭建 1.安装node.js 2.配置环境变量 3.VSCode配置 4.安装Vue CLI 5.在VS Code中打开Vue项目 6.运行Vue项目 &#x1f440; Vue基础学习 1.引入vue.js 2.数据方法 3.生命周期&#xff01; 4.模板语法 5.对象语法 6.条件渲染 7.列表渲…

简历上写熟悉Linux下常用命令?直接寄

大家写简历技术栈时&#xff0c;都觉得越多越好&#xff0c;其中一条&#xff0c;熟悉Linux下常用命令&#xff1f;其实开发中Linux不是必备考点&#xff0c;除了运维&#xff0c;真正用的多的仅仅cd ls mkdir等&#xff0c;但当面试官问到上面命令时&#xff0c;是不是就傻眼了…

Java使用OpenOffice将office文件转换为PDF

Java使用OpenOffice将office文件转换为PDF 1. 先行工作1.1 OpenOffice官网下载1.2 JODConverter官网下载1.3 下载内容 2.介绍3. 安装OpenOffice服务3.1.Windows环境3.2 Linux环境 4. maven依赖5. 转换代码 1. 先行工作 请注意&#xff0c;无论是windows还是liunx环境都需要安装…