打印
[其他ST产品]

arm中断保护和恢复_STM32低功耗待机模式+RTC闹钟中断唤醒

[复制链接]
楼主: 远芳侵古道
手机看帖
扫描二维码
随时随地手机跟帖
41
远芳侵古道|  楼主 | 2023-8-27 15:09 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
3种模式的功耗
单片机最小系统电路功耗,不精确测量值

正常模式:10mA
睡眠模式:2mA
停机模式:20uA
待机模式:2uA
因不同型号,不同工艺差异,不同程序下功耗不同这里只能给出大概范围。

使用特权

评论回复
42
远芳侵古道|  楼主 | 2023-8-27 15:09 | 只看该作者
五、RTC实时时钟简介
STM32的RTC外设(Real Time Clock),实质是一个掉电后还继续运行的定时器。从定时器的角度来说,相对于通用定时器TIM外设,它十分简单,只有很纯粹的计时和触发中断的功能;但从掉电还继续运行的角度来说,它却是STM32中唯一一个具有如此强大功能的外设。所以RTC外设的复杂之处并不在于它的定时功能,而在于它掉电还继续运行的特性。

使用特权

评论回复
43
远芳侵古道|  楼主 | 2023-8-27 15:09 | 只看该作者
以上所说的掉电,是指主电源VDD断开的情况,为了RTC外设掉电继续运行,必须接上锂电池给STM32的RTC、备份发卡通过VBAT引脚供电。当主电源VDD有效时,由VDD给RTC外设供电;而当VDD掉电后,由VBAT给RTC外设供电。但无论由什么电源供电,RTC中的数据都保存在属于RTC的备份域中,若主电源Vpp和VBAT都掉电,那么备份域中保存的所有数据将丢失。备份域除了RTC模块的寄存器,还有42个16位的寄存器可以在VDD掉电的情况下保存用户程序的数据,系统复位或电源复位时,这些数据也不会被复位。

使用特权

评论回复
44
远芳侵古道|  楼主 | 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退出待机模式==。

使用特权

评论回复
45
远芳侵古道|  楼主 | 2023-8-27 15:09 | 只看该作者

使用特权

评论回复
46
远芳侵古道|  楼主 | 2023-8-27 15:09 | 只看该作者
框图中浅灰色的部分都是属于备份域的,在VDD掉电时可在VBAT的驱动下继续运行。这部分仅包括RTC的分频器,计数器,和闹钟控制器。==若VDD电源有效,RTC可以触发RTC Second(秒中断)、RTCOverflow(溢出事件)和RTCAlarm(闹钟中断)==。从结构图可以分析到,其中的定时器溢出事件无法被配置为中断。若STM32原本处于待机状态,可由闹钟事件或WKUP事件(外部唤醒事件,属于EXTI模块,不属于RTC)使它退出待机模式。闹钟事件是在计数器RTCCNT的值等于闹钟寄存器RTCALR的值时触发的。

使用特权

评论回复
47
远芳侵古道|  楼主 | 2023-8-27 15:10 | 只看该作者

在备份域中所有寄存器都是16位的,RTC控制相关的寄存器也不例外。它的计数器RTCCNT的32位由RTCCNTL和RTCCNTH两个寄存器组成,分别保存定时计数值的低16位和高16位。在配置RTC模块的时钟时,通常把输入的32768Hz的RTCCLK进行32768分频得到实际驱动计数器的时钟TR CLK=RTCCLK/32768=1Hz,计时周期为1秒,计时器在TR_CLK的驱动下计数,即每秒计数器RTC_CNT的值加1。

使用特权

评论回复
48
远芳侵古道|  楼主 | 2023-8-27 15:10 | 只看该作者
六、程序讲解
为了能够更加清楚地了解利用RTC闹钟中断唤醒待机模式,假设现在利用STM3进行超声波测距,当距离大于1米时,单片机进入休眠状态,10秒钟后RTC自动唤醒STM32继续测量。在一米范围内不休眠,一但距离大于1米就开始休眠,10秒后唤醒继续测量。

使用特权

评论回复
49
远芳侵古道|  楼主 | 2023-8-27 15:10 | 只看该作者
rtc.c
#include "sys.h"
#include "delay.h"
#include "rtc.h"
//实时时钟配置
//初始化RTC时钟,同时检测时钟是否工作正常
void RTC_Init()
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1Periph_PWR,ENABLE);//使能PWR和BKP外设时钟   
//默认情况下,RTC 所属的备份域禁止访问,可使用库函数 PWR_BackupAccessCmd 使能访问
PWR_BackupAccessCmd(ENABLE);//允许访问备份区域,后备区域解锁   
if(PWR_GetFlagStatus(PWR_FLAG_SB)!=RESET) //如果现在处于待机模式
{
  PWR_ClearFlag(PWR_FLAG_SB);             //清除待机模式
  RTC_ITConfig(RTC_IT_SEC, ENABLE);     //打开RTC中断
  RTC_WaitForSynchro();                   //等待RTC寄存器同步  
}
else
{
  BKP_DeInit();//复位备份区域 使用此函数必须调用RCC_APB1PeriphClockCmd()函数
  RCC_LSEConfig(RCC_LSE_ON);//设置外部低速晶振(LSE),外部32.768KHZ晶振开启
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) //等待稳定
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //设置RTC时钟(RTCCLK),选择LSE(晶振频率为 32.768KHz)作为RTC时钟   
  RCC_RTCCLKCmd(ENABLE);    //使能RTC时钟   
  RTC_WaitForLastTask();   //等待RTC寄存器同步,因为RTC时钟是低速的,内环时钟是高速的,所以要同步
  RTC_WaitForSynchro();     //写寄存器之前要确保上一次RTC的操作完成
  //下面这两条语句是开启RTC秒中断的函数,每过1秒钟产生一次中断,就进入了中断服务函数
  RTC_ITConfig(RTC_IT_SEC, ENABLE);//使能RTC秒中断
  RTC_WaitForLastTask();           //确保上一次 RTC 的操作完成  
  
  RTC_EnterConfigMode();    //进入RTC配置模式
  RTC_SetCounter(0);        //初始值设定为0s 在使用本函数前必须先调用函数RTC_WaitForLastTask();等待标志位RTOFF被设置
  RTC_WaitForLastTask();  
  
  RTC_SetPrescaler(32767);  //设置RTC分频: 使 RTC周期为1s  RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) = 1HZ 在使用本函数前必须先调用函数RTC_WaitForLastTask();等待标志位RTOFF被设置
  RTC_WaitForLastTask();    //确保上一次 RTC 的操作完成
  RTC_ExitConfigMode();     //退出RTC 配置模式
}
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;  
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
NVIC_Init(&NVIC_InitStructure);  

}
void RTC_IRQHandler()
{
    if(RTC_GetITStatus(RTC_IT_SEC)!=RESET)  //是否秒中断发生
{  
  printf("Time is  =%d rn",RTC_GetCounter()); //输出此时的秒数
}
RTC_WaitForLastTask();
RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW); //清除秒中断标志位和溢出位
}

使用特权

评论回复
50
远芳侵古道|  楼主 | 2023-8-27 15:10 | 只看该作者
rtc.h
#ifndef __RTC_H
#define __RTC_H
#include "sys.h"

void RTC_Init(void);

#endif

使用特权

评论回复
51
远芳侵古道|  楼主 | 2023-8-27 15:10 | 只看该作者
main.c
int main(void)
{
  int Distance_data=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //NVIC优先级分组2
delay_init();                                   //延时函数初始化
uart_init(115200);                              //串口1初始化 PA9-RX PA10-TX
LED_Init();                                  //LED端口初始化
Beep_Init();                              //BEEP端口初始化
OLED_Init() ;                                   //OLED端口初始化
RTC_Init();
while(1)
{
     Distance_data=Ultrasonic_Ranging();
  if(Distance_data>=1500)
  {
   printf("进入休眠!n");
   RTC_SetAlarm(RTC_GetCounter()+10); //闹钟在此时刻加上10秒
   RTC_WaitForLastTask();             //等待最近一次对RTC寄存器的写操作完成
   PWR_EnterSTANDBYMode();            //进入待机(STANDBY)模式   
  }
}
}

使用特权

评论回复
52
chenqianqian| | 2024-5-10 07:54 | 只看该作者
ST的低功耗模式设计还是很合理

使用特权

评论回复
53
Bowclad| | 2024-5-12 23:30 | 只看该作者
rtc是怎么触发中断的啊

使用特权

评论回复
54
帛灿灿| | 2024-9-16 07:04 | 只看该作者

如果在编程时加密锁定位被使能/锁定,就无法用普通编程器直接读取单片机内的程序

使用特权

评论回复
55
Bblythe| | 2024-9-16 08:07 | 只看该作者

编程器定位插字节

使用特权

评论回复
56
童雨竹| | 2024-9-16 10:03 | 只看该作者

缩短距离较近的电容的寿命

使用特权

评论回复
57
Pulitzer| | 2024-9-16 11:06 | 只看该作者

利用协议、加密算法或这些算法中的安全漏洞来进行攻击

使用特权

评论回复
58
童雨竹| | 2024-9-16 13:02 | 只看该作者

大地的地会通过散热器(用绝缘体与漏极隔开)从这些节点获取能量

使用特权

评论回复
59
Wordsworth| | 2024-9-16 14:05 | 只看该作者

具存储功能的存储器芯片也能加密

使用特权

评论回复
60
Clyde011| | 2024-9-16 15:08 | 只看该作者

紫外光复位保护电路是不行的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则