STM32复习笔记(十二)RTC实时时钟(低功耗待机唤醒)

声明:本篇文章只是个人知识盲区、知识弱点、重点部分的归纳总结,望各位大佬不喜勿喷。梳理顺序是按照正点原子的视频和文档的实际顺序梳理,转载请注明出处。

作者:sumjess

适用:这个视频我已经看过3遍了,总会有忘记的,所以来写这本书的随手笔记,记录重点、易忘点。该博客可以当做字典,也可以当做笔记。

目前内容:RTC实时时钟(低功耗待机唤醒)

 

一、RTC实时时钟特征与原理:

★  RTC (Real Time Clock):实时时钟

★  RTC是个独立的定时器。RTC模块拥有一个连续计数的计数器,在相应的软件配置下,可以提供时钟日历的功能。修改计数器的值可以重新设置当前时间和日期。

★  RTC模块和时钟配置系统(RCC_BDCR寄存器)是在后备区域,即在系统复位或从待机模式唤醒后RTC的设置和时间维持不变。但是在系统复位后,会自动禁止访问后备寄存器和RTC,以防止对后备区域(BKP)的意外写操作。所以在要设置时间之前, 先要取消备份区域(BKP)写保护。

(1)RTC特征:

(2)RTC工作原理框图:

(3)RTC由两部分组成:

APB1接口:用来和APB1总线相连。通过APB1接口可以访问RTC的相关寄存器(预分频值,计数器值,闹钟值)。

RTC核心:由一组可编程计数器组成。分两个主要模块。

第一个是RTC预分频模块,它可以编程产生最长1秒的RTC时间基TR_CLK。如果设置了秒中断允许位,可以产生秒中断。

第二个是32位的可编程计数器,可被初始化为当前时间。系统时间按TR_CLK周期累加并与存储在RTC_ALR寄存器中的可编程时间相比,当匹配时候如果设置了闹钟中断允许位,可以产生闹钟中断。

RTC内核完全独立于APB1接口,软件通过APB1接口对RTC相关寄存器访问。但是相关寄存器只在RTC APB1时钟进行重新同步的RTC时钟的上升沿被更新。所以软件必须先等待寄存器同步标志位(RTC_CRLRSF位)被硬件置1才读。

二、RTC时钟源:

三、BKP备份寄存器:

备份寄存器是4216位的寄存器。可用来存储84个字节数据。

它们处在备份区域,当VDD电源切断,仍然由VBAT维持供电。

当系统在待机模式下被唤醒,或者系统复位或者电源复位,它们也不会复位。

执行以下操作将使能对后备寄存器和RTC访问:

设置寄存器RCC_APB1ENRPWRENBKPEN位,使能电源和后备时钟。

设置寄存器PWR_CRDBP位,使能对RTC和后备寄存器的访问。

提醒:一共有4216位备份寄存器。常用来保存一些系统配置信息和相关标志位。

四、RTC相关寄存器:

RTC控制寄存器             (RTC_CRH,   RTC_CRL)

RTC预分频装载寄存器  (RTC_PRLHRTC_PRLL)

RTC预分频余数寄存器  (RTC_DIVH,  RTC_DIVL)

RTC计数器寄存器         (RTC_CNTHRTC_CNTL)

RTC闹钟寄存器             (RTC_ALRH RTC_ALRL)

五、RTC控制寄存器高位(RTC_CRH):

                                

①修改CRH/CRL寄存器,必须先判断RSF位,确定已经同步。

②修改CNT,ALR,PRL的时候,必须先配置CNF位进入配置模式,修改完之后,设置CNF位为0退出配置模式

③同时在对RTC相关寄存器写操作之前,必须判断上一次写操作已经结束,也就是判断RTOFF位是否置位。

       

      

      

      

     

六、RTC相关库函数讲解:

库函数所在文件: stm32f10x_rtc.c / stm32f10x_rtc.h

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)//等待上次操作完成:CRLRTOFF

 void RTC_WaitForSynchro(void)//等待时钟同步:CRLRSF

相关状态位获取清除函数:

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();//使能PWRBKP时钟

RCC_LSEConfig();//开启LSERTC选择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

七、RTC配置一般步骤:

使能PWRBKP时钟:RCC_APB1PeriphClockCmd();

②  使能后备寄存器访问:   PWR_BackupAccessCmd();

③  配置RTC时钟源,使能RTC时钟:

      RCC_RTCCLKConfig();

      RCC_RTCCLKCmd();

      如果使用LSE,要打开LSERCC_LSEConfig(RCC_LSE_ON);

设置RTC预分频系数:RTC_SetPrescaler();

⑤ 设置时间:RTC_SetCounter();

⑥开启相关中断(如果需要):RTC_ITConfig()

⑦编写中断服务函数:RTC_IRQHandler();

⑧部分操作要等待写操作完成和同步。

   RTC_WaitForLastTask();//等待最近一次对RTC寄存器的写操作完成

   RTC_WaitForSynchro();  //等待RTC寄存器同步

八、待机唤醒

很多单片机有低功耗模式,STM32也不例外。在系统或者电源复位后,微控制器出于运行状态之下,HCLKCPU提供时钟,内核执行代码。当CPU不需要继续运行时,可以利用多种低功耗模式来节省功耗,例如等待某个事件触发。

九、STM323种低功耗模式:

睡眠模式:内核停止,外设如NVIC,系统时钟Systick仍运行。

停止模式:所有时钟都已停止。1.8V内核电源工作。

                         PLL,HISHSE RC振荡器功能禁止。

                         寄存器和SRAM内容保留。

待机模式:1.8V内核电源关闭。

                         只有备份寄存器和待机电路维持供电。

                         寄存器和SRAM内容全部丢失。实现最低功耗。

在运行模式下,可以通过下面方式降低功耗:

① 降低系统时钟。

② 关闭APBAHB总线上未被使用的外设时钟

用户根据最低电源消耗,最快启动时间和可用的唤醒源等条件,选择一种最佳的低功耗模式

待机模式理想状态下,只需要2uA电流。停机模式下典型电流为20uA

(1)PWR_CR电源控制寄存器:

设置PDDS位进入深度睡眠时进入待机模式。

设置CWUF位,清除之前的WUF唤醒位。

(2)PWR_CSR电源控制/状态寄存器:

① 设置EWUP,使能WKUP引脚用于待机模式唤醒。

WUF唤醒标志,用来判断是否发生唤醒事件。

十、固件库中低功耗操作函数:

文件:stm32f10x_pwr.c  / stm32f10x_pwr.h

 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); 

文件: core_cm3.h

__WFI() ;

__WFE() ;

十一、PWR_EnterSTANDBYMode函数:

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();//
} 

十二、PWR_EnterSTOPMode函数:

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_CSREWUP位,使能WK_UP用于将CPU从待机模式唤醒。

   PWR_WakeUpPinCmd(ENABLE);  //使能唤醒管脚功能

设置SLEEPDEEP位,设置PDDS位,执行WFI指令,进入待机模式。

   void PWR_EnterSTANDBYMode(void)

 

1设计要求 要求系统按如下方式进入和退出睡眠模式: 在系统启动2秒后,将RTC在3秒钟之后配置为产生一个报警事件,接着通过WFI指令使系统进入停机模式。 如果要唤醒系统到正常模式,可通过按Key按钮;否则,在3秒钟后,会产生RTC报警中断自动将系统唤醒。 一旦退出停机模式,系统时钟被配置成先前的状态(在停机模式下,外部高速振荡器HSE和PLL是不可用的)。 经过一段延时之后,系统将再次进入停机状态,并可按上述操作无限重复。 2 硬件电路设计 硬件电路采用与7.1小节应用实例一样硬件电路,可见图7-10。其中Key按钮用于通过PB9产生一个外部中断, LED1、LED2、LED3、LED4则用于显示处理器所处的模式和中断触发情况。 3 软件程序设计 根据任务要求,程序内容主要包括: (1) 配置GPIOB口,配置RTC,配置外部中断; (2) 配置PB口第9个引脚作为外部中断,下降延触发;配置RTC报警中断,上升沿触发; (3) 两个中断服务子程序的内容分别是:切换LED2和LED3灯的状态; 整个工程包含3个源文件:STM32F10x.s、stm32f10x_it.c和main.c,其中STM32F10x.s为启动代码,所有中断 服务子程序均在stm32f10x_it.c中,其它函数则在main.c中。下面分别介绍相关的函数,具体程序清单见参考程序。 函数SYSCLKConfig_STOP用于当处理器从停机模式唤醒之后,配置系统时钟、使能HSE和PLL,并以PLL作为系统时钟源。当处理器处理停机模式的时候,HSE、PLL是不可用的。 函数GPIO_Configuration用于配置GPIO的PC6、PC7、PC8、PC9和PB9。 函数EXTI_Configuration用于配置外部中断线9(PB9)和17(RTC报警)。 函数NVIC_Configuration配置NVIC及中断向量表,这里主要是配置外部中断线9和17。 函数EXTI9_5_IRQHandler处理按钮Key(PB9)所触发的中断,其主要作用是将LED2灯的状态翻转一次。 函数RTCAlarm_IRQHandler处理RTC报警所触发的中断,其主要作用事将LED3 灯的状态翻转一次,如果设置了唤醒标志则清除之。 运行过程: (1) 使用Keil uVision3 通过ULINK 2仿真器连接EduKit-M3实验平台,打开实验例程目录PWR_TEST子目录下的PWR.Uv2 例程,编译链接工程; (2) 选择软件调试模式,点击MDK 的Debug菜单,选择Start/Stop Debug Session项或Ctrl+F5键,在逻 辑分析仪中添加GPIOC_ODR.6、GPIOC_ODR.7、GPIOC_ODR.8、GPIOC_ODR.9,点击Run按钮即可在逻辑分析 仪中看到如图7-14,还可用Peripherals-General Port-GPIOB来模拟KEY按钮的动作; (3) 选择硬件调试模式,选择Start/Stop Debug Session项或Ctrl+F5键,下载程序并运行,观察LED灯 的变化情况。注意,当目标系统进入停机模式之后,将无法使用仿真器进行调试了; (4) 退出Debug模式,打开Flash菜单>Download,将程序下载到EduKit-M3实验平台的Flash中,按RESET键复位,观察 LED灯的情况,正常情况应为:系统处于运行模式时LED1亮、LED4灭;系统处于停机状态时LED1灭、LED4亮; 当按下KEY按钮时LED2灯状态发生反转;当发生RTC报警时LED3状态发生反转。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值