实时时钟芯片DS1307的使用及驱动代码

2023-05-16

DS1307实时时钟芯片的介绍及驱动代码

目录

一、DS1307是什么?

二、DS1307的功能

三、DS1307的寄存器

四、代码

1.读出数据

2.写入数据

3.时间初始化设置

4.获取当前时间

五、注意事项

总结


一、DS1307是什么?

DS1307是一款基于IIC总线接口的实时时钟芯片,可以独立于MCU工作,芯片具有备用电源自动切换功能,可以在主电源掉电或其他一些恶劣环境下保证系统时钟的准确。

二、DS1307的功能

  1. DS1307具有产生时、分、秒、日、月、年等功能,闰年可自动调整,日历和时钟数据以BCD码的方式存放在片内的寄存器上。
  2. 片内集成了56字节的具有掉电后电池保持的RAM数据存储器,可以用来保存一些关键数据,
  3. 芯片具有掉电检测和自动切换电池供电功能,当DS1307靠后备电池维持工作时,拒绝CPU对其的读出和写入操作。

三、DS1307的寄存器

DS1307片内有多个时间保存寄存器,单片机就是通过读取这些寄存器得到时间和日期相关的数据的,其中有8个寄存器专门用来存储时间信息,另外56个字节的RAM可以供用户自由使用。

  1. 时间和日历信息在时间保存寄存器上的存放是以BCD码的形式存放的,以分钟寄存器为例,分的十位存放寄存器的高四位,分的个位存放在寄存器的低四位。
  2. 日期和星期寄存器的值会在每天的午夜递增,我们需要在程序中指定星期与星期寄存器的对应关系,也就是说把星期寄存器值为1时定义为星期一,那么当读取的值为1时就应当是星期日。
  3. 寄存器0(地址00h)的第7位是时钟停止位CH。当这一位置1时,时间振荡器会被禁止,该位清零时,振荡器会使能。
  4. 芯片在第一次上电时,时间和日期会被复位成:01月01日00年、星期01、00时00分00秒,秒寄存器的CH位会被设定为1。我们在对时间值进行设定时,需将CH位清零以使能振荡器。
  5. DS1307可以运行在12小时模式或24小时模式。小时寄存器的bit6是定义12小时或24小时模式选择位。当该位置1时,时钟被定义为12小时模式,清零时为24小时模式。
  6. DS1307可以设定为12小时模式下,小时寄存器的bit5是AM/PM位,其值为0时表示AM,为1时表示PM;在24小时模式下bit5是20小时位(20-23)。

四、代码

1.读出数据

/*
*********************************************************************************************************
*	函 数 名: uint8_t DS1307_Read(uint8_t address)
*	功能说明: 向DS1307寄存器读取数据
*	形    参:寄存器地址
*	返 回 值: 读出的数据
*********************************************************************************************************
*/
uint8_t DS1307_Read(uint8_t address)
{
	uint8_t dat;	
	i2c_Start();
	i2c_SendByte(0xD0);//发送设备地址,写指令
	i2c_WaitAck();
	i2c_SendByte(address);//发送寄存器地址
	i2c_WaitAck();
	i2c_Stop();
	i2c_Start();//重新启动IIC总线
	i2c_SendByte(0xD1);	//发送设备地址,读指令
	i2c_WaitAck();
	dat=i2c_ReadByte(); //读一个字节数据
	i2c_NAck();	
	i2c_Stop();
	return dat;
}

2.写入数据

/*
*********************************************************************************************************
*	函 数 名: DS1307_Wirte(uint8_t address , uint8_t dat)
*	功能说明: 向DS1307寄存器写数据
*	形    参:address:寄存器地址,dat:要写入的数据
*	返 回 值: 无
*********************************************************************************************************
*/
void DS1307_Wirte(uint8_t address , uint8_t dat)
{ 
	i2c_Start();
	i2c_SendByte(0xD0);//发送设备地址,写指令
	i2c_WaitAck();
	i2c_SendByte(address);//发送寄存器地址
	i2c_WaitAck();
	i2c_SendByte(dat);//写一个字节数据
	i2c_WaitAck();
	i2c_Stop();	
}

3.时间初始化设置

/*
*********************************************************************************************************
*	函 数 名: void DS1307_Init_Time(void)
*	功能说明: 第一次上电时,需要初始化时间,初始化一次后就不必重复初始化
*	形    参:无
*	返 回 值: 无
*********************************************************************************************************
*/
void DS1307_Init_Time(void)
{
	if(DS1307_Read(FLAG_ADDR)!=FLAG_VAL)//如果未初始化,执行初始化时间
	{
		DS1307_Set_Time(2023,2,16,19,02,00,4);//2023年2月16日 17:50:00 星期四
		printf("时间初始化完成,flag=%d\r\n",DS1307_Read(FLAG_ADDR));
	}	else{
		printf("时间已初始化过,flag=%d\r\n",DS1307_Read(FLAG_ADDR));
	}
}
//时间初始化设置
void DS1307_Set_Time(uint16_t year,uint8_t mon,uint8_t day,uint8_t hour,uint8_t min,uint8_t sec,uint8_t week)
{
	year-=2000;//年默认2000年开始
	if(year > 100) year = 0;
	
	//十进制转为BCD码
	year = ((year /10) << 4) + year %10;
	mon  = ((mon  /10) << 4) + mon  %10;
	day  = ((day  /10) << 4) + day  %10;
	week = ((week /10) << 4) + week  %10;
	hour = ((hour /10) << 4) + hour %10;
	min  = ((min  /10) << 4) + min  %10;
	sec  = ((sec  /10) << 4) + sec  %10;
	
	//写入寄存器,同时标记一个地址
	DS1307_Wirte(FLAG_ADDR,FLAG_VAL);   //写入已经设置时间标志		
	DS1307_Wirte(0x00,sec);    //设置秒
    DS1307_Wirte(0x01,min);    //设置分
    DS1307_Wirte(0x02,hour);   //设置时
    DS1307_Wirte(0x03,week);   //设置周
    DS1307_Wirte(0x04,day);    //设置日
    DS1307_Wirte(0x05,mon);    //设置月	
    DS1307_Wirte(0x06,year);   //设置年		
}

4.获取当前时间

//获取当前时间
void Get_Now_Time(void)
{
	uint8_t sec,min,hour,week,day,mon,year;
	uint8_t i;
	
	sec  = DS1307_Read(0x00);
	min  = DS1307_Read(0x01);
	hour = DS1307_Read(0x02);
	week = DS1307_Read(0x03);	
	day  = DS1307_Read(0x04);
	mon  = DS1307_Read(0x05);
	year = DS1307_Read(0x06);
	
	//BCD码转十进制
	date_time.sec  = (sec/16)*10 + sec%16;
	date_time.min  = (min/16)*10 + min%16;
	date_time.hour = (hour/16)*10 + hour%16;
	date_time.day  = (day/16)*10  + day%16;
	date_time.mon  = (mon/16)*10  + mon%16;
	date_time.year = (year/16)*10 + year%16 + 2000;
	date_time.week = (week/16)*10 + week%16;   			
}

五、注意事项

  1. DS1307的工作电压为4.5V-5.5V供电。
  2. I2C总线控制DS1307,用GPIO模拟I2C时序即可。
  3. 时间配置:直接把时间值写入0x00~0x06的时间寄存器。
  4. 时间读取:直接读取0x00~0x06的时间寄存器即可。
  5. 读取时间时发现未走时可能是00h 地址的寄存器第7 位为1,此位为1则芯片未开始工作,即时钟未走时,记得首次上电时把该位清零。
  6. 首次上电设置时间后不必每次上电都再次初始化一下时间,停电后有备用电池,此时不必重写时间单元。

总结

本文简单介绍了DS1307实时时钟芯片的使用,提供了DS1307的驱动程序代码,方便首次使用DS1307的初学者们学习和参考。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实时时钟芯片DS1307的使用及驱动代码 的相关文章

随机推荐

  • DIY无人机组装与飞控参数调试记录(DJI NAZA-LITE)

    早就想玩一玩无人机 xff0c 奈何各种原因一直没有机会 xff0c 工作之后资金富足 xff0c 加上本身工作和这个相关性比较大 xff0c 于是就自己DIY了一台无人机 一 材料准备 xff1a F450机架 GPS支架 好盈乐天 20
  • Mysql(16)——日志

    前言 我们之前了解过redo log和undo log xff0c 他们是作用在InnoDb存储引擎层的 xff0c 今天我们来讲讲服务层的其他日志类型 一 错误日志 错误日志是 MySQL 中最重要的日志之一 xff0c 它记录了当 my
  • Mysql(17)——优化

    前言 一 SQL和索引优化 二 应用优化 除了优化SQL和索引 xff0c 很多时候 xff0c 在实际生产环境中 xff0c 由于数据库服务器本身的性能局限 xff0c 就必须要对上层的应用来进行一些优化 xff0c 使得上层应用访问数据
  • 项目——C++实现数据库连接池

    前言 在学习Mysql的时候 xff0c 我们都有这个常识 xff1a 对于DB的操作 xff0c 其实本质上是对于磁盘的操作 xff0c 如果对于DB的访问次数过多 xff0c 其实就是涉及了大量的磁盘IO xff0c 这就会导致MYsq
  • Redis入门——发展历程及NoSQL

    前言 随着社会的发展 xff0c 数据存储经历了诸多的过程 xff0c 这篇文章就是介绍Redis的发展由来 xff1a 1 单机Mysql时代 这种模式存在以下的瓶颈 xff1a 数据量太大 xff0c 一个机器存放不下数据的索引太大 x
  • Redis(1)——基本命令及数据类型(5+3)

    Redis的基本概念 Remote Dictionary Server xff1a 远程字典服务Redis 是一个开源 xff08 BSD许可 xff09 的 xff0c 内存中的数据结构存储系统 xff0c 它可以用作数据库 缓存和消息中
  • Redis(2)——事务机制

    Redis的事务机制 Redis的事务本质 xff1a 一组命令的集合一个事务中的所有命令都会都被序列化 xff0c 在事务执行的过程中 xff0c 会按照顺序执行 xff01 一次性 顺序性 排他性 执行一系列的命令Redis没有事务隔离
  • Redis(3)—— 持久化、发布订阅

    持久化 Redis是内存数据库 xff0c 如果不将内存中的数据库状态保存到磁盘中 xff0c 那么一旦服务器进程退出 xff0c 服务器中的数据库状态也会消失 所以Redis提供了持久化的功能 1 RDB xff08 Redis Data
  • Redis(4)——主从复制

    Redis主从复制 主从复制 xff1a 指的是将一个Redis服务器的数据 xff0c 复制到其他的Redis服务器 前者称为主节点 xff08 master leader xff0c 后者称为从节点 xff08 slave follow
  • Redis(5)——缓存穿透和雪崩

    概要 Redis缓存的使用 xff0c 极大的提高了应用程序的性能和效率 xff0c 特别是数据查询等 但同时 xff0c 它也带来了一些问题 其中 xff0c 最主要的问题就是数据一致性 xff0c 从严格意义上来讲 xff0c 这个问题
  • 复习:结构体大小的内存对齐问题

    内存对齐 内存对齐是指 xff1a 任意单个类型的数据都需要存放在能被它本身大小所能整除的地址上 基本类型的大小 char 1 short 2 int 4 long 4 long long 8 float 4 double 8 指针 4 8
  • 0.一些自己初学Solidworks的疑惑

    1 为什么要选择学习SolidWorks 首先 作为初学者 我们对一个东西并不是很了解 那么就需要别人来教我们 对吧 这些人可以是老师 可以是同学 可以是师傅 可以是网络上热心肠的大神 可以是一些培训机构 等等 首先呢 学习三维设计软件 看
  • LInux——五种IO模型

    Linux中的IO简述 IO主要分为以下的三种 xff1a 内存IO网络IO磁盘IO 通常我们所说的IO是后两者 xff0c Linux中无法直接操作IO设备 xff0c 必须通过系统调用请求kernal来协助完成IO的动作 xff0c 内
  • 复习:Linux中的软连接和硬连接

    前言 首先我们先来复习以下Linux的文件系统 Linux的文件系统是EXT4 以EXT4文件系统格式化磁盘时 xff0c 将磁盘分成了三个区 xff0c 分别是 xff1a 1 superblock xff1a 记录文件系统的整体信息 x
  • 复习:字节对齐的原则

    为什么需要字节对齐 xff1f 现代计算机中内存空间都是按照byte划分的 xff0c 从理论上讲似乎对任何类型的变量的访问可以从任何地址开始 xff0c 但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问 xff0c 这就需要各
  • Reactor模型

    前言 首先让我们来回顾一下select poll和epoll是如何获取网络事件的 xff1a 在获取事件时 xff0c 先把我们要关心的连接传给内核 xff0c 再由内核检测 xff1a 若没有事件发生 xff0c 线程只需阻塞在这个系统调
  • Proactor模型

    前言 上一篇讲解的Reaactor是非阻塞的同步网络模式 xff0c 而Proactor是异步网络模式 至于异步IO怎么理解 xff1a 可以参考我的这一篇博客 xff1a Linux的五种IO模型 理解之后 xff1a 你就会感受到 xf
  • STL空间配置器(一级配置器及二级配置器)

    前言 在我们日常使用STL中的容器时 xff0c 我们是几乎感受不到空间配置器的存在 xff0c 因为他一直在默默工作 xff0c 我们在之前的这一篇博客中也大概介绍过 xff1a C 43 43 xff08 21 xff09 vector
  • HTTP各个版本的区别

    HTTP 1 0 短连接版本 HTTP 1 0规定浏览器与服务器只保持短暂的连接 xff0c 即每一次请求都需要与服务器建立一次TCP连接 xff0c 服务器完成请求处理后立即断开TCP连接 服务器不会跟踪每个客户也不记录过去的请求 xff
  • 实时时钟芯片DS1307的使用及驱动代码

    DS1307实时时钟芯片的介绍及驱动代码 目录 一 DS1307是什么 xff1f 二 DS1307的功能 三 DS1307的寄存器 四 代码 1 读出数据 2 写入数据 3 时间初始化设置 4 获取当前时间 五 注意事项 总结 一 DS1