一、简介
二、BKP
三、BKP库函数
void BKP_DeInit(void);//回复初始配置,全部置零
void BKP_TamperPinLevelConfig(uint16_t BKP_TamperPinLevel);//高电平还是低电平触发
void BKP_TamperPinCmd(FunctionalState NewState);//配置侵入检测功能
void BKP_ITConfig(FunctionalState NewState);//中断功能配置
void BKP_RTCOutputConfig(uint16_t BKP_RTCOutputSource);//时钟输出配置
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);//中断标志位相关函数
void PWR_BackupAccessCmd(FunctionalState NewState);//使能对BKP的访问
四、BKP代码实现
uint16_t ArrayWrite[] = {0x1234, 0x0713 };
uint16_t ArrayRead[2];
int main(void)
{
KEY_Init();
OLED_Init();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//BKP备用电源掉电会被清除
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);//以上初始化BKP
OLED_ShowString(1, 1, "W:");
OLED_ShowString(2, 1, "R:");
while(1)
{
uint8_t KeyNum = KEY_GETNUM();
if (KeyNum == 1)
{
ArrayWrite[0] ++;
ArrayWrite[1] ++;
BKP_WriteBackupRegister(BKP_DR1, ArrayWrite[0]);//写入bkpDR寄存器
BKP_WriteBackupRegister(BKP_DR2, ArrayWrite[1]);//写入bkpDR寄存器
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);
}
}
五、实时时钟
1.库函数
void RCC_LSEConfig(uint8_t RCC_LSE);//开启LSE外部时钟
void RCC_LSICmd(FunctionalState NewState);//配置LSI低速内部时钟
void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);//选择RTCCLK时钟源
void RCC_RTCCLKCmd(FunctionalState NewState);//启动RTCCLK
FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG);//获取RCC标志位,确定时钟启动完成
void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState);//配置中断输出
void RTC_EnterConfigMode(void);//进入配置模式,CNF位置一
void RTC_ExitConfigMode(void);//推出配置模式,CNF位清零
uint32_t RTC_GetCounter(void);//读取时钟
void RTC_SetCounter(uint32_t CounterValue);//写入CNT计数器的值,设置时间
void RTC_SetPrescaler(uint32_t PrescalerValue);//写入预分频器
void RTC_SetAlarm(uint32_t AlarmValue);//写入闹钟值
uint32_t RTC_GetDivider(void);//读取DIV余数寄存器,为了确定更精确的时间
void RTC_WaitForLastTask(void);//等待上次操作完成
void RTC_WaitForSynchro(void);//等待同步
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);//清除中断标志位
2.实时时钟模块
#include "stm32f10x.h" // Device header
#include <time.h>
uint16_t MyRTC_Time[] = {2024, 9, 17, 14, 03, 55};
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) - 8 * 60 * 60;//把结构体的地址传进去,设置时间,同时进行日期时间到秒数的转化
RTC_SetCounter(time_cnt);//将秒数发送给CNT计数器
RTC_WaitForLastTask();//等待写入完成
}
void MyRTC_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//开启PWR时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);//开启BKP时钟
PWR_BackupAccessCmd(ENABLE);//使能BKP
if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
{
RCC_LSEConfig(RCC_LSE_ON);//启动LSE时钟
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) != 1);//等待LSE启动完成
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//选择时钟
RCC_RTCCLKCmd(ENABLE);//启动时钟
RTC_WaitForSynchro();//等待同步
RTC_WaitForLastTask();//等待任务完成
RTC_SetPrescaler(32768 - 1);//进行1分频
RTC_WaitForLastTask();//等待写入完成
MyRTC_SetTime();
BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
}
else
{
RTC_WaitForSynchro();//等待同步
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;
}