DS1302实时时钟模块详解:从原理到代码实现
创作时间:
作者:
@小白创作中心
DS1302实时时钟模块详解:从原理到代码实现
引用
CSDN
1.
https://blog.csdn.net/qq_45217381/article/details/146173925
DS1302是一种常用的实时时钟模块,广泛应用于各种嵌入式系统中。本文将详细介绍DS1302的使用方法,包括其功能简介、引脚说明以及具体的程序设计,帮助读者快速掌握DS1302的使用技巧。
一、DS1302简介
我们首先来简单介绍一下DS1302,首先DS1302具有实时时钟的功能,DS1302能够精确记录当前的时间,包括秒、分钟、小时、日期、月份以及年份,并支持闰年的自动调整。
除了实时时钟功能外,DS1302还具备数据保存功能,DS1302内置有31字节静态RAM用于数据备份,即使外部供电中断也能依靠后备电池保持数据不丢失。
DS1302采用简单的三线SPI兼容串行接口进行通讯,仅需三条信号线即可完成全部操作命令传输及与MCU的数据交互。DS1302使用一跟数据线实现双向数据传输,类似于我们之前介绍过的DS18B20和DHT11。
这里插一小段,在使用DS1302之前不知道大家有没有使用过STM32的RTC功能,对于像一些STM32F103ZET6这种核心板上有这个3V电池的板子来说,用起来还是比较友好的,但是像我们平时用的STM32F103C8T6这种比较小巧的核心板来讲,没有这个3V电池,如果使用到RTC功能,想要做到断电能够继续计时的话需要给单片机的VBAT引脚接上3V电池供电。
二、引脚介绍
DS1302总共有五个引脚
引脚 | 功能 |
---|---|
VCC | 电源引脚,接3.3V/5V |
CLK | 时钟引脚 |
DAT | 数据线,与MCU实现双向数据交互 |
RST | 复位引脚,可以理解成类似片选 |
三、程序设计
3.1 DAT引脚处理
DAT引脚由于需要完成MCU和DS1302的双向数据传输,所以在不同情况下需要配置成不同的状态,我们这里封装一个函数来方便处理,当然也可以使用宏定义函数来实现
/*
*==============================================================================
*函数名称:Drv_Ds1302_DatIoCtrl
*函数功能:DS1302 DAT引脚控制
*输入参数:state:状态(0输入/1输出)
*返回值:无
*备 注:无
*==============================================================================
*/
void Drv_Ds1302_DatIoCtrl (u8 state)
{
// 结构体定义
GPIO_InitTypeDef GPIO_InitStructure;
// 使能时钟
RCC_APB2PeriphClockCmd (DS1302_DAT_CLK, ENABLE);
if (state)
{
// 配置结构体
GPIO_InitStructure.GPIO_Pin = DS1302_DAT_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(DS1302_DAT_PORT, &GPIO_InitStructure);
}
else
{
// 配置结构体
GPIO_InitStructure.GPIO_Pin = DS1302_DAT_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(DS1302_DAT_PORT, &GPIO_InitStructure);
}
}
3.2 DS1302读写寄存器
/*
*==============================================================================
*函数名称:Med_Ds1302_WriteByte
*函数功能:DS1302写入寄存器
*输入参数:
*返回值:无
*备 注:无
*==============================================================================
*/
void Med_Ds1302_WriteByte (u8 addr,u8 data)
{
u8 i;
RST = 0; // 关闭数据传输
CLK = 0; // 拉低时钟
RST = 1; // 启动数据传输
Drv_Ds1302_DatIoCtrl(1); // DAT引脚设置成输出模式
addr = addr & 0xFE; // 最低位置零,寄存器0位为0时写,为1时读
// 写入目标地址
for(i = 0;i < 8;i ++)
{
if (addr & 0x01)
DAT = 1;
else
DAT = 0;
CLK = 1; // 时钟上升沿写入数据
CLK = 0;
addr = addr >> 1;
}
// 写入数据
for (i = 0;i < 8;i ++)
{
if(data & 0x01)
DAT = 1;
else
DAT = 0;
CLK = 1; // 时钟上升沿写入数据
CLK = 0;
data = data >> 1;
}
CLK = 1; // 将时钟电平置于高电平状态
RST = 0; // 关闭数据传输
}
/*
*==============================================================================
*函数名称:Med_Ds1302_ReadByte
*函数功能:DS1302读取寄存器
*输入参数:
*返回值:无
*备 注:无
*==============================================================================
*/
u8 Med_Ds1302_ReadByte (u8 addr)
{
u8 i,data;
RST = 0; // 关闭数据传输
CLK = 0; // 拉低时钟
RST = 1; // 启动数据传输
Drv_Ds1302_DatIoCtrl(1); // DAT引脚设置成输出模式
addr = addr | 0x01; // 最低位置高,寄存器0位为0时写,为1时读
// 写入目标地址
for(i = 0;i < 8;i ++)
{
if (addr & 0x01)
DAT = 1;
else
DAT = 0;
CLK = 1; // 时钟上升沿写入数据
CLK = 0;
addr = addr >> 1;
}
// 从DS1302读出数据
Drv_Ds1302_DatIoCtrl(0); // DAT引脚设置为输入模式
for(i = 0;i < 8;i ++)
{
data = data >> 1;
if (DS1302_DAT_IN())
data |= 0x80;
else
data &= 0x7F;
CLK = 1; // 时钟上升沿写入数据
CLK = 0;
}
CLK = 1; // 将时钟电平置于高电平状态
RST = 0; // 关闭数据传输
return data;
}
3.3 DS1302设置时间
/*
*==============================================================================
*函数名称:Med_Ds1302_SetTime
*函数功能:DS1302设置时间
*输入参数:writeTime:要设置的时间
*返回值:无
*备 注:无
*==============================================================================
*/
void Med_Ds1302_SetTime (uint8_t *targetTime)
{
Med_Ds1302_WriteByte(DS1302_CONTROL_ADDR,0x00); // 关闭写入
Med_Ds1302_WriteByte(DS1302_SEC_ADDR,0x80); // 暂停时钟
// Med_Ds1302_WriteByte(DS1302_CHARGER_ADDR,0xa9); // 涓流充电
Med_Ds1302_WriteByte(DS1302_YEAR_ADDR,targetTime[1]); // 年
Med_Ds1302_WriteByte(DS1302_MONTH_ADDR,targetTime[2]); // 月
Med_Ds1302_WriteByte(DS1302_DAY_ADDR,targetTime[3]); // 日
Med_Ds1302_WriteByte(DS1302_HOUR_ADDR,targetTime[4]); // 时
Med_Ds1302_WriteByte(DS1302_MIN_ADDR,targetTime[5]); // 分
Med_Ds1302_WriteByte(DS1302_SEC_ADDR,targetTime[6]); // 秒
Med_Ds1302_WriteByte(DS1302_WEEK_ADDR,targetTime[7]); // 周
Med_Ds1302_WriteByte(DS1302_CHARGER_ADDR,0xA5); // 打开充电功能 选择2K电阻充电方式
Med_Ds1302_WriteByte(DS1302_CONTROL_ADDR,0x80); // 打开写入
}
3.4 DS1302获取当前时间
/*
*==============================================================================
*函数名称:Med_Ds1302_GetTime
*函数功能:DS1302获取时间
*输入参数:writeTime:要设置的时间
*返回值:无
*备 注:无
*==============================================================================
*/
void Med_Ds1302_GetTime (DS1302TimeStruct *timeData)
{
u8 readtime[8]; // 当前时间
readtime[1] = Med_Ds1302_ReadByte(DS1302_YEAR_ADDR); // 年
readtime[2] = Med_Ds1302_ReadByte(DS1302_MONTH_ADDR); // 月
readtime[3] = Med_Ds1302_ReadByte(DS1302_DAY_ADDR); // 日
readtime[4] = Med_Ds1302_ReadByte(DS1302_HOUR_ADDR); // 时
readtime[5] = Med_Ds1302_ReadByte(DS1302_MIN_ADDR); // 分
readtime[6] = (Med_Ds1302_ReadByte(DS1302_SEC_ADDR)) & 0x7f; // 秒,屏蔽秒的第7位,避免超出59
readtime[7] = Med_Ds1302_ReadByte(DS1302_WEEK_ADDR); // 周
timeData -> year = (readtime[0] >> 4) * 1000 + (readtime[0] & 0x0F) * 100 + (readtime[1] >> 4) * 10 + (readtime[1] & 0x0F); // 计算年份
timeData -> month = (readtime[2] >> 4) * 10 + (readtime[2] & 0x0F); // 计算月份
timeData -> day = (readtime[3] >> 4) * 10 + (readtime[3] & 0x0F); // 计算日期
timeData -> hour = (readtime[4] >> 4) * 10 + (readtime[4] & 0x0F); // 计算小时
timeData -> minute = (readtime[5] >> 4) * 10 + (readtime[5] & 0x0F); // 计算分钟
timeData -> second = (readtime[6] >> 4) * 10 + (readtime[6] & 0x0F); // 计算秒钟
timeData -> week = (readtime[7] & 0x0F); // 计算星期
}
热门推荐
如何编写产品需求规格书
酸奶和酒可以一起喝吗?答案令人惊喜
如何显示或隐藏桌面通用图标
艾滋病感染者用药时间:精准管理,守护生命之光
探秘低温锂电池组:极寒中的能量守护者
建议收藏:历代中国牡丹画臻选(附评论文章及部分作品下载链接)
牡丹(探究牡丹在中国文化中的意义和代表的人物)
银杏树生长环境探究:从土壤到光照的全方位指南
银杏树生长环境探究(银杏树在什么地方最适合生长?)
Telegram关闭通讯录权限指南:保护隐私的必要操作
固定测速摄像头从多远开始拍照?这种测速方式有哪些规定?
结核病耐药机制研究
结核耐药基因检测价格透明化,助力我国抗结核治疗水平提升
杀完牙神经后,是否一定需要进行补牙治疗?
什么是车内加热功能
中国商务签证申请指南
诸葛亮的人物特点是怎样的?他的主要事迹有哪些?
肤色暗沉者的穿衣指南:这些颜色让你气色更佳
海口秀英永兴镇:小蜜蜂带动“甜蜜事业”大发展
汉霸二王城:穿越时空的历史遗迹之旅
RFID常用的差错控制编码及其应用场景
糖尿病人这测血糖才精准,空腹和餐后血糖,差值这个数易暴雷
哈尔滨亚冬会服装设计项目负责人:将第一缕阳光穿上身
春天没食欲,试试这8道菜,开胃下饭,提高抵抗力
黄巾起义的镇压与平息
巫女:日本动漫中的神秘使者,她们的历史与现代角色你知道吗?
巫女:日本动漫中的神秘使者,她们的历史与现代角色你知道吗?
人工智能在野生动物保护中的应用
如何有效购置专利以满足您的特定需求攻略
如何利用日常物品制作简易早教闪卡?这些小知识能帮你!