读写备份寄存器BKP与实时时钟RTC

文章目录


读写备份寄存器

接线图

即接个3.3v的电源到VBT引脚

代码

代码效果:第一次写入备份寄存器,下载程序后再注释掉,再进行下载,之前写入的数据还会保存在备份寄存器中(还可以读到),并且复位键或拔掉主电源再插上数据也不会丢失,直到主电源备用电源同时不能供电数据才会消失

c 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"

uint16_t Data;
int main(void)
{
	OLED_Init();
	OLED_ShowChar(1,1,'z');
	
	// 打开PWR,BKP时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);
	
	// 使能PWR
	PWR_BackupAccessCmd(ENABLE);
	
	// 写备份寄存器
	//BKP_WriteBackupRegister(BKP_DR1,0X1234);
	
	// 读取备份寄存器
	Data = BKP_ReadBackupRegister(BKP_DR1);
	
	OLED_ShowHexNum(2,1,Data,4);
	while (1)
	{
		
	}
}

RTC实时时钟

接线图

代码

对RTC进行配置,保存于ThisRTC.c

c 复制代码
#include "stm32f10x.h"                  // Device header
#include <time.h>
struct ThisRTC_Time{
	uint16_t year;		// 年
	uint8_t month;		// 月
	uint8_t day;		// 日
	uint8_t hour;		// 时
	uint8_t min;		// 分
	uint8_t sec;		// 秒	
};
extern struct ThisRTC_Time ThisRTC_Time1;

void ThisRTC_Init(void){
	// 打开PWR,BKP时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);
	
	// 使能PWR
	PWR_BackupAccessCmd(ENABLE);
	// 如果备份寄存器数据丢失则重新初始化
	if(BKP_ReadBackupRegister(BKP_DR1) != 0X9999){
	
		// 启动LSE时钟源
		RCC_LSEConfig(RCC_LSE_ON);
		
		// 等待LSE启动完成
		while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)!=SET);
		
		// 选择RTC时钟源为LSE
		RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
		
		// 使能RTC时钟
		RCC_RTCCLKCmd(ENABLE);
		
		// 等待同步
		RTC_WaitForSynchro();
		// 等待上一步写操作完成
		RTC_WaitForLastTask();
		
		// 配置分频系数,自动进入配置模式并退出
		RTC_SetPrescaler(32768-1);
		// 等待上一步写操作完成
		RTC_WaitForLastTask();
		
		void ThisRTC_SetTime(void);
		ThisRTC_SetTime();
		
		// 写入备份寄存器
		BKP_WriteBackupRegister(BKP_DR1,0X9999);
	}else{
		// 等待同步
		RTC_WaitForSynchro();
		// 等待上一步写操作完成
		RTC_WaitForLastTask();
	}
	
}


void ThisRTC_SetTime(void){
	time_t time_cnt;
	struct tm time_date;
	time_date.tm_year = ThisRTC_Time1.year - 1900;
	time_date.tm_mon = ThisRTC_Time1.month - 1;
	time_date.tm_mday = ThisRTC_Time1.day;
	time_date.tm_hour = ThisRTC_Time1.hour;
	time_date.tm_min = ThisRTC_Time1.min;
	time_date.tm_sec = ThisRTC_Time1.sec;
	// 将日期类型转换为秒计数器类型,并设置为RTC时间
	time_cnt = mktime(&time_date) - 8 * 60 * 60;
	RTC_SetCounter(time_cnt);
	// 等待上一步写操作完成
	RTC_WaitForLastTask();
}


void ThisRTC_ReadTime(void){
	time_t time_cnt;
	struct tm time_date;
	time_cnt = RTC_GetCounter() + 8 * 60 * 60;	// 加时区偏移变为北京时间
	time_date = *localtime(&time_cnt);
	ThisRTC_Time1.year = time_date.tm_year + 1900;
	ThisRTC_Time1.month = time_date.tm_mon + 1;
	ThisRTC_Time1.day = time_date.tm_mday;
	ThisRTC_Time1.hour = time_date.tm_hour;
	ThisRTC_Time1.min = time_date.tm_min;
	ThisRTC_Time1.sec = time_date.tm_sec;
}

头文件ThisRTC.h声明

c 复制代码
#ifndef __THISRTC_H
#define __THISRTC_H
// 存放时间结构体
struct ThisRTC_Time{
	uint16_t year;	// 年
	uint8_t month;	// 月
	uint8_t day;		// 日
	uint8_t hour;		// 时
	uint8_t min;		// 分
	uint8_t sec;		// 秒	
};
struct ThisRTC_Time ThisRTC_Time1 = {2024,10,27,5,2,0};

void ThisRTC_Init(void);
void ThisRTC_SetTime(void);
void ThisRTC_ReadTime(void);


#endif

主函数内容

c 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "ThisRTC.h"

int main(void)
{
	OLED_Init();
	ThisRTC_Init();
	OLED_ShowString(1,1,"Date:XXXX-XX-XX");
	OLED_ShowString(2,1,"Time:XX:XX:XX");
	OLED_ShowString(3,1,"CNT :");
	OLED_ShowString(4,1,"DIV :");
	while (1)
	{
		ThisRTC_ReadTime();
		OLED_ShowNum(1,6,ThisRTC_Time1.year,4);
		OLED_ShowNum(1,11,ThisRTC_Time1.month,2);
		OLED_ShowNum(1,14,ThisRTC_Time1.day,2);
		OLED_ShowNum(2,6,ThisRTC_Time1.hour,2);
		OLED_ShowNum(2,9,ThisRTC_Time1.min,2);
		OLED_ShowNum(2,12,ThisRTC_Time1.sec,2);
		OLED_ShowNum(3,6,RTC_GetCounter(),10);
		OLED_ShowNum(4,6,RTC_GetDivider(),6);		// 余数寄存器
	}
}

相关推荐
.生产的驴2 小时前
React 路由权限跳转 Token判断 路由控制 登录状态控制
前端·javascript·react.js·ajax·前端框架·c#·ecmascript
BreezeJuvenile2 小时前
外设模块学习(11)——火焰传感器、光敏电阻传感器(STM32)
stm32·单片机·学习·火焰传感器·光敏电阻传感器
SunnyDays101110 小时前
如何使用 C# 将 CSV 数据轻松转换为 PDF
c#·csv转pdf
Big_潘大师10 小时前
C# 六自由度机械臂正反解计算
数学建模·机器人·c#·六自由度机械臂
我不是程序猿儿10 小时前
【C#】XtraMessageBox(DevExpress)与MessageBox(WinForms 标准库)的区别
开发语言·c#
偶尔的鼠标人11 小时前
Avalonia/WPF 打开子窗口,并且跨页面传值
c#·wpf·mvvm·avalonia
玖笙&11 小时前
✨WPF编程进阶【6.1】:图形原则(附源码)
c++·c#·wpf·visual studio
huoshan1234511 小时前
给旧版 .NET 也开一扇“私有之门”——ILAccess.Fody 实现原理与设计
c#·.net·fody·il·mono.cecil
纸照片12 小时前
WPF中为Button设置IsMouseOver和IsPressed事件中改变背景颜色不起作用
c#·.net·wpf
郭子涵本人12 小时前
51单片机(markdown格式阅读)
单片机·嵌入式硬件·51单片机