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

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

  • 基本知识介绍
  • 低功耗模式
    • STM32F10xxx有三种低功耗模式:
    • 停止模式
    • 进入停止模式
    • 待机模式
  • 低功耗模式下的自动唤醒(AWU)

基本知识介绍

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电源关闭)
STM32CubeMX(stm32L151C8T6) 之RTC闹钟唤醒停机模式_第1张图片

停止模式

	停止模式是在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个外设。
STM32CubeMX(stm32L151C8T6) 之RTC闹钟唤醒停机模式_第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节)将会指示内核由待机状态退出
STM32CubeMX(stm32L151C8T6) 之RTC闹钟唤醒停机模式_第3张图片

低功耗模式下的自动唤醒(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)

开始深入学习
STM32CubeMX(stm32L151C8T6) 之RTC闹钟唤醒停机模式_第4张图片
这里我们选用LSI,这个项目没有加外部低速时钟,

这里我还要使能中断
选择1HZ就是1s 如果你要5s唤醒一次只需要在wake up counter 填入 (5-1)
STM32CubeMX(stm32L151C8T6) 之RTC闹钟唤醒停机模式_第5张图片

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

接下来,我们看代码

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

/**
  ******************************************************************************
  * File Name          : RTC.c
  * Description        : This file provides code for the configuration
  *                      of the RTC instances.
  ******************************************************************************
  * @attention
  *
  * 

© Copyright (c) 2020 STMicroelectronics. * All rights reserved.

* * 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的软件我已经全部告知,不用谢

你可能感兴趣的:(STM32)