32RTC&BKP

目录

一.时间戳

二.BKP简介

三.RTC外设简介

​编辑四.相关寄存器

五.相关函数

六.代码实现

(1)读写备份寄存器

(2)实时时钟


一.时间戳

最早在Unix系统上使用

Linux,Windos,安卓的底层计时系统

好处:

1.简化硬件电路,直接采样一个秒寄存器来进行存储

2.在进行一些时间间隔的计算时非常方便

3.存储较方便,一个变量即可

但比较占用软件资源,需要进行秒分时年月日计算

STM32内部定义的变量、是一个无符号的32为整形数据,可以持续到2106年

每次产生闰秒时,时间戳的时间和标准时间会产生一秒的偏差

二.BKP简介

后备寄存器

VBAT(V Battery)备用电池电源

TAMPER引脚,对应PC-13-TAMPER-RTC,对应PC13引脚,可以用于设计侵入检测功能

校准时钟可以对内部RTC微小误差进行校准,可以配合校准寄存器

闹钟脉冲或者秒脉冲,可以输出为其他设备提供信号

三.RTC外设简介

在51中,DS1302是外设的 RTC芯片,可以进行独立计时

而在STM32内部,具有RTC外设

高速时钟供内部程序运行和主要外设使用

低速时钟供RTC,看门狗使用,LSE时钟为了省电默认是关闭的

四.相关寄存器

设计成16位可以简化电路设计

五.相关函数

BKP

cpp 复制代码
void BKP_TamperPinLevelConfig(uint16_t BKP_TamperPinLevel);//高低电平是否触发TAMPER侵入检测功能
void BKP_TamperPinCmd(FunctionalState NewState);//是否开启TAMPER侵入检测功能
void BKP_ITConfig(FunctionalState NewState);//是否开启中断
void BKP_RTCOutputConfig(uint16_t BKP_RTCOutputSource);//RTC时钟输出功能配置
void BKP_SetRTCCalibrationValue(uint8_t CalibrationValue);//设置RTC校准值
void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data);//写备份寄存器
uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR);//读备份寄存器
FlagStatus BKP_GetFlagStatus(void);
void BKP_ClearFlag(void);
ITStatus BKP_GetITStatus(void);
void BKP_ClearITPendingBit(void);

PWR

cpp 复制代码
void PWR_BackupAccessCmd(FunctionalState NewState);//备份寄存器使能,设置DBP

rcc.h

cpp 复制代码
void RCC_LSEConfig(uint8_t RCC_LSE);//配置LSE外部低速时钟
void RCC_LSICmd(FunctionalState NewState);//配置LSI内部低速时钟
void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);//选择时钟源
void RCC_RTCCLKCmd(FunctionalState NewState);//使能

FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG);//LSE启动标志位

rtc.h

cpp 复制代码
void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState);
void RTC_EnterConfigMode(void);//进入配置模式,设置CNF位
void RTC_ExitConfigMode(void);//退出配置模式,将CNF位清零
uint32_t  RTC_GetCounter(void);//获取CNT计数器值
void RTC_SetCounter(uint32_t CounterValue);//写入CNT计数器值
void RTC_SetPrescaler(uint32_t PrescalerValue);//写入预分频器(PRL)
void RTC_SetAlarm(uint32_t AlarmValue);//写入闹钟值
uint32_t  RTC_GetDivider(void);//读取预分频器中的DIV余数寄存器,可以获取比秒更加精确的时间
void RTC_WaitForLastTask(void);//等待上次操作的完成,等待RTOFF为1
void RTC_WaitForSynchro(void);//等待同步,RSF为1
FlagStatus RTC_GetFlagStatus(uint16_t RTC_FLAG);
void RTC_ClearFlag(uint16_t RTC_FLAG);
ITStatus RTC_GetITStatus(uint16_t RTC_IT);
void RTC_ClearITPendingBit(uint16_t RTC_IT);

六.代码实现

(1)读写备份寄存器

main.c

cpp 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"  
#include "OLED.h" 
#include "Key.h"
uint16_t ArrayWrite[] = {0x1234,0x5678};
uint16_t ArrayRead[2];
uint8_t Num;

int main(void)
{
	OLED_Init();
	Key_Init();
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
	
	PWR_BackupAccessCmd(ENABLE);
	OLED_ShowString(1,1,"W:");
	OLED_ShowString(2,1,"R:");

	while(1)
	{
		Num = Keynum();
		if(Num == 1)
		{
			ArrayWrite[0]++;
			ArrayWrite[1]++;
			
			BKP_WriteBackupRegister(BKP_DR1,ArrayWrite[0]);
			BKP_WriteBackupRegister(BKP_DR2,ArrayWrite[1]);
			
			OLED_ShowHexNum(1,3,ArrayWrite[0],4);
			OLED_ShowHexNum(1,8,ArrayWrite[1],4);
			
			ArrayRead[0] = BKP_ReadBackupRegister(BKP_DR1);
			ArrayRead[1] = BKP_ReadBackupRegister(BKP_DR2);			
		}
		
		OLED_ShowHexNum(2,3,ArrayRead[0],4);
		OLED_ShowHexNum(2,8,ArrayRead[1],4);

		
	}	
}
	

(2)实时时钟

MyRTC.c

cpp 复制代码
#include "stm32f10x.h"                  // Device header
#include <time.h>
uint16_t Mytime[6] = {2024,2,20,23,59,55};

void MyRTC_SET(void);

void MyRTC_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
	
	PWR_BackupAccessCmd(ENABLE);
	
	if(BKP_ReadBackupRegister(BKP_DR1) != 0x12)
	{
		RCC_LSEConfig(RCC_LSE_ON);
		while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);
		
		RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//需要选择LSE时钟
		RCC_RTCCLKCmd(ENABLE);
	
		RTC_WaitForLastTask();
		RTC_WaitForSynchro();
	
		RTC_SetPrescaler(32768 - 1);
		RTC_WaitForLastTask();
		MyRTC_SET();
		BKP_WriteBackupRegister(BKP_DR1,0x12);
	}
	else
	{
		RTC_WaitForLastTask();
		RTC_WaitForSynchro();
	}
	
}
void MyRTC_SET(void)//输入北京时间,转化为伦敦时间
{
	time_t time_cnt;
	struct tm time_st;
	time_st.tm_year =Mytime[0]-1900;
	time_st.tm_mon =Mytime[1]-1;
	time_st.tm_mday = Mytime[2];
	time_st.tm_hour =Mytime[3];
	time_st.tm_min = Mytime[4];
	time_st.tm_sec =Mytime[5] ;
	time_cnt = mktime(&time_st) - 8*60*60;
	RTC_SetCounter(time_cnt);
	RTC_WaitForLastTask();
}
void MyRTC_READ(void)//读取伦敦时间,转换为北京时间
{
	time_t time_cnt;
	struct tm time_st;
	time_cnt = RTC_GetCounter() + 8*60*60;
	time_st = *localtime(&time_cnt);
	Mytime[0]=time_st.tm_year+1900;
	Mytime[1]=time_st.tm_mon+1;
	Mytime[2]=time_st.tm_mday;
	Mytime[3]=time_st.tm_hour;
	Mytime[4]=time_st.tm_min;
	Mytime[5]=time_st.tm_sec;
	
}

main.c

cpp 复制代码
#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,"    -  -  ");
	OLED_ShowString(2,1,"  :  :  ");
	OLED_ShowString(3,1,"CNT:");
	OLED_ShowString(4,1,"DIV:");
	while(1)
	{
		MyRTC_READ();
		OLED_ShowNum(1,1,Mytime[0],4);
		OLED_ShowNum(1,6,Mytime[1],2);
		OLED_ShowNum(1,10,Mytime[2],2);
		OLED_ShowNum(2,1,Mytime[3],2);
		OLED_ShowNum(2,4,Mytime[4],2);
		OLED_ShowNum(2,7,Mytime[5],2);
		OLED_ShowNum(3,5,RTC_GetCounter(),10);
		OLED_ShowNum(4,5,(32767-RTC_GetDivider())/32767.0*999,10);//需要加上小数点
		//可以读取DIV,对其进行线性变换,读取任意时刻的毫秒

		
	}	
}
	
相关推荐
BreezeJuvenile2 小时前
外设模块学习(5)——DS18B20温度传感器(STM32)
stm32·嵌入式硬件·学习·温度传感器·ds18b20
hollq4 小时前
STM32F103RCT6+STM32CubeMX+keil5(MDK-ARM)+Flymcu实现串口重定向
arm开发·stm32·嵌入式硬件
小鱼儿电子6 小时前
17-基于STM32的宠物饲养系统设计与实现
stm32·嵌入式硬件·物联网·宠物·宠物饲养系统
小莞尔7 小时前
【51单片机】【protues仿真】基于51单片机四层电梯系统
单片机·嵌入式硬件
CFZPL7 小时前
使用江科大串口发送函数发送freertos的vTaskList出现跑飞
单片机
F133168929578 小时前
WD5030A,24V降5V,15A 大电流,应用于手机、平板、笔记本充电器
stm32·单片机·嵌入式硬件·51单片机·硬件工程·pcb工艺
易享电子9 小时前
基于单片机电器断路器保护器系统Proteus仿真(含全部资料)
单片机·嵌入式硬件·fpga开发·51单片机·proteus
爱倒腾的老唐12 小时前
01、如何学习单片机
单片机·嵌入式硬件·学习
点灯小铭12 小时前
基于单片机的夹具压力控制系统设计
单片机·嵌入式硬件·mongodb·毕业设计·课程设计
雾削木18 小时前
stm32解锁芯片
javascript·stm32·单片机·嵌入式硬件·gitee