APB1接口:用来和APB1总线相连。通过APB1接口可以访问RTC的相关寄存器(预分频值,计数器值,闹钟值)。
RTC核心:由一组可编程计数器组成。分两个主要模块。
①第一个是RTC预分频模块,它可以编程产生最长1秒的RTC时间基TR_CLK。如果设置了秒中断允许位,可以产生秒中断。
②第二个是32位的可编程计数器,可被初始化为当前时间。系统时间按TR_CLK周期累加并与存储在RTC_ALR寄存器中的可编程时间相比,当匹配时候如果设置了闹钟中断允许位,可以产生闹钟中断。
①备份寄存器是42个16位的寄存器。可用来存储84个字节数据。
②它们处在备份区域,当VDD电源切断,仍然由VBAT维持供电。
③当系统在待机模式下被唤醒,或者系统复位或者电源复位,它们也不会复位。
④执行以下操作将使能对后备寄存器和RTC访问:
设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备时钟。
设置寄存器PWR_CR的DBP位,使能对RTC和后备寄存器的访问。
提醒:一共有42个16位备份寄存器。常用来保存一些系统配置信息和相关标志位。
①RTC控制寄存器 (RTC_CRH, RTC_CRL)
②RTC预分频装载寄存器 (RTC_PRLH, RTC_PRLL)
③RTC预分频余数寄存器 (RTC_DIVH, RTC_DIVL)
④RTC计数器寄存器 (RTC_CNTH, RTC_CNTL)
⑤RTC闹钟寄存器 (RTC_ALRH ,RTC_ALRL)
①修改CRH/CRL寄存器,必须先判断RSF位,确定已经同步。
②修改CNT,ALR,PRL的时候,必须先配置CNF位进入配置模式,修改完之后,设置CNF位为0退出配置模式
③同时在对RTC相关寄存器写操作之前,必须判断上一次写操作已经结束,也就是判断RTOFF位是否置位。
void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState);
void RTC_EnterConfigMode(void);
void RTC_ExitConfigMode(void);
uint32_t RTC_GetCounter(void);
void RTC_SetCounter(uint32_t CounterValue);
void RTC_SetPrescaler(uint32_t PrescalerValue);
void RTC_SetAlarm(uint32_t AlarmValue);
uint32_t RTC_GetDivider(void);
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);
RTC时钟源和时钟操作函数:
void RCC_RTCCLKConfig(uint32_t CLKSource);//时钟源选择
void RCC_RTCCLKCmd(FunctionalState NewState)//时钟使能
RTC配置函数(预分频,计数值:
void RTC_SetPrescaler(uint32_t PrescalerValue);//预分频配置:PRLH/PRLL
void RTC_SetCounter(uint32_t CounterValue);//设置计数器值:CNTH/CNTL
void RTC_SetAlarm(uint32_t AlarmValue);//闹钟设置:ALRH/ALRL
RTC中断设置函数:
void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState);//CRH
RTC允许配置和退出配置函数:
void RTC_EnterConfigMode(void);//允许RTC配置 :CRL位 CNF
void RTC_ExitConfigMode(void);//退出配置模式:CRL位 CNF
同步函数:
void RTC_WaitForLastTask(void);//等待上次操作完成:CRL位RTOFF
void RTC_WaitForSynchro(void);//等待时钟同步:CRL位RSF
相关状态位获取清除函数:
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);
其他相关函数(BKP等)
PWR_BackupAccessCmd();//BKP后备区域访问使能
RCC_APB1PeriphClockCmd();//使能PWR和BKP时钟
RCC_LSEConfig();//开启LSE,RTC选择LSE作为时钟源
其他相关函数(BKP等)
PWR_BackupAccessCmd();//BKP后备区域访问使能
uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR);//读BKP寄存器
void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data);//写BKP
①使能PWR和BKP时钟:RCC_APB1PeriphClockCmd();
② 使能后备寄存器访问: PWR_BackupAccessCmd();
③ 配置RTC时钟源,使能RTC时钟:
RCC_RTCCLKConfig();
RCC_RTCCLKCmd();
如果使用LSE,要打开LSE:RCC_LSEConfig(RCC_LSE_ON);
④ 设置RTC预分频系数:RTC_SetPrescaler();
⑤ 设置时间:RTC_SetCounter();
⑥开启相关中断(如果需要):RTC_ITConfig();
⑦编写中断服务函数:RTC_IRQHandler();
⑧部分操作要等待写操作完成和同步。
RTC_WaitForLastTask();//等待最近一次对RTC寄存器的写操作完成
RTC_WaitForSynchro(); //等待RTC寄存器同步
很多单片机有低功耗模式,STM32也不例外。在系统或者电源复位后,微控制器出于运行状态之下,HCLK为CPU提供时钟,内核执行代码。当CPU不需要继续运行时,可以利用多种低功耗模式来节省功耗,例如等待某个事件触发。
① 睡眠模式:内核停止,外设如NVIC,系统时钟Systick仍运行。
② 停止模式:所有时钟都已停止。1.8V内核电源工作。
PLL,HIS和HSE RC振荡器功能禁止。
寄存器和SRAM内容保留。
③待机模式:1.8V内核电源关闭。
只有备份寄存器和待机电路维持供电。
寄存器和SRAM内容全部丢失。实现最低功耗。
在运行模式下,可以通过下面方式降低功耗:
① 降低系统时钟。
② 关闭APB和AHB总线上未被使用的外设时钟。
用户根据最低电源消耗,最快启动时间和可用的唤醒源等条件,选择一种最佳的低功耗模式
待机模式理想状态下,只需要2uA电流。停机模式下典型电流为20uA。
①设置PDDS位进入深度睡眠时进入待机模式。
②设置CWUF位,清除之前的WUF唤醒位。
① 设置EWUP,使能WKUP引脚用于待机模式唤醒。
② WUF唤醒标志,用来判断是否发生唤醒事件。
void PWR_EnterSTOPMode();//进入停机模式
void PWR_EnterSTANDBYMode(void);//进入待机模式
void PWR_WakeUpPinCmd(FunctionalState NewState);//使能Wakeup引脚唤醒
FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG);
void PWR_ClearFlag(uint32_t PWR_FLAG);
__WFI() ;
__WFE() ;
void PWR_EnterSTANDBYMode(void)
{
PWR->CR |= PWR_CR_CWUF; /* Clear Wake-up flag */
PWR->CR |= PWR_CR_PDDS; /* Select STANDBY mode */
/* Set SLEEPDEEP bit of Cortex System Control Register */
SCB->SCR |= SCB_SCR_SLEEPDEEP;
/* This option is used to ensure that store operations are completed */
#if defined ( __CC_ARM )
__force_stores();
#endif
/* Request Wait For Interrupt */
__WFI();//
}
void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)
{
uint32_t tmpreg = 0;
tmpreg = PWR->CR;
tmpreg &= CR_DS_MASK;
tmpreg |= PWR_Regulator;
PWR->CR = tmpreg;
SCB->SCR |= SCB_SCR_SLEEPDEEP;
if(PWR_STOPEntry == PWR_STOPEntry_WFI){
__WFI();
}else{
__WFE();
}
SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
}
①使能电源时钟。
因为要配置电源控制寄存器,所以必须先使能电源时钟。
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
②设置WK_UP引脚作为唤醒源。
设置PWR_CSR的EWUP位,使能WK_UP用于将CPU从待机模式唤醒。
PWR_WakeUpPinCmd(ENABLE); //使能唤醒管脚功能
③设置SLEEPDEEP位,设置PDDS位,执行WFI指令,进入待机模式。
void PWR_EnterSTANDBYMode(void);