STM32CubeMX(stm32L151C8T6) 之RTC闹钟唤醒停机模式

基本知识介绍

1、37kHz低速内部RC,可以用于驱动独立看门狗和通过程序选择驱动RTC。 RTC用于从停机/
待机模式下自动唤醒系统
2、LSI时钟
LSI RC担当一个低功耗时钟源的角色,它可以在停机和待机模式下保持运行,为独立看门狗和
自动唤醒单元提供时钟。 LSI时钟频率大约40kHz(在30kHz和60kHz之间)。
3、LSI RC可以通过控制/状态寄存器(RCC_CSR)里的LSION位来启动或关闭。
4、注意: 只有大容量和互联型产品可以进行LSI校准

低功耗模式

在系统或电源复位以后,微控制器处于运行状态。当CPU不需继续运行时,可以利用多种低功
耗模式来节省功耗,例如等待某个外部事件时。用户需要根据最低电源消耗、最快速启动时间
和可用的唤醒源等条件,选定一个最佳的低功耗模式。

STM32F10xxx有三种低功耗模式:

● 睡眠模式(Cortex™-M3内核停止,所有外设包括Cortex-M3核心的外设,如NVIC、系统时
钟(SysTick)等仍在运行)
● 停止模式(所有的时钟都已停止)
● 待机模式(1.8V电源关闭)
在这里插入图片描述

停止模式

	停止模式是在Cortex™-M3的深睡眠模式基础上结合了外设的时钟控制机制,在停止模式下电压
	调节器可运行在正常或低功耗模式。此时在1.8V供电区域的的所有时钟都被停止, PLL、 HSI和
	HSE RC振荡器的功能被禁止, SRAM和寄存器内容被保留下来。
	在停止模式下,所有的I/O引脚都保持它们在运行模式时的状态

进入停止模式

关于如何进入停止模式。
在停止模式下,通过设置电源控制寄存器(PWR_CR)的LPDS位使内部调节器进入低功耗模式,
能够降低更多的功耗。
如果正在进行闪存编程,直到对内存访问完成,系统才进入停止模式。
如果正在进行对APB的访问,直到对APB访问完成,系统才进入停止模式。
电源控制(PWR)
● 独立看门狗(IWDG):可通过写入看门狗的键寄存器或硬件选择来启动IWDG。一旦启动了
独立看门狗,除了系统复位,它不能再被停止。详见17.3节。
● 实时时钟(RTC):通过备份域控制寄存器 (RCC_BDCR)的RTCEN位来设置。
● 内部RC振荡器(LSI RC):通过控制/状态寄存器 (RCC_CSR)的LSION位来设置。
● 外部32.768kHz振荡器(LSE):通过备份域控制寄存器 (RCC_BDCR)的LSEON位设置。
在停止模式下,如果在进入该模式前ADC和DAC没有被关闭,那么这些外设仍然消耗电流。通
过设置寄存器ADC_CR2的ADON位和寄存器DAC_CR的ENx位为0可关闭这2个外设。
在这里插入图片描述
进入STOP模式,好像是手动进入的,RTC只是唤醒

待机模式

待机模式可实现系统的最低功耗。该模式是在Cortex-M3深睡眠模式时关闭电压调节器。整个
1.8V供电区域被断电。 PLL、 HSI和HSE振荡器也被断电。 SRAM和寄存器内容丢失。只有备份
的寄存器和待机电路维持供电。
可以通过设置独立的控制位,选择以下待机模式的功能:
● 独立看门狗(IWDG):可通过写入看门狗的键寄存器或硬件选择来启动IWDG。一旦启动了
独立看门狗,除了系统复位,它不能再被停止。详见17.3节。
● 实时时钟(RTC):通过备用区域控制寄存器(RCC_BDCR)的RTCEN位来设置。
● 内部RC振荡器(LSI RC):通过控制/状态寄存器(RCC_CSR)的LSION位来设置。
● 外部32.768kHz振荡器(LSE):通过备用区域控制寄存器(RCC_BDCR)的LSEON位设置。
退出待机模式
当一个外部复位(NRST引脚)、 IWDG复位、 WKUP引脚上的上升沿或RTC闹钟事件的上升沿发
生时(见图154: 简化的RTC框图),微控制器从待机模式退出。从待机唤醒后,除了电源控制/状
态寄存器(PWR_CSR)(见第4.4.2节),所有寄存器被复位。
从待机模式唤醒后的代码执行等同于复位后的执行(采样启动模式引脚、读取复位向量等)。 电源
控制/状态寄存器(PWR_CSR)(见第4.4.2节)将会指示内核由待机状态退出
在这里插入图片描述

低功耗模式下的自动唤醒(AWU)

RTC可以在不需要依赖外部中断的情况下唤醒低功耗模式下的微控制器(自动唤醒模式)。 RTC提
供一个可编程的时间基数,用于周期性从停止或待机模式下唤醒。通过对备份区域控制寄存器
(RCC_BDCR)的RTCSEL[1:0]位的编程,三个RTC时钟源中的二个时钟源可以选作实现此功
能。
● 低功耗32.768kHz外部晶振(LSE)
该时钟源提供了一个低功耗且精确的时间基准。 (在典型情形下消耗小于1µA)
● 低功耗内部RC振荡器(LSI RC)
使用该时钟源,节省了一个32.768kHz晶振的成本。但是RC振荡器将少许增加电源消耗。
为了用RTC闹钟事件将系统从停止模式下唤醒,必须进行如下操作:
● 配置外部中断线17为上升沿触发。
● 配置RTC使其可产生RTC闹钟事件。(其实就是闹钟事件)
如果要从待机模式中唤醒,不必配置外部中断线17。(但是好像用的就是中断线17)

开始深入学习
在这里插入图片描述
这里我们选用LSI,这个项目没有加外部低速时钟,

这里我还要使能中断
选择1HZ就是1s 如果你要5s唤醒一次只需要在wake up counter 填入 (5-1)
在这里插入图片描述

进入睡眠模式
WFI(等待中断) WFE (是等待事件)

接下来,我们看代码

先看看生成的rtc初始化代码,,这里面不用动都可以

/**
  ******************************************************************************
  * File Name          : RTC.c
  * Description        : This file provides code for the configuration
  *                      of the RTC instances.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "rtc.h"

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

RTC_HandleTypeDef hrtc;

/* RTC init function */
void MX_RTC_Init(void)
{
  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};

  /** Initialize RTC Only 
  */
  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  hrtc.Init.AsynchPrediv = 127;
  hrtc.Init.SynchPrediv = 255;
  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }

  /* USER CODE BEGIN Check_RTC_BKUP */
    
  /* USER CODE END Check_RTC_BKUP */

  /** Initialize RTC and set the Time and Date 
  */
  sTime.Hours = 0x8;
  sTime.Minutes = 0x0;
  sTime.Seconds = 0x0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  sDate.Month = RTC_MONTH_JANUARY;
  sDate.Date = 0x8;
  sDate.Year = 0x18;

  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
	//HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,0x32F2);
  /** Enable the WakeUp 
  */
  //修改这里就可以修改唤醒时间
  if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 4, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)
  {
    Error_Handler();
  }
		
}

void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
{

  if(rtcHandle->Instance==RTC)
  {
  /* USER CODE BEGIN RTC_MspInit 0 */

  /* USER CODE END RTC_MspInit 0 */
    /* RTC clock enable */
    __HAL_RCC_RTC_ENABLE();

    /* RTC interrupt Init */
    HAL_NVIC_SetPriority(RTC_WKUP_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn);
  /* USER CODE BEGIN RTC_MspInit 1 */

  /* USER CODE END RTC_MspInit 1 */
  }
}

void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle)
{

  if(rtcHandle->Instance==RTC)
  {
  /* USER CODE BEGIN RTC_MspDeInit 0 */

  /* USER CODE END RTC_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_RTC_DISABLE();

    /* RTC interrupt Deinit */
    HAL_NVIC_DisableIRQ(RTC_WKUP_IRQn);
  /* USER CODE BEGIN RTC_MspDeInit 1 */

  /* USER CODE END RTC_MspDeInit 1 */
  }
} 

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

接下来就是进入停止模式
进入之前需要把所有的io口设置成模拟输入,不然即使你进了停止模式,电流还是有300ua

	
	GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0 
                          |GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4 
                          |GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8 
                          |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
	
	 GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
	
	GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7 
                          |GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 
                          |GPIO_PIN_12|GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_1|GPIO_PIN_10 
                          |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 |GPIO_PIN_11
                          |GPIO_PIN_15|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5 
                          |GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
	
  HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON,PWR_STOPENTRY_WFI);  //直接进入停止模式,中断唤醒。然后时间到了就会唤醒

唤醒stop模式后,需要重新配置时钟,因为停止模式会关掉除低频时钟外的其他时钟,比如MSI、HSI、 HSE、 PPL这些,都会关闭。停止模式唤醒后,默认是用MSI时钟,假如你用的不是MSI,就要重新配置时钟。停止模式,就是让CPU停在那里,唤醒后,继续执行,所以配置时钟要放在停止模式函数的后面。这样就行了

SystemClock_Config();

因为上面我们把所有io的模式设置成了模拟输入,所以我们还得初始化io
//把使用到的外设io在初始化一遍

HAL_UART_MspInit(&huart1);
HAL_ADC_MspInit(&hadc);
HAL_SPI_MspInit(&hspi2);
MX_GPIO_Init();

就上面的所有设置我做到了 7ua 供大家参考
这里我还使用了nrf24l01
也把nrf24l04低功耗了,,,功耗也才7.9ua

//让他进入低功耗模式

HAL_GPIO_WritePin(NRF2401_CE_GPIOX,NRF2401_CE_PIN,0);
NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x02); 

但是光上面的两行代码,还不够,功耗还是有350ua 带pa的
还需要设置io口

GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_15|GPIO_PIN_14|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

多次尝试发现这么设置,才能把功耗降下去

这里STM32L151的软件我已经全部告知,不用谢

  • 7
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: STM32F103系列微控制器支持低功耗模式,其中停机模式是其中一种常见的低功耗模式停机模式可以使芯片进入非常低功耗状态,只保持RTC(实时时钟)和唤醒的工作。 下面是一个简单的STM32F103停机模式RTC唤醒的代码示例: 首先,需要进行相应的配置和初始化。在初始化阶段,需要设置RTC工作和时钟,同时配置唤醒。 ```c // 初始化RTC RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); PWR_BackupAccessCmd(ENABLE); RCC_LSEConfig(RCC_LSE_ON); while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET){} RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); RCC_RTCCLKCmd(ENABLE); RTC_WaitForSynchro(); RTC_WakeUpCmd(DISABLE); RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits); RTC_SetWakeUpCounter(0x0800); ``` 然后,在需要进入停机模式的地方,使用以下代码: ```c PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_StopEntry_WFI); ``` 当系统运行到这一行代码时,芯片进入停机模式。在停机模式下,除了RTC唤醒之外,所有的时钟和外设都被停止,电消耗非常低。 当满足唤醒条件时,RTC会自动唤醒芯片。例如,当定时器到达设定的唤醒时间时,芯片会被唤醒。然后,可以通过以下代码进行唤醒后的操作: ```c if (PWR_GetFlagStatus(PWR_FLAG_WU) != RESET) { PWR_ClearFlag(PWR_FLAG_WU); // 唤醒后的操作 } ``` 在操作完成后,程序即可继续正常运行。 以上就是一个简单的STM32F103停机模式RTC唤醒的代码示例。根据实际需求可能还需要对一些参数进行调整和优化,但基本的流程和原理是相同的。希望对您有所帮助。 ### 回答2: STM32F103系列微控制器支持RTC唤醒功能,可用于在停机模式下通过RTC中断来唤醒芯片并恢复正常运行。以下是一个简单的示例代码: 1. 配置RTC时钟和相关寄存器: ```c RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); // 使能PWR和BKP模块时钟 PWR_BackupAccessCmd(ENABLE); //允许访问后备寄存器 BKP_RTCOutputConfig(BKP_RTCOutputSource_None); //禁用RTC输出信号 BKP_RTCCLKConfig(BKP_RTCCLKSource_LSE); //配置RTC时钟为LSE(外部低速振荡器) RCC_LSEConfig(RCC_LSE_ON); //启动LSE时钟 while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); //等待LSE时钟稳定 RCC_RTCCLKCmd(ENABLE); //启动RTC时钟 RTC_WaitForSynchro(); //等待RTC寄存器同步 RTC_ITConfig(RTC_IT_WUT, ENABLE); //使能RTC唤醒中断 RTC_WakeUpCmd(ENABLE); //使能RTC唤醒功能 ``` 2. 配置RTC唤醒时间: ```c RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits); //配置RTC唤醒时钟为1 Hz(利用预分频器实现) RTC_SetWakeUpCounter(3600); //设置RTC唤醒时间间隔为1小时(1 Hz * 3600秒) ``` 3. 进入停机模式: ```c PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); //进入低功耗停机模式并等待唤醒 ``` 4. 唤醒处理: ```c void RTC_WKUP_IRQHandler(void) //RTC唤醒中断处理函数 { if (RTC_GetITStatus(RTC_IT_WUT) != RESET) { RTC_ClearITPendingBit(RTC_IT_WUT); //清除RTC唤醒中断标志位 // 执行唤醒时需要的操作 } } ``` 上述代码通过配置RTC时钟、设置RTC唤醒时间间隔以及使用低功耗停机模式来实现RTC唤醒功能。在进入停机模式后,当RTC唤醒定时器到达预定时间时,芯片将被唤醒并执行唤醒时需要的操作。 ### 回答3: 为了在STM32F103停机模式下通过RTC唤醒,我们需要进行以下步骤: 首先,需要配置RTC时钟唤醒时间。可以通过初始化RTC外设的时钟和配置RTC预分频器来实现RTC时钟的配置。然后,需要使用RTC的初始化函数来设置RTC时钟和时间格式。接着,我们可以配置RTC唤醒时间,即设置唤醒时间的秒数。这可以通过将RTC唤醒时间设置为相对于当前时间的秒数来实现。 其次,我们需要启用RTC唤醒功能以及配置RTC唤醒中断。可以通过设置RTC唤醒定时器和启用唤醒定时器来启用RTC唤醒功能。然后,通过配置RTC唤醒中断并使能RTC唤醒中断来配置RTC唤醒中断。通过这些配置,当唤醒时间到达时,RTC将会发出唤醒中断信号。 最后,需要配置STM32F103的电管理单元(PWR)。可以通过配置PWR寄存器来选择停机模式。在停机模式下,所有外设和主时钟将会关闭,但RTC唤醒系统仍然可以工作。为了使STM32F103进入停机模式,我们需要在代码中调用PWR_EnterSTOPMode函数,并设置参数以选择停机模式。 综上所述,通过配置RTC时钟唤醒时间、启用RTC唤醒功能和配置RTC唤醒中断、配置STM32F103的电管理单元,我们可以实现在STM32F103停机模式下通过RTC唤醒的代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值