赞
踩
BKP控制寄存器用来备份、管理侵入检测和RTC校准功能
- /*备份寄存器访问使能*/
- PWR_BackupAccessCmd(ENABLE); //使用PWR开启对备份寄存器的访问
实时时钟是一个独立的定时器。 RTC 模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。RTC 模块和时钟配置系统 (RCC_BDCR 寄存器 ) 处于后备区域,即在系统复位或从待机模式唤醒 后,RTC 的设置和时间维持不变。系统复位后,对后备寄存器和 RTC 的访问被禁止,这是为了防止对后备区域 (BKP) 的意外写操作。
RTC虽然有三种时钟源,不过只能选 LSE 时钟,因为只有它才能起到断电后会借助VBAT供电
执行以下操作将使能对后备寄存器和RTC的访问:
RTC由两个主要部分组成
由一组可编程计数器组成,分成两个主要模块。
RTC_Second为秒中断,用于刷新时间,
RTC_Overflow是溢出中断。
RTC Alarm 控制开关机
1、执行以下操作将使能对BKP和RTC的访问:
2、若在读取RTC寄存器时,RTC的APB1接口曾经处于禁止状态,则软件首先必须等待 RTC_CRL寄存器中的RSF位(寄存器同步标志)被硬件置1(库函数RTC等待同步)
3、必须设置 RTC_CRL 寄存器中的 CNF 位,使 RTC 进入配置模式后,才能写入 RTC_PRL、RTC_CNT、RTC_ALR寄存器
4、对RTC任何寄存器的写操作,都必须在前一次写操作结束后进行。可以通过查询RTC_CR寄存器中的RTOFF状态位,判断RTC寄存器是否处于更新中。仅当RTOFF状态位是1时,才可以写入RTC寄存器 (调用一个等待函数)
- /**
- * 函 数:RTC初始化
- * 参 数:无
- * 返 回 值:无
- */
- void MyRTC_Init(void)
- {
- /*开启时钟*/
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //开启PWR的时钟
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE); //开启BKP的时钟
-
- /*备份寄存器访问使能*/
- PWR_BackupAccessCmd(ENABLE); //使用PWR开启对备份寄存器的访问
-
- if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
- //通过写入备份寄存器的标志位,判断RTC是否是第一次配置
- //if成立则执行第一次的RTC配置
- {
- RCC_LSEConfig(RCC_LSE_ON); //开启LSE时钟
- while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET); //等待LSE准备就绪
-
- RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //选择RTCCLK来源为LSE
- RCC_RTCCLKCmd(ENABLE); //RTCCLK使能
-
- RTC_WaitForSynchro(); //等待同步
- RTC_WaitForLastTask(); //等待上一次操作完成
-
- RTC_SetPrescaler(32768 - 1); //设置RTC预分频器,预分频后的计数频率为1Hz
- RTC_WaitForLastTask(); //等待上一次操作完成
-
- MyRTC_SetTime(); //设置时间,调用此函数,全局数组里时间值刷新到RTC硬件电路
-
- BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
- //在备份寄存器写入自己规定的标志位,用于判断RTC是不是第一次执行配置
- }
- else //RTC不是第一次配置
- {
- RTC_WaitForSynchro(); //等待同步
- RTC_WaitForLastTask(); //等待上一次操作完成
- }
- }
如果LSE无法起振导致程序卡死在初始化函数中,
可将初始化函数替换为下述代码,使用LSI当作RTCCLK
LSI无法由备用电源供电,故主电源掉电时,RTC走时会暂停
- void MyRTC_Init(void)
- {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);
-
- PWR_BackupAccessCmd(ENABLE);
-
- if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
- {
- RCC_LSICmd(ENABLE);
- while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) != SET);
-
- RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
- RCC_RTCCLKCmd(ENABLE);
-
- RTC_WaitForSynchro();
- RTC_WaitForLastTask();
-
- RTC_SetPrescaler(40000 - 1);
- RTC_WaitForLastTask();
-
- MyRTC_SetTime();
-
- BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
- }
- else
- {
- RCC_LSICmd(ENABLE); //即使不是第一次配置,也需要再次开启LSI时钟
- while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) != SET);
-
- RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
- RCC_RTCCLKCmd(ENABLE);
-
- RTC_WaitForSynchro();
- RTC_WaitForLastTask();
- }
- }
以后自己画板子,此电路是个不错备份参考电路
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。