加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入

嵌入式外设集-时钟模块(DS1302)驱动

03/20 15:16
4437
服务支持:
技术交流群

完成交易后在“购买成功”页面扫码入群,即可与技术大咖们分享疑惑和经验、收获成长和认同、领取优惠和红包等。

虚拟商品不可退

当前内容为数字版权作品,购买后不支持退换且无法转移使用。

加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论
放大
实物图
相关方案
  • 方案介绍
    • 一、模块介绍
    • 二、资料获取
    • 三、代码编写
    • 四、参考
  • 相关文件
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

一、模块介绍

DS1302时钟模块是一款由美国DALLAS公司生产的高性能、低功耗实时时钟芯片。它可以对年、月、日、时、分、秒进行计时,并具有闰年补偿功能。该芯片内部集成了一个31字的RAM寄存组,用于临时存放数据。其接口简单,与TTL兼容。 以下是DS1302时钟模块的主要特点:

1. 实时时钟:DS1302可以准确地计时年、月、日、时、分、秒,适用于需要精确时间控制的场合。

2. 闰年补偿:DS1302能够自动进行闰年补偿,确保日历数据的准确性。

3. 低功耗:DS1302在正常工作状态下功耗较低,有利于延长系统续航时间。

4. 涓流充电:DS1302具备涓流充电功能,可以对备用电源进行充电,提高了系统的可靠性。

5. 3线接口:DS1302采用简单的3线接口与微处理器通讯,便于集成到各种系统中。

6. 兼容性:DS1302与DS1202兼容,可以替代DS1202在相关应用中使用。

7. 宽电压范围:DS1302的工作电压范围为2.5V至5.5V,适应不同电源环境。

DS1302时钟模块在许多应用领域都有广泛的应用,如嵌入式系统智能家居工业自动化等。通过与单片机等微处理器配合使用,可以实现实时时间显示、数据记录等功能。

二、资料获取

关注微信公众号--星之援工作室 发送关键字(DS1302

➡️➡️

 效果展示

接线规则(可在ds1302.h中自行修改)

/*
DS1302接口:
VCC -> 5.0/3.3
GND -> GND
GPIOB_14 ->DS1302_RST
GPIOB_13 ->DS1302_DAT
GPIOB_12 ->DS1302_CLK
*/

三、代码编写

main

用于显示处理,当时钟模块的秒更新之后就会通过串口输出

/*--------------------------------------------------------*
 *                                       								  *
 *   	 星之援网络科技工作室学习资料v1.0    								*
 *		 时间:2022.7.14                    								*
 *		 程序介绍:DS1302实验              								  *
 *		 实现效果:串口输出系统时间   										  *
 *                                      							    *
 *--------------------------------------------------------*
*/

#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "usart.h"
#include "ds1302.h"

int main(void)
{
	DS1302_Time_t time = {0};
	char str[50];
	u8 sec=0;
	delay_init();
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	// LED 端口初始化 
	LED_GPIO_Config();
	// KEY 初始化
	Key_GPIO_Config();
	// 串口初始化
	uart_init(115200);
	//初始化ds1302端口
	DS1302_Init();	
	printf("init okn");
	
  while(1)
	{
		DS1302_GetTime(&time);   //读取此时时刻
		if(sec==time.second)//判断秒钟数是否有更新
		{
			delay_ms(5);//没有更新便延时5ms
		}
		else
		{
			sec=time.second;//秒钟数有更新,则将变量sec更新
			sprintf(str,"Data: %d-%d-%d Time: %d:%d:%d ",time.year,time.month,time.day,
																		 time.hour,time.minute,time.second);
			printf("%sn",str);
		}
   }   
}

ds1302.c

驱动代码

#include "ds1302.h"
#include "delay.h"
 
/*
DS1302接口:
	VCC -> 5.0/3.3
	GND -> GND
	GPIOB_14 ->DS1302_RST
	GPIOB_13 ->DS1302_DAT
	GPIOB_12 ->DS1302_CLK
*/
//DS1302地址定义
#define DS1302_SEC_ADDR           0x80		//秒数据地址
#define DS1302_MIN_ADDR           0x82		//分数据地址
#define DS1302_HOUR_ADDR          0x84		//时数据地址
#define DS1302_DAY_ADDR           0x86		//日数据地址
#define DS1302_MONTH_ADDR         0x88		//月数据地址
#define DS1302_WEEK_ADDR          0x8a		//星期数据地址
#define DS1302_YEAR_ADDR          0x8c		//年数据地址
#define DS1302_CONTROL_ADDR       0x8e		//控制数据地址
#define DS1302_CHARGER_ADDR       0x90 		//充电功能地址			 
#define DS1302_CLKBURST_ADDR      0xbe
 
//初始时间定义
static u8 time_buf[8] = {0x20,0x19,0x04,0x12,0x15,0x07,0x00,0x06};//初始时间2019年4月12号15点07分00秒 星期五
u8 sec_buf=0;  //秒缓存
u8 sec_flag=0; //秒标志位

void DS1302_Init()//CE,SCLK端口初始化
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(CE_GPIO_CLK, ENABLE);
	GPIO_InitStructure.GPIO_Pin = CE_GPIO_PIN; //PC.11  CE
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
	GPIO_Init(CE_GPIO_PORT, &GPIO_InitStructure);//初始化GPIOC.11
	GPIO_ResetBits(CE_GPIO_PORT,CE_GPIO_PIN); 
	 
	GPIO_InitStructure.GPIO_Pin = SCLK__GPIO_PIN; //PC.12  SCLK
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
	GPIO_Init(SCLK__GPIO_PORT, &GPIO_InitStructure);//初始化GPIOC.12
	GPIO_ResetBits(SCLK__GPIO_PORT,SCLK__GPIO_PIN); 
}
//配置双向I/O端口为输出态
static void ds1032_DATAOUT_init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(DATA_GPIO_CLK, ENABLE);
 
	GPIO_InitStructure.GPIO_Pin = DATA__GPIO_PIN; //PC.10  DATA
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(DATA__GPIO_PORT, &GPIO_InitStructure);//初始化GPIOC.10
	GPIO_ResetBits(DATA__GPIO_PORT,DATA__GPIO_PIN);
}
//配置双向I/O端口为输入态
static void ds1032_DATAINPUT_init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(DATA_GPIO_CLK, ENABLE);
	GPIO_InitStructure.GPIO_Pin = DATA__GPIO_PIN; //PC.10 DATA
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(DATA__GPIO_PORT, &GPIO_InitStructure);//初始化GPIOC.10
}
 //向DS1302写入一字节数据
void DS1302_WriteByte(u8 addr,u8 data) 
{
	u8 i;
	DS1302_RST=0; //禁止数据传输 !!!这条很重要
	DS1302_CLK=0; //确保写数据前SCLK为低电平
	DS1302_RST=1;	//启动DS1302总线	
	ds1032_DATAOUT_init();
	addr=addr&0xFE;  //最低位置零,寄存器0位为0时写,为1时读
	for(i=0;i<8;i++) //写入目标地址:addr
	{
		if (addr&0x01) DS1302_OUT=1;
		else DS1302_OUT=0;
		DS1302_CLK=1; //时钟上升沿写入数据
		DS1302_CLK=0;
		addr=addr>>1;
	}	
	for (i=0;i<8;i++) //写入数据:data
	{
		if(data&0x01) DS1302_OUT=1;
		else DS1302_OUT=0;
		DS1302_CLK=1;    //时钟上升沿写入数据
		DS1302_CLK=0;
		data = data >> 1;
	}
	DS1302_CLK=1;    // 将时钟电平置于高电平状态 ,处于已知状态
	DS1302_RST=0;	//停止DS1302总线
}

//从DS1302读出一字节数据
u8 DS1302_ReadByte(u8 addr) 
{
	u8 i,temp;	
	DS1302_RST=0; //这条很重要
	DS1302_CLK=0; //先将SCLK置低电平,确保写数居前SCLK被拉低
	DS1302_RST=1; //启动DS1302总线
	ds1032_DATAOUT_init();
	//写入目标地址:addr
	addr=addr|0x01; //最低位置高,寄存器0位为0时写,为1时读
	for(i=0;i<8;i++) 
	{
		if (addr&0x01) DS1302_OUT=1;
		else DS1302_OUT=0;
		DS1302_CLK=1; //写数据
		DS1302_CLK=0;
		addr = addr >> 1;
	}	
	//从DS1302读出数据:temp
	ds1032_DATAINPUT_init();
	for(i=0;i<8;i++)
	{
		temp=temp>>1;
		if (DS1302_IN) temp|=0x80;
		else temp&=0x7F;
		DS1302_CLK=1;
		DS1302_CLK=0;
	}	
	DS1302_CLK=1;  //将时钟电平置于已知状态
	DS1302_RST=0;	//停止DS1302总线
	return temp;
}

//向DS1302写入时钟数据,用于时间校准修改
void DS1302_WriteTime() 
{
	DS1302_WriteByte(DS1302_CONTROL_ADDR,0x00);       //关闭写保护 
	DS1302_WriteByte(DS1302_SEC_ADDR,0x80);           //暂停时钟 
	//DS1302_WriteByte(DS1302_CHARGER_ADDR,0xa9);     //涓流充电 
	DS1302_WriteByte(DS1302_YEAR_ADDR,time_buf[1]);   //年 
	DS1302_WriteByte(DS1302_MONTH_ADDR,time_buf[2]);  //月 
	DS1302_WriteByte(DS1302_DAY_ADDR,time_buf[3]);    //日 
	DS1302_WriteByte(DS1302_HOUR_ADDR,time_buf[4]);   //时 
	DS1302_WriteByte(DS1302_MIN_ADDR,time_buf[5]);    //分
	DS1302_WriteByte(DS1302_SEC_ADDR,time_buf[6]);    //秒
	DS1302_WriteByte(DS1302_WEEK_ADDR,time_buf[7]);	  //周 
	DS1302_WriteByte(DS1302_CHARGER_ADDR,0xA5);//打开充电功能 选择2K电阻充电方式
	DS1302_WriteByte(DS1302_CONTROL_ADDR,0x80);//打开写保护     
}

//从DS1302读出时钟数据
void DS1302_ReadTime(void)  
{
	time_buf[1]=DS1302_ReadByte(DS1302_YEAR_ADDR);          //年 
	time_buf[2]=DS1302_ReadByte(DS1302_MONTH_ADDR);         //月 
	time_buf[3]=DS1302_ReadByte(DS1302_DAY_ADDR);           //日 
	time_buf[4]=DS1302_ReadByte(DS1302_HOUR_ADDR);          //时 
	time_buf[5]=DS1302_ReadByte(DS1302_MIN_ADDR);           //分 
	time_buf[6]=(DS1302_ReadByte(DS1302_SEC_ADDR))&0x7f;    //秒,屏蔽秒的第7位,避免超出59
	time_buf[7]=DS1302_ReadByte(DS1302_WEEK_ADDR);          //周 	
}

//主函数
void DS1302_GetTime(DS1302_Time_t* time)
{ 
    DS1302_ReadTime(); //读取时间
    time->year=(time_buf[0]>>4)*1000+(time_buf[0]&0x0F)*100+(time_buf[1]>>4)*10+(time_buf[1]&0x0F); //计算年份
    time->month=(time_buf[2]>>4)*10+(time_buf[2]&0x0F);  //计算月份
    time->day=(time_buf[3]>>4)*10+(time_buf[3]&0x0F);    //计算日期
    time->hour=(time_buf[4]>>4)*10+(time_buf[4]&0x0F);   //计算小时
    time->minute=(time_buf[5]>>4)*10+(time_buf[5]&0x0F); //计算分钟
    time->second=(time_buf[6]>>4)*10+(time_buf[6]&0x0F); //计算秒钟
    time->week=(time_buf[7]&0x0F);                       //计算星期
  //printf("时间:%d-%d-%d %d:%d:%d %d n",TimeData.year,TimeData.month,TimeData.day,TimeData.hour,TimeData.minute,TimeData.second,TimeData.week);																												
}

ds1302.h

参数定义

#ifndef __ds1302_H 
#define __ds1302_H  
 
#include "sys.h" 
/*
DS1302接口:
	VCC -> 5.0/3.3
	GND -> GND
	GPIOB_14 ->DS1302_RST
	GPIOB_13 ->DS1302_DAT
	GPIOB_12 ->DS1302_CLK
*/
/* 定义LED连接的GPIO端口, 用户只需要修改下面的代码即可改变控制的LED引脚 */
#define CE_GPIO_PORT    		GPIOB		              /* GPIO端口 */
#define CE_GPIO_CLK 	    	RCC_APB2Periph_GPIOB		/* GPIO端口时钟 */
#define CE_GPIO_PIN					GPIO_Pin_14			        /* 连接到SCL时钟线的GPIO */
#define SCLK__GPIO_PORT    	GPIOB		              /* GPIO端口 */
#define SCLK_GPIO_CLK 	    RCC_APB2Periph_GPIOB		/* GPIO端口时钟 */
#define SCLK__GPIO_PIN			GPIO_Pin_12			        /* 连接到SCL时钟线的GPIO */
#define DATA__GPIO_PORT    	GPIOB		              /* GPIO端口 */
#define DATA_GPIO_CLK 	    RCC_APB2Periph_GPIOB		/* GPIO端口时钟 */
#define DATA__GPIO_PIN			GPIO_Pin_13			        /* 连接到SCL时钟线的GPIO */

//DS1302引脚定义,可根据实际情况自行修改端口定义
//#define DS1302_OutPut_Mode() {GPIOB->CRL &= 0xF0FFFFFF;GPIOB->CRL |= 0x03000000;}//将 GPIOA 口的 PA6 引脚设置成推挽输出模式,并清空了其他引脚的配置
//#define DS1302_InPut_Mode()  {GPIOB->CRL &= 0xF0FFFFFF;GPIOB->CRL |= 0x08000000;}//PA7 引脚既可以作为普通的 GPIO 输出口

#define DS1302_IN  PBin(13)
#define DS1302_OUT PBout(13)
#define DS1302_RST PBout(14)
#define DS1302_CLK PBout(12)

typedef struct TIMEData
{
	u16 year;
	u8  month;
	u8  day;
	u8  hour;
	u8  minute;
	u8  second;
	u8  week;
}DS1302_Time_t;
//创建TIMEData结构体方便存储时间日期数据


void DS1302_Init(void);
void DS1302_WriteByte(u8 addr,u8 data);
u8   DS1302_ReadByte(u8 addr);
void DS1302_WriteTime(void);
void DS1302_ReadTime(void);
void DS1302_GetTime(DS1302_Time_t* time);

 
#endif

四、参考

基于STM32的DS1302时钟模块驱动程序icon-default.png?t=N7T8https://blog.csdn.net/qq_43270506/article/details/104952746?ops_request_misc=&request_id=&biz_id=102&utm_term=stmDS1302&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-4-104952746.142%5Ev96%5Epc_search_result_base7&spm=1018.2226.3001.4187

STM32基于标准库工程驱动DS1302icon-default.png?t=N7T8https://blog.csdn.net/weixin_42880082/article/details/129941871?ops_request_misc=&request_id=&biz_id=102&utm_term=stm%20DS1302&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~sobaiduweb~default-4-129941871.nonecase&spm=1018.2226.3001.4450


完整代码请关注公众号进行获取和咨询


联系方式 微信号:13648103287

  • 联系方式.docx

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
GS2962-IBE3 1 Gennum Corporation Consumer Circuit, PBGA100
$41.45 查看
SA605DK/01,112 1 NXP Semiconductors SA605 - High performance low power mixer FM IF system SSOP2 20-Pin
$5.47 查看
PGA2505IDBR 1 Texas Instruments Gain Range: 0dB, and 9dB to 60dB, in 3dB steps 24-SSOP -40 to 85

ECAD模型

下载ECAD模型
暂无数据 查看

相关推荐

电子产业图谱

方案定制,程序设计方案、单片机程序设计与讲解、APP定制开发。本公众号致力于向读者传递关于程序设计和开发的相关知识,并分享一些关于软件开发的最佳实践。如果您有什么问题或建议,请随时联系我们。我们将竭诚为您服务