esp32 操作DS1307时钟芯片

电气参数摘要

  • 有VCC供电,IIC活动状态是1.5mA,待机状态200μA,电池电流5nA(MAX=50nA)
  • 无VCC供电的时候,电池电流,300nA(时钟运行),10nA(时钟停止)
  • 供电电压是4.5-5.5V,不支持3.3V
  • IIC频率最大400kHZ。
  • 因为ESP32不支持5V电压,但是DS1307必须用5V供电,因此在IIC上拉电阻的位置,必须上拉到3.3V。否则直接给ESP32的IO灌5V可能会烧掉。可以使用ESP32内部的IO上拉,然后去掉外部的上拉就行。

IIC的通信

  • 访问是通过实施启动条件,并提供设备识别代码,后跟寄存器地址而获得的。可以按顺序访问后续寄存器,直到执行停止条件为止。
  • 芯片iic地址是0x68
  • 配置寄存器,先发送设备地址,发送寄存器地址(比如0),然后发送寄存器的值。可以一次性发送多个字节,芯片会自动偏移寄存器地址。
  • 读取寄存器,先发送寄存器地址,然后读取。支持连续读取多个寄存器。

寄存器

  • RTC寄存器位于地址00h至07h的位置。
  • RAM寄存器位于地址08h至3Fh的位置。

在多字节访问期间,当地址指针达到3Fh,即RAM空间的末尾时,它会环绕到位置00h,即时钟空间的开头。
在这里插入图片描述

  • 在初次上电的时候(指初次装上纽扣电池),CH位是置1的,表示振荡器停止,计时功能处于停止状态。这时候纽扣电池的耗电量位10nA。
  • 所以在初次使用的时候,需要对CH位清零,一般这个清零操作会在设置当前时间到DS1307时同时完成。
  • 当CH位置0后,断开主电,RTC也会继续运行,这时候纽扣电池的耗电量典型值为300nA(无方波输出时)。

计算

  1. 芯片将“年月日时分秒周”存放到地址00-06这7个寄存器里面。每个寄存器相应bit对应的含义,看寄存器列表。
  2. 读取秒的寄存器是00h。先要读取出10倍数的秒(也就是十位数),对应BIT4~bit6.
    然后读取个位数的秒数,BIT0~BIT3.
    在这里插入图片描述
    比如读取到寄存器值为0x59,则对应二进制为00101 1001b。则bit4~bit6=5 ,BIT0~BIT3= 9最终为5*10+9=59秒。
    这个寄存器的CH位是时钟启停控制bit。
    3.比如读小时,小时在芯片里面有12小时表示法和24小时表示法。具体看BIT6。
    当bit6=1,则剩余的bit按照12小时制展开。
    当bit6=0,则剩余的bit按照24小时制展开。
    在这里插入图片描述

DS1307上的RAM

这个RAM是留给用户使用的存储空间,RTC不会用到这部分RAM

DS1307上的RAM(随机存储器)用于存储临时数据,用户自定义的设置以及其他需要在断电时保持的信息。以下是DS1307上RAM的主要用途:

存储用户数据: 用户可以将自定义数据存储在DS1307的RAM中。这可以包括配置参数、计数器值、标志位等。因为这部分RAM是带电池支持的,所以即使在主电源断电时,这些数据也会被保持。保存配置信息: DS1307的RAM可以用于存储与实时时钟(RTC)和其他功能相关的配置信息。这些配置信息可能包括时钟格式(12小时或24小时制)、日期格式、方波输出频率等。临时存储: RAM还可用于存储临时性的运行时数据。例如,当进行时钟校准或其他运行时操作时,可能需要在RAM中存储一些中间数据。断电备份: 由于RAM是带电池支持的,所以它提供了断电备份的功能。即使主电源断电,RAM中的数据仍然会被保存,确保在电源重新连接时可以恢复先前的状态。

总的来说,DS1307上的RAM为用户提供了一块持久存储区域,允许在断电时保留关键的信息。这在需要在系统重新上电时恢复先前状态或保留特定配置和数据时非常有用。

操作时序

设置时钟,比如设置时钟为2024-01-26 10:37:10 周五
在这里插入图片描述发送的字节依次为:设备地址0x68,寄存器地址00,接下来7个字节是要设置进00h-06h这7个寄存器的值。

读取时钟
1.先发送一个数据00,将读取指针只想寄存器0.这个操作在数据手册有说。
在这里插入图片描述2.然后连续读取出数据

在这里插入图片描述## 赋上次芯片的driver代码

#include <stdio.h>
#include "esp_log.h"
#include "ds1307_driver.h"
#include "driver/i2c.h"
#include <string.h>static const char *TAG = "ds1307-driver";#define I2C_MASTER_SCL_IO CONFIG_I2C_MASTER_SCL /*!< GPIO number used for I2C master clock */
#define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA /*!< GPIO number used for I2C master data  */
#define I2C_MASTER_NUM 0                        /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
#define I2C_MASTER_FREQ_HZ 100000               /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE 0             /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0             /*!< I2C master doesn't need buffer */
#define I2C_MASTER_TIMEOUT_MS 1000#define DS1307_I2C_ADDR 0x68 /*!< Slave address of the MPU9250 sensor */RTC_time_typedef time;esp_err_t ds1307_init(void)
{int ret;// 初始化iicint i2c_master_port = I2C_MASTER_NUM;i2c_config_t conf = {.mode = I2C_MODE_MASTER,.sda_io_num = I2C_MASTER_SDA_IO,.scl_io_num = I2C_MASTER_SCL_IO,.sda_pullup_en = GPIO_PULLUP_ENABLE,.scl_pullup_en = GPIO_PULLUP_ENABLE,.master.clk_speed = I2C_MASTER_FREQ_HZ,};i2c_param_config(i2c_master_port, &conf);ret = i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);ESP_LOGI(TAG, "I2C initialized successfully");return ret;
}esp_err_t ds1307_read_time(date_time_t *p_time)
{int ret;uint8_t write_buf[8] = {0};uint8_t *p = (uint8_t *)p_time;// 1.先要发一个字节(write),值为0,write_buf[0] = 0;ret = i2c_master_write_to_device(I2C_MASTER_NUM, DS1307_I2C_ADDR, write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);vTaskDelay(20 / portTICK_PERIOD_MS);// 开始读取数据ret = i2c_master_read_from_device(I2C_MASTER_NUM, DS1307_I2C_ADDR, (uint8_t *)&time, 7, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);ESP_LOGI(TAG, "get raw data:%x,%x,%x,%x,%x,%x,%x,", *(p + 0), *(p + 1), *(p + 2), *(p + 03), *(p + 04), *(p + 05), *(p + 06));p_time->second = time.seconds.ten_sec * 10 + time.seconds.seconds;p_time->minute = time.minutes.ten_min * 10 + time.minutes.minutes;p_time->hour = time.hours.ten_hour * 10 + time.hours.hours;p_time->week = time.weeks.week;p_time->day = time.dates.ten_date * 10 + time.dates.date;p_time->month = time.months.ten_month * 10 + time.months.month;p_time->year = time.years.ten_year * 10 + time.years.year;ESP_LOGI(TAG, "%d-%d-%d %d:%d:%d week=%d", p_time->year, p_time->month, p_time->day, p_time->hour, p_time->minute, p_time->second, p_time->week);return ret;
}/*** @brief 设置芯片的时间*/
esp_err_t ds1307_set_time(date_time_t datetime)
{int ret;RTC_time_typedef time;uint8_t write_buf[9] = {0};uint8_t *p = (uint8_t *)&time;time.years.ten_year = datetime.year / 10;time.years.year = datetime.year % 10;time.months.ten_month = datetime.month / 10;time.months.month = datetime.month % 10;time.dates.ten_date = datetime.day / 10;time.dates.date = datetime.day % 10;time.weeks.week = datetime.week;time.hours.ten_hour = datetime.hour / 10;time.hours.hours = datetime.hour % 10;time.minutes.ten_min = datetime.minute / 10;time.minutes.minutes = datetime.minute % 10;time.seconds.ten_sec = datetime.second / 10;time.seconds.seconds = datetime.second % 10;time.seconds.ch = 0;ESP_LOGI(TAG, "set raw data:%x,%x,%x,%x,%x,%x,%x,", *(p + 0), *(p + 1), *(p + 2), *(p + 03), *(p + 04), *(p + 05), *(p + 06));memcpy(write_buf + 1, p, 7);ret = i2c_master_write_to_device(I2C_MASTER_NUM, DS1307_I2C_ADDR, write_buf, 8, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);return ret;
}

头文件

#ifndef __DS1307_H_
#define __DS1307_H_#include "driver/i2c.h"typedef struct
{union{uint8_t value;struct{uint8_t seconds : 4;uint8_t ten_sec : 3;uint8_t ch : 1;};};
} second_data_TypeDef; // 秒typedef struct
{union{uint8_t value;struct{uint8_t minutes : 4;uint8_t ten_min : 3;uint8_t bit7 : 1;};};
} minutes_data_TypeDef; // 分typedef struct
{union{uint8_t value;struct{uint8_t hours : 4;uint8_t ten_hour : 2;uint8_t jinzhi : 1;uint8_t : 1;};};
} hours_data_TypeDef; // 时typedef struct
{union{uint8_t value;struct{uint8_t week : 3;uint8_t : 5;};};
} weeks_data_TypeDef; // 周typedef struct
{union{uint8_t value;struct{uint8_t date : 4;uint8_t ten_date : 2;uint8_t : 2;};};
} dates_data_TypeDef; // 日typedef struct
{union{uint8_t value;struct{uint8_t month : 4;uint8_t ten_month : 1;uint8_t : 3;};};
} months_data_TypeDef; // 月typedef struct
{union{uint8_t value;struct{uint8_t year : 4;uint8_t ten_year : 4;};};
} years_data_TypeDef; // 年typedef struct
{second_data_TypeDef seconds;minutes_data_TypeDef minutes;hours_data_TypeDef hours;weeks_data_TypeDef weeks;dates_data_TypeDef dates;months_data_TypeDef months;years_data_TypeDef years;
} RTC_time_typedef;typedef struct
{uint16_t year;uint16_t month;uint16_t day;uint8_t week;uint16_t hour;uint16_t minute;uint16_t second;
} date_time_t;esp_err_t ds1307_init(void);
esp_err_t ds1307_read_time(date_time_t *p_time);
esp_err_t ds1307_set_time(date_time_t datetime);#endif

main文件

#include <stdio.h>
#include "esp_log.h"
#include "ds1307_driver.h"static const char *TAG = "i2c_DS1307_main";void app_main(void)
{date_time_t date_time={.year = 24,.month = 1,.day = 26,.week = 5,.hour = 10,.minute = 37,.second = 10,},date_time_now;ESP_ERROR_CHECK(ds1307_init());/* Read the MPU9250 WHO_AM_I register, on power up the register should have the value 0x71 */ESP_ERROR_CHECK(ds1307_set_time(date_time));ESP_LOGI(TAG, "set successfully");vTaskDelay(3000/portTICK_PERIOD_MS);while(1){ds1307_read_time(&date_time_now);vTaskDelay(1000/portTICK_PERIOD_MS);}}

程序小结:

  1. 这个芯片读取数据没有校验位,因此在操作的时候,如果太快,还是比较容易出现数据不对。因此要想办法校验数据正确性。
  2. 可以多次读取,然后判断值的有效性

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

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

相关文章

机器学习-pandas(含数据)

pandas 优势&#xff1a; 增强图表可读性便捷的数据处理能力读取文件方便封装了Matplotlib、Numpy的画图和计算 更详细的教程&#xff1a;Pandas 教程 | 菜鸟教程 (runoob.com) Pandas数据结构 Pandas中一共有三种数据结构&#xff0c;分别为&#xff1a;Series、DataFram…

Vite+Electron快速构建一个VUE3桌面应用(一)

一. 简介 首先&#xff0c;介绍下vite和Electron。 Vite是一种新型前端构建工具&#xff0c;能够显著提升前端开发体验。Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入Chromium和Node.js到二进制的 Electron 允许您保持一个 JavaScript 代码代码…

Docker 容器内运行 mysqldump 命令来导出 MySQL 数据库,自动化备份

备份容器数据库命令&#xff1a; docker exec 容器名称或ID mysqldump -u用户名 -p密码 数据库名称 > 导出文件.sql请替换以下占位符&#xff1a; 容器名称或ID&#xff1a;您的 MySQL 容器的名称或ID。用户名&#xff1a;您的 MySQL 用户名。密码&#xff1a;您的 MySQL …

3dmax效果图渲染出现曝光怎么解决?

在使用3ds Max完成效果图渲染工作时&#xff0c;有时会遇到曝光过度的问题&#xff0c;这会使得渲染的图像出现光斑或者过亮&#xff0c;损害了效果的真实感和美观度。那么解决解决3dmax曝光问题呢&#xff1f;一起看看吧&#xff01; 3dmax效果图渲染出现曝光解决方法 1、相机…

鸿蒙HarmonyOS获取GPS精确位置信息

参考官方文档 #1.初始化时获取经纬度信息 aboutToAppear() {this.getLocation() } async getLocation () {try {const result await geoLocationManager.getCurrentLocation()AlertDialog.show({message: JSON.stringify(result)})}catch (error) {AlertDialog.show({message…

派网AX50C做多宽带路由和核心交换机配置实战教程

接近300办公人员的工厂需要网络升级&#xff0c;我规划设计和部署实施了以下方案&#xff0c;同样是简约不简单&#xff0c;在满足性能需求稳定性的前提下&#xff0c;既有经济性&#xff0c;又有安全性。 派网做路由器&#xff0c;刚好开启默认防病毒策略&#xff0c;省下来一…

[HTML]Web前端开发技术18(HTML5、CSS3、JavaScript )HTML5 基础与CSS3 应用——喵喵画网页

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;佬佬会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…

防御保护防火墙的NET使用

要求如下 下图为实验图&#xff1a;根据四条要求分析&#xff0c;&#xff0c;图中的分公司与本实验无关&#xff0c;直接无视掉。 要求一&#xff1a;生产区在工作时间内可以访问服务器区&#xff08;DMZ&#xff09;&#xff0c;仅可以访问http服务器&#xff1b; 要求二&am…

【C++中STL】map/multimap容器

map/multimap容器 map基本概念map构造和赋值map的大小和交换map插入和删除map的查找和统计 map排序 map基本概念 map中的所有元素都是pair对组&#xff0c;高效率&#xff0c;pair中的第一个元素为key&#xff08;键值&#xff09;&#xff0c;起到索引作用&#xff0c;第二个…

“趣味夕阳,乐享生活”小组活动(第二节)

立冬以来&#xff0c;天气日渐寒冷&#xff0c;气温变化较大&#xff0c;各种传染病多发&#xff0c;为进一步增强老年人冬季预防传染病保健意识及科学合理健康的生活方式。近日&#xff0c;1月22日&#xff0c;南阳市人人社工灌涨站开展了“趣味夕阳&#xff0c;乐享生活”小组…

Python zip函数

在Python编程中&#xff0c;zip()函数是一个功能强大而灵活的工具&#xff0c;用于将多个可迭代对象&#xff08;如列表、元组、字符串等&#xff09;组合成一个元组的序列。本文将深入探讨zip()函数的用法、语法、示例代码&#xff0c;并探讨其在实际编程中的应用场景。 什么…

pytorch 实现中文文本分类

&#x1f368; 本文为[&#x1f517;365天深度学习训练营学习记录博客&#x1f366; 参考文章&#xff1a;365天深度学习训练营&#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制]\n&#x1f680; 文章来源&#xff1a;[K同学的学习圈子](https://www.yuque.com/mi…

MySQL十部曲之一:MySQL概述及手册说明

文章目录 数据库、数据库管理系统以及SQL之间的关系关系型数据库与非关系型数据库手册语法约定 数据库、数据库管理系统以及SQL之间的关系 名称说明数据库&#xff08;Database&#xff09;即存储数据的仓库&#xff0c;其本质是一个文件系统。它保存了一系列有组织的数据。数…

今日AI大热潮,明日智能风向标

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

mybatis-plus常用使用方法

** mybaits-plus常用使用方法 ** 常用三层分别继承方法 1.1mapper层&#xff08;接口定义层&#xff09;可以用BaseMapper<> 例如&#xff1a; 1.2.里面常用的封装方法有 1.3常用方法介绍 【添加数据&#xff1a;&#xff08;增&#xff09;】int insert(T entity);…

RUST笔记:candle使用基础

candle介绍 candle是huggingface开源的Rust的极简 ML 框架。 candle-矩阵乘法示例 cargo new myapp cd myapp cargo add --git https://github.com/huggingface/candle.git candle-core cargo build # 测试&#xff0c;或执行 cargo ckeckmain.rs use candle_core::{Device…

力扣hot100 课程表 拓扑序列

Problem: 207. 课程表 文章目录 思路复杂度Code 思路 &#x1f468;‍&#x1f3eb; 三叶题解 复杂度 时间复杂度: O ( n m ) O(nm) O(nm) 空间复杂度: O ( n m ) O(nm) O(nm) Code class Solution{int N 100010, M 5010, idx;int[] in new int[N];// in[i] 表示节…

MySQL十部曲之四:MySQL中的数据类型

文章目录 前言概述数字类型数字类型语法数字类型字面量十六进制字面量位字面量布尔字面量 数字类型的属性超出范围和溢出处理 时间和日期类型时间和日期类型语法DATE、DATETIME和TIMESTAMP的异同TIMESTAMP和DATETIME的自动初始化和更新时间和日期字面量 字符串类型字符串类型语…

解读BEVFormer,新一代CV工作的基石

文章出处 BEVFormer这篇文章很有划时代的意义&#xff0c;改变了许多视觉领域工作的pipeline[2203.17270] BEVFormer: Learning Birds-Eye-View Representation from Multi-Camera Images via Spatiotemporal Transformers (arxiv.org)https://arxiv.org/abs/2203.17270 BEV …

php mysql字段默认值使用问题

前提是使用了事务&#xff0c;在第一个阶段 是A表操作保存&#xff0c;第二阶段操作B表&#xff0c;操作B表的时候使用了A表的一个字段&#xff0c;这个字段在第一阶段没有设置值&#xff0c;保存的时候使用字段默认值。 【这种情况 最好是在第一阶段 把后面要使用的字段设置好…