物联网实战--驱动篇之(七)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.hqwc.cn/news/611230.html

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

相关文章

转行项目经理,考软考还是PMP?

这两者择其一&#xff0c;或者有条件的两个都可以考虑一下&#xff0c;因为国内对这两个证书的需求都很大。 从企业环境来看 PMP适用于各行各业&#xff0c;在外企更受欢迎。 软考适用于计算机领域&#xff0c;而且在国企和政府部门比较受欢迎。 因此&#xff0c;可以综合考…

Github 2024-04-12 Java开源项目日报Top9

根据Github Trendings的统计,今日(2024-04-12统计)共有9个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Java项目9TypeScript项目3强大易用的开源建站工具 创建周期:2214 天开发语言:Java, TypeScript协议类型:GNU General Public License v3.0Sta…

集群开发学习(一)(安装GO和MySQL,K8S基础概念)

完成gin小任务 参考文档&#xff1a; https://www.kancloud.cn/jiajunxi/ginweb100/1801414 https://github.com/hanjialeOK/going 最终代码地址&#xff1a;https://github.com/qinliangql/gin_mini_test.git 学习 1.安装go wget https://dl.google.com/go/go1.20.2.linu…

第6章 6.3.1 正则表达式的语法(MATLAB入门课程)

讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 正则表达式可以由一般的字符、转义字符、元字符、限定符等元素组…

李廉洋;4.11#黄金,WTI原油#行情走势分析策略。

美国银行预计&#xff0c;在今天召开的欧洲央行会议上不会有重大的政策变化&#xff0c;但欧洲央行正逐渐接近开始降息&#xff0c;尽管它采取的是一种谨慎的、依赖数据的方式。虽然欧洲央行对降息轨迹的信心不断增强&#xff0c;但降息的具体速度和幅度仍未公布&#xff0c;而…

Sorting Algorithms in Python (排序算法)

本篇文章主要介绍几种经典排序算法&#xff1a;冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序、归并排序、桶排序和基数排序。并给出用python实现的算法代码。 目录 一、冒泡排序 二、快速排序 三、选择排序 四、堆排序 五、插入排序 六、希尔排序 七、归…

255Mesh 无线lora模块详细配置和测试

一、型号介绍 字符含义&#xff1a; E&#xff1a;终端 N&#xff1a;节点&#xff08;node&#xff09; G&#xff1a;网关 &#xff08;gateway&#xff09; 官网淘宝介绍 注意&#xff1a;组网必须配网关。 二、功能配置 软件界面 1.网络参数 网络参数包括网络 ID&a…

基于SSM“口腔助手”小程序

采用技术 基于SSM“口腔助手”小程序的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringMVCMyBatis 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 页面展示效果 小程序前台首页 注册 保健知识 我的 医生登录成功 后台管理员 …

Docker镜像,什么是Docker镜像,Docker基本常用命令

docker镜像 1.1什么是镜像&#xff0c;镜像基础 1.1.1 镜像的简介 镜像是一种轻量级&#xff0c;可执行的独立软件包&#xff0c;也可以说是一个精简的操作系统。镜像中包含应用软件及应用软件的运行环境&#xff0c;具体来说镜像包含运行某个软件所需的所有内容&#xff0c;…

从 SQLite 3.4.2 迁移到 3.5.0(二十)

返回&#xff1a;SQLite—系列文章目录 上一篇:SQLite---调试提示&#xff08;十九&#xff09; 下一篇&#xff1a;SQLite—系列文章目录 ​ SQLite 版本 3.5.0 &#xff08;2007-09-04&#xff09; 引入了一个新的操作系统接口层&#xff0c; 与所有先前版本的 SQLi…

机器学习——模型融合:Stacking算法

机器学习——模型融合&#xff1a;Stacking算法 在机器学习中&#xff0c;模型融合是一种常用的方法&#xff0c;它可以提高模型的泛化能力和预测性能。Stacking算法&#xff08;又称为堆叠泛化&#xff09;是一种强大的模型融合技术&#xff0c;它通过组合多个基本分类器的预…

一文破解Promise难题:Promise机制深入剖析与实例

Promise 是 JavaScript 中用于处理异步操作的一种重要机制。Promise 用于解决 JavaScript 中异步操作的复杂性&#xff0c;通过状态管理、链式调用、错误处理等功能&#xff0c;实现代码的清晰、有序与可维护&#xff0c;避免回调地狱&#xff0c;提升异步编程的效率与体验。 …