22_BKP备份寄存器&RTC实时时钟

BKP备份寄存器&RTC实时时钟

BKP简介

image-20240306202613421

BKP基本结构

image-20240306231540821

一个数据寄存器存2字节

RTC简介

image-20240306232021063

image-20240307000643329

选LSE的32.768kHZ的时钟频率,因为支持VBAT供电

RTC框图

image-20240307000914341

RTC基本结构

image-20240307002601240

硬件电路

image-20240307002847010

供电方案

image-20240307005142467

RTC操作注意事项

image-20240307010110852

读写备份寄存器

接线图

image-20240307012022331

代码

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"


int main(void)
{
	OLED_Init();
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
	
	PWR_BackupAccessCmd(ENABLE); //使能对BKP和RTC的访问
	
	BKP_WriteBackupRegister(BKP_DR1,0x1234);
	OLED_ShowHexNum(1,1,BKP_ReadBackupRegister(BKP_DR1),4);
	
	while(1)
	{
		
	}
}

RTC实时时钟

接线图

image-20240307154232991

代码

MyRTC.c

#include "stm32f10x.h"                  // Device header
#include <time.h>
#include "MyRTC.h"

uint16_t MyRTC_Time[]={2023,1,1,23,59,55};

void MyRTC_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
	
	PWR_BackupAccessCmd(ENABLE);
	
	if(BKP_ReadBackupRegister(BKP_DR1)!=0xA5A5)
	{
		RCC_LSEConfig(RCC_LSE_ON);
		while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)!=SET);
		RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
		RCC_RTCCLKCmd(ENABLE);
		
		RTC_WaitForSynchro(); //等待同步
		RTC_WaitForLastTask(); //等待上一次写入操作完成
		
		RTC_SetPrescaler(32768-1); //分频
		RTC_WaitForLastTask();
		
		MyRTC_SetTime();
		
		BKP_WriteBackupRegister(BKP_DR1,0xA5A5);
	}
	else
	{
		RTC_WaitForSynchro(); //等待同步
		RTC_WaitForLastTask(); //等待上一次写入操作完成
	}
}

void MyRTC_SetTime(void)
{
	time_t time_cnt;
	struct tm time_date;
	time_date.tm_year=MyRTC_Time[0]-1900;
	time_date.tm_mon=MyRTC_Time[1]-1;
	time_date.tm_mday=MyRTC_Time[2];
	time_date.tm_hour=MyRTC_Time[3];
	time_date.tm_min=MyRTC_Time[4];
	time_date.tm_sec=MyRTC_Time[5];
	
	time_cnt=mktime(&time_date); //秒数
	
	RTC_SetCounter(time_cnt-8*60*60);
	RTC_WaitForLastTask();
}

void MyRTC_ReadTime(void)
{
	time_t time_cnt;
	struct tm time_date;
	
	time_cnt=RTC_GetCounter()+8*60*60; //转成北京时区
	
	time_date=*localtime(&time_cnt);
	
	MyRTC_Time[0]=time_date.tm_year+1900;
	MyRTC_Time[1]=time_date.tm_mon+1;
	MyRTC_Time[2]=time_date.tm_mday;
	MyRTC_Time[3]=time_date.tm_hour;
	MyRTC_Time[4]=time_date.tm_min;
	MyRTC_Time[5]=time_date.tm_sec;
	
}

MyRTC.h

#ifndef __MYRTC_H__
#define __MYRTC_H__

extern uint16_t MyRTC_Time[];

void MyRTC_Init(void);
void MyRTC_SetTime(void);
void MyRTC_ReadTime(void);

#endif

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyRTC.h"

int main(void)
{
	OLED_Init();
	MyRTC_Init();
	OLED_ShowString(1,1,"Data:xxxx-xx-xx");
	OLED_ShowString(2,1,"Time:xx:xx:xx");
	OLED_ShowString(3,1,"CNT :");
	OLED_ShowString(4,1,"DIV :");
	while(1)
	{
		MyRTC_ReadTime();
		OLED_ShowNum(1,6,MyRTC_Time[0],4);
		OLED_ShowNum(1,11,MyRTC_Time[1],2);
		OLED_ShowNum(1,14,MyRTC_Time[2],2);
		OLED_ShowNum(2,6,MyRTC_Time[3],2);
		OLED_ShowNum(2,9,MyRTC_Time[4],2);
		OLED_ShowNum(2,12,MyRTC_Time[5],2);
		OLED_ShowNum(3,6,RTC_GetCounter(),10);
		OLED_ShowNum(4,6,RTC_GetDivider(),10);
	}
}
posted @ 2024-03-07 19:50  爱吃冰激凌的黄某某  阅读(15)  评论(0编辑  收藏  举报