[其他ST产品] arm中断保护和恢复_STM32低功耗待机模式+RTC闹钟中断唤醒

[复制链接]
3428|63
 楼主| 远芳侵古道 发表于 2023-8-27 15:09 | 显示全部楼层
3种模式的功耗
单片机最小系统电路功耗,不精确测量值

正常模式:10mA
睡眠模式:2mA
停机模式:20uA
待机模式:2uA
因不同型号,不同工艺差异,不同程序下功耗不同这里只能给出大概范围。
 楼主| 远芳侵古道 发表于 2023-8-27 15:09 | 显示全部楼层
五、RTC实时时钟简介
STM32的RTC外设(Real Time Clock),实质是一个掉电后还继续运行的定时器。从定时器的角度来说,相对于通用定时器TIM外设,它十分简单,只有很纯粹的计时和触发中断的功能;但从掉电还继续运行的角度来说,它却是STM32中唯一一个具有如此强大功能的外设。所以RTC外设的复杂之处并不在于它的定时功能,而在于它掉电还继续运行的特性。
 楼主| 远芳侵古道 发表于 2023-8-27 15:09 | 显示全部楼层
以上所说的掉电,是指主电源VDD断开的情况,为了RTC外设掉电继续运行,必须接上锂电池给STM32的RTC、备份发卡通过VBAT引脚供电。当主电源VDD有效时,由VDD给RTC外设供电;而当VDD掉电后,由VBAT给RTC外设供电。但无论由什么电源供电,RTC中的数据都保存在属于RTC的备份域中,若主电源Vpp和VBAT都掉电,那么备份域中保存的所有数据将丢失。备份域除了RTC模块的寄存器,还有42个16位的寄存器可以在VDD掉电的情况下保存用户程序的数据,系统复位或电源复位时,这些数据也不会被复位。
 楼主| 远芳侵古道 发表于 2023-8-27 15:09 | 显示全部楼层
从RTC的定时器特性来说,它是一个32位的计数器,只能向上计数。它使用的时钟源有三种,分别为高速外部时钟的128分频(HSE/128)、低速内部时钟LSI以及低速外部时钟LSE;使HSE分频时钟或LSI的话,在主电源VDD掉电的情况下,这两个时钟来源都会受到影响,因此没法保证RTC正常工作。因此RTC一般使用低速外部时钟LSE,在设计中,频率通常为实时时钟模块中常用的32.768KHz,这是因为32768=2^15,分频容易实现,所以它被广泛应用到RTC模块。==在主电源Vpp有效的情况下(待机),RTC还可以配置闹钟事件使STM32退出待机模式==。
 楼主| 远芳侵古道 发表于 2023-8-27 15:09 | 显示全部楼层
 楼主| 远芳侵古道 发表于 2023-8-27 15:09 | 显示全部楼层
框图中浅灰色的部分都是属于备份域的,在VDD掉电时可在VBAT的驱动下继续运行。这部分仅包括RTC的分频器,计数器,和闹钟控制器。==若VDD电源有效,RTC可以触发RTC Second(秒中断)、RTCOverflow(溢出事件)和RTCAlarm(闹钟中断)==。从结构图可以分析到,其中的定时器溢出事件无法被配置为中断。若STM32原本处于待机状态,可由闹钟事件或WKUP事件(外部唤醒事件,属于EXTI模块,不属于RTC)使它退出待机模式。闹钟事件是在计数器RTCCNT的值等于闹钟寄存器RTCALR的值时触发的。
 楼主| 远芳侵古道 发表于 2023-8-27 15:10 | 显示全部楼层
7284964eaf6c4be45f.png
在备份域中所有寄存器都是16位的,RTC控制相关的寄存器也不例外。它的计数器RTCCNT的32位由RTCCNTL和RTCCNTH两个寄存器组成,分别保存定时计数值的低16位和高16位。在配置RTC模块的时钟时,通常把输入的32768Hz的RTCCLK进行32768分频得到实际驱动计数器的时钟TR CLK=RTCCLK/32768=1Hz,计时周期为1秒,计时器在TR_CLK的驱动下计数,即每秒计数器RTC_CNT的值加1。
 楼主| 远芳侵古道 发表于 2023-8-27 15:10 | 显示全部楼层
六、程序讲解
为了能够更加清楚地了解利用RTC闹钟中断唤醒待机模式,假设现在利用STM3进行超声波测距,当距离大于1米时,单片机进入休眠状态,10秒钟后RTC自动唤醒STM32继续测量。在一米范围内不休眠,一但距离大于1米就开始休眠,10秒后唤醒继续测量。
 楼主| 远芳侵古道 发表于 2023-8-27 15:10 | 显示全部楼层
rtc.c
  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "rtc.h"
  4. //实时时钟配置
  5. //初始化RTC时钟,同时检测时钟是否工作正常
  6. void RTC_Init()
  7. {
  8. NVIC_InitTypeDef NVIC_InitStructure;
  9. RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1Periph_PWR,ENABLE);//使能PWR和BKP外设时钟   
  10. //默认情况下,RTC 所属的备份域禁止访问,可使用库函数 PWR_BackupAccessCmd 使能访问
  11. PWR_BackupAccessCmd(ENABLE);//允许访问备份区域,后备区域解锁   
  12. if(PWR_GetFlagStatus(PWR_FLAG_SB)!=RESET) //如果现在处于待机模式
  13. {
  14.   PWR_ClearFlag(PWR_FLAG_SB);             //清除待机模式
  15.   RTC_ITConfig(RTC_IT_SEC, ENABLE);     //打开RTC中断
  16.   RTC_WaitForSynchro();                   //等待RTC寄存器同步  
  17. }
  18. else
  19. {
  20.   BKP_DeInit();//复位备份区域 使用此函数必须调用RCC_APB1PeriphClockCmd()函数
  21.   RCC_LSEConfig(RCC_LSE_ON);//设置外部低速晶振(LSE),外部32.768KHZ晶振开启
  22.   while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) //等待稳定
  23.   RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //设置RTC时钟(RTCCLK),选择LSE(晶振频率为 32.768KHz)作为RTC时钟   
  24.   RCC_RTCCLKCmd(ENABLE);    //使能RTC时钟   
  25.   RTC_WaitForLastTask();   //等待RTC寄存器同步,因为RTC时钟是低速的,内环时钟是高速的,所以要同步
  26.   RTC_WaitForSynchro();     //写寄存器之前要确保上一次RTC的操作完成
  27.   //下面这两条语句是开启RTC秒中断的函数,每过1秒钟产生一次中断,就进入了中断服务函数
  28.   RTC_ITConfig(RTC_IT_SEC, ENABLE);//使能RTC秒中断
  29.   RTC_WaitForLastTask();           //确保上一次 RTC 的操作完成  
  30.   
  31.   RTC_EnterConfigMode();    //进入RTC配置模式
  32.   RTC_SetCounter(0);        //初始值设定为0s 在使用本函数前必须先调用函数RTC_WaitForLastTask();等待标志位RTOFF被设置
  33.   RTC_WaitForLastTask();  
  34.   
  35.   RTC_SetPrescaler(32767);  //设置RTC分频: 使 RTC周期为1s  RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) = 1HZ 在使用本函数前必须先调用函数RTC_WaitForLastTask();等待标志位RTOFF被设置
  36.   RTC_WaitForLastTask();    //确保上一次 RTC 的操作完成
  37.   RTC_ExitConfigMode();     //退出RTC 配置模式
  38. }
  39. NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;  
  40. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  41. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  42. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  43. NVIC_Init(&NVIC_InitStructure);  

  44. }
  45. void RTC_IRQHandler()
  46. {
  47.     if(RTC_GetITStatus(RTC_IT_SEC)!=RESET)  //是否秒中断发生
  48. {  
  49.   printf("Time is  =%d rn",RTC_GetCounter()); //输出此时的秒数
  50. }
  51. RTC_WaitForLastTask();
  52. RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW); //清除秒中断标志位和溢出位
  53. }
 楼主| 远芳侵古道 发表于 2023-8-27 15:10 | 显示全部楼层
rtc.h
  1. #ifndef __RTC_H
  2. #define __RTC_H
  3. #include "sys.h"

  4. void RTC_Init(void);

  5. #endif
 楼主| 远芳侵古道 发表于 2023-8-27 15:10 | 显示全部楼层
main.c
  1. int main(void)
  2. {
  3.   int Distance_data=0;
  4. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //NVIC优先级分组2
  5. delay_init();                                   //延时函数初始化
  6. uart_init(115200);                              //串口1初始化 PA9-RX PA10-TX
  7. LED_Init();                                  //LED端口初始化
  8. Beep_Init();                              //BEEP端口初始化
  9. OLED_Init() ;                                   //OLED端口初始化
  10. RTC_Init();
  11. while(1)
  12. {
  13.      Distance_data=Ultrasonic_Ranging();
  14.   if(Distance_data>=1500)
  15.   {
  16.    printf("进入休眠!n");
  17.    RTC_SetAlarm(RTC_GetCounter()+10); //闹钟在此时刻加上10秒
  18.    RTC_WaitForLastTask();             //等待最近一次对RTC寄存器的写操作完成
  19.    PWR_EnterSTANDBYMode();            //进入待机(STANDBY)模式   
  20.   }
  21. }
  22. }
chenqianqian 发表于 2024-5-10 07:54 来自手机 | 显示全部楼层
ST的低功耗模式设计还是很合理
Bowclad 发表于 2024-5-12 23:30 | 显示全部楼层
rtc是怎么触发中断的啊
帛灿灿 发表于 2024-9-16 07:04 | 显示全部楼层

如果在编程时加密锁定位被使能/锁定,就无法用普通编程器直接读取单片机内的程序
Bblythe 发表于 2024-9-16 08:07 | 显示全部楼层

编程器定位插字节
童雨竹 发表于 2024-9-16 10:03 | 显示全部楼层

缩短距离较近的电容的寿命
Pulitzer 发表于 2024-9-16 11:06 | 显示全部楼层

利用协议、加密算法或这些算法中的安全漏洞来进行攻击
童雨竹 发表于 2024-9-16 13:02 | 显示全部楼层

大地的地会通过散热器(用绝缘体与漏极隔开)从这些节点获取能量
Wordsworth 发表于 2024-9-16 14:05 | 显示全部楼层

具存储功能的存储器芯片也能加密
Clyde011 发表于 2024-9-16 15:08 | 显示全部楼层

紫外光复位保护电路是不行的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部