STM32F103和DS1302时钟

news/2024/11/18 22:30:23/

STM32F103和DS1302时钟

  • DS1302模块讲解
  • 源文件演示
      • 源文件下载链接


最近在写了一些关于STM32F103C8T6对于模块的时候方面的代码的整合,想把之前用到的代码全部都整合成一个一个的例程来,以后要用直接拖进来改头文件的引脚口就好了。现在也开启第一章关于DS1302模块的使用的来。

DS1302模块讲解

DS1302时钟模块是时钟模块主要的实现方法简单来说就是通过协议往DS1302芯片内的存储空间里面写入当前时间。

然后模块上面自带晶振计数,所以可以实现模块里面的时钟一直在走,然后用一个纽扣电池为整个模块供电,即使单片机重启或者关闭电源还是有纽扣电池提供电力让其继续计时。

读取数据的时候只需要根据协议的方式读取芯片内计时的时间即可了。

芯片的引脚说明
在这里插入图片描述
VCC1和VCC2:都是电源脚只是供电的方式问题
X1和X2:晶振电路的引脚用来根据晶振的次数来记录时间
SCLK:单片机和DS1302芯片的时钟线
RST:从低到高的一个上升沿开始允许写数据,拉低RST端则禁止读写数据
I/O(DATA):数据线用来数据的读取或者写入
GND:地线

源文件演示

源文件下载链接

https://download.csdn.net/download/qq_45488746/85280373

贴点演示代码吧,大家关注比较多的也是怎么去实现需要的功能。

主函数

#include "sys.h"
#include "led.h"
#include "ds1302.h"
#include "usart.h"
#include "delay.h"#define Printf_EN 1
/*系统功能:RTC时钟时间:2022/05/04设备:STM32F103C8T6、DS1302时钟、USB转TTL接线:USB转TTLPA9	---- RXPA10---- TXDS1302:PA5----RSTPA6----DATAPA7----SCK*/
extern struct TIMEData TimeData;int main(void)
{	u8 i = 0;delay_init();	    	 	//延时函数初始化	  NVIC_Configuration(); 	 	//设置NVIC中断分组2:2位抢占优先级,2位响应优先级 	LED_Init();			     	//LED端口初始化uart_init(115200);DS1302_Init();				//引脚口初始化		
//	DS1302_WriteTime();			//第一次向DS1302芯片写入时间printf("DS1302初始化成功\r\n");while(1) {		i++;if(i == 200){i=0;LED_Pout = !LED_Pout;//系通功能运行DS1302_GetTime();#if Printf_ENprintf("时间:%d-%d-%d %d:%d:%d %d \r\n",TimeData.year,TimeData.month,TimeData.day,TimeData.hour,TimeData.minute,TimeData.second,TimeData.week);	#endif}delay_ms(5);}		}

部分ds1302.c,主要是根据DS1302芯片的通信方式用代码去实现,代码中有部分是参考别人的代码去实现的,当然不可能重头造轮子啦。

//DS1302初始化函数
void DS1302_Init() 
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin = RST_Pin; 				//RSTGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	//推挽输出GPIO_Init(RST_GPIO, &GPIO_InitStructure);			//初始化GPIO_ResetBits(RST_GPIO,RST_Pin); GPIO_InitStructure.GPIO_Pin = SCLK_Pin; 			//SCLKGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	//推挽输出GPIO_Init(SCLK_GPIO, &GPIO_InitStructure);			//初始化GPIO_ResetBits(SCLK_GPIO,SCLK_Pin);  
}//向DS1302写入一字节数据
void DS1302_WriteByte(u8 addr,u8 data) 
{u8 i;DS1302_RST=0; //禁止数据传输 !!!这条很重要DS1302_CLK=0; //确保写数据前SCLK为低电平DS1302_RST=1;	//启动DS1302总线	DS1302_OutPut_Mode();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总线DS1302_OutPut_Mode();//写入目标地址:addraddr=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读出数据:tempDS1302_InPut_Mode();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位,避免超出59time_buf[7]=DS1302_ReadByte(DS1302_WEEK_ADDR);          //周 	
}//DS1302获取完时间后进行数据的计算
void DS1302_GetTime()
{ DS1302_ReadTime(); //读取时间TimeData.year	=(time_buf[0]>>4)*1000	+(time_buf[0]&0x0F)*100+(time_buf[1]>>4)*10+(time_buf[1]&0x0F); //计算年份TimeData.month	=(time_buf[2]>>4)*10	+(time_buf[2]&0x0F);  	//计算月份TimeData.day	=(time_buf[3]>>4)*10	+(time_buf[3]&0x0F);    //计算日期TimeData.hour	=(time_buf[4]>>4)*10	+(time_buf[4]&0x0F);   	//计算小时TimeData.minute	=(time_buf[5]>>4)*10	+(time_buf[5]&0x0F); 	//计算分钟TimeData.second	=(time_buf[6]>>4)*10	+(time_buf[6]&0x0F); 	//计算秒钟TimeData.week	=(time_buf[7]&0x0F);                       		//计算星期																										
}

ds1302.h
主要也都是根据DS1302芯片资料上面的芯片内部地址做一些宏定义,方便操作

//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#define DS1302_IN  PAin(6)
#define DS1302_OUT PAout(6)
#define DS1302_RST PAout(5)
#define DS1302_CLK PAout(7)#define RST_GPIO	GPIOA
#define RST_Pin		GPIO_Pin_5#define SCLK_GPIO	GPIOA
#define SCLK_Pin	GPIO_Pin_7#define DATA_GPIO	GPIOA
#define DATA_Pin	GPIO_Pin_6struct TIMEData
{u16 year;u8  month;u8  day;u8  hour;u8  minute;u8  second;u8  week;
};
extern struct TIMEData TimeData;
extern u8 readtime[15];
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(void);

http://www.ppmy.cn/news/894762.html

相关文章

STM32利用I2C驱动SSD1306代码

前言&#xff1a; 之前购买了一款SSD1306驱动的0.96inchOLED显示屏幕&#xff0c;采用ESP8266使用u8g2库成功驱动。如今想自己摸索一下如何利用I2C驱动SSD1306. I2C协议 I2C开始 SCL为高电平期间&#xff0c;SDA由高到低 void IIC_START()//IIC_SCL高电平时候 IIC_SDA拉低 {I…

GD32E103/F303系列替换STM32F103

注&#xff1a;本文档仅针对GD32E103/F303系列替代STM32F103系列 版权&#xff1a;威尔健科技有限公司 联系方式&#xff1a;18816824119&#xff08;微信同号&#xff09; 本人&#xff1a;GD技术支持 明&#xff1a;GD32E103/GD32F10x/GD32F30x都是和STM32F10x系列是完全P…

stm32F103驱动lcd1602

接线 GPIOG0-7&#xff1a;D0-D7 RS&#xff1a;GPIOD13 RW&#xff1a;GPIOD14 EN&#xff1a;GPIOD15 程序 lcd.h #ifndef _lcd_H #define _lcd_H #include "stm32f10x.h" #include "SysTick.h"#define RS GPIO_Pin_13 #define RW GPIO_Pin_14 #d…

STM32F103-LCD1602驱动

STM32驱动LCD1602&#xff0c;不是很难&#xff0c;主要注意GPIO_Write(GPIOD,(GPIO_ReadOutputData(GPIOD) & 0xff00) | cmd);对电平的读取是整个驱动的核心&#xff0c;其他均与51驱动一致。 lcd.h文件 #ifndef __LCD_H__ #define __LCD_H__ #include "stm3…

stm32f103

配置:PLLCLK 32 参考电路图stlink与正点原子的接口连的时候,注意板子上接口实际正反是反的 蓝牙模块 一 蓝牙的AT指令模式 注意EN要接3.3v/EN什么都不接,长按蓝牙按钮的同时然后再上电. 慢闪是AT模式,快闪是透传模式. 指令集: AT //返回OK ATNAME? //返回蓝牙模块的名字…

【mcuclub】时钟模块DS1302

一、实物图 二、原理图 编号名称功能1VCC2双供电配置中的主电源供应引脚。DS1302工作于 VCC1和VCC2中较大者.当VCC2比VCC1高0.2V 时&#xff0c;VCC2 给 DS1302供电。当VCC1比VCC2高时, VCC1给DS1302供电2X132.768kHz晶振引脚3X24GND电源地5CE使能引脚。输入信号&#xff0c;在…

STM32F103操作DS1302时钟芯片串口显示(标准库和HAL库)

目录 DS1302的性能指标 DS1302的寄存器及片内RAM 标准库实现 HAL库实现 源码链接 单片机型号&#xff1a;STM32F103C8T6 在日常生活中&#xff0c;很多情况下会需要使用时间&#xff0c;单片机中虽然也是有定时器但并不能较为准备的实现计时功能&#xff0c;而且定时计时…

高等数学❤️第一章~第二节~极限❤️极限的概念与性质~函数极限(自变量趋于有限值时的极限)详解

【精讲】高等数学中函数极限&#xff1a;自变量趋于有限值时的极限 博主&#xff1a;命运之光的主页 专栏&#xff1a;高等数学 目录 【精讲】高等数学中函数极限&#xff1a;自变量趋于有限值时的极限 导言 二、函数极限自变量趋于有限值的判定方法 三、函数极限自变量趋于…