一,电源管理库函数
前面的入门文章对 STM32 的超低功耗的做了使用介绍,当然在使用超低功耗的时候还会考虑 RAM 的数据会不会丢失,什么时候重写 备份寄存器,进入低功耗模式的时候要怎么保持 IO 的状态,本篇文章就带来这些的介绍。
二,电源管理的 API
ST 的 HAL 库做了很全面的低功耗相关的 API , 知道这些函数的作用,掌握这些函数的作用,就会对超低功耗有了进一步的认识。
-
复位电源管理寄存器
void HAL_PWR_DeInit(void)
复位电源管理寄存器,将他们设置到默认重置值,复位之后将导致外设无法正常工作。具体的复位值可以在手册上看到。
例如下图:
这里的复位值是 0x0000 0200 也就是 bit9 为 1, 其他位全部为 0.
bit9 的电源范围是 RANGE1 -
备份域是否可访问
可访问备份域:void HAL_PWR_EnableBkUpAccess(void)
使能之后,RTC 寄存器 RTC 备份数据寄存器是可以访问的,也就是可以进行写操作
不可访问备份域:void HAL_PWR_DisableBkUpAccess(void)
关闭之后 备份域的数据将不能够再改变 -
配置电压检测的阈值
在 STM32L4 系列的 MCU 中支持电压阈值的检测,检测到异常之后会触发一个中断PVD_PVM_IRQHandler
, 这个 PVD(Power Voltage Detector) 是可以配置的,配置函数:
HAL_StatusTypeDef HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD)
typedef struct
{
uint32_t PVDLevel; /*!< PVDLevel: Specifies the PVD detection level.
This parameter can be a value of @ref PWR_PVD_detection_level. */
uint32_t Mode; /*!< Mode: Specifies the operating mode for the selected pins.
This parameter can be a value of @ref PWR_PVD_Mode. */
}PWR_PVDTypeDef;
通过上面的结构体可以知道,实际上就是配置了 2 个参数。
PVDLevel 可以配置的值参考手册:
mode 可以配置成 4 种模式:
- PVD_MODE_IT : 外部中断
- PVD_MODE_EVT : 内部事件
- PVD_RISING_EDGE : 上升沿触发
- PVD_FALLING_EDGE : 下降沿触发
完成上面的配置之后,还要调用使能的函数之后,以上的配置才会生效:
使能函数:void HAL_PWR_EnablePVD(void)
失能函数:void HAL_PWR_DisablePVD(void)
- 唤醒引脚的配置
在 MCU 进入低功耗模式之后可以通过特定的 I/O(唤醒引脚) , 来实现唤醒 MCU,这些引脚是固定不可复用。
这些引脚只有在使能之后才能有唤醒 MCU 的能力。
使能唤醒引脚:void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity)
可设置的值如下:
#define PWR_WAKEUP_PIN1_HIGH PWR_CR3_EWUP1 /*!< Wakeup pin 1 (with high level polarity) */
#define PWR_WAKEUP_PIN2_HIGH PWR_CR3_EWUP2 /*!< Wakeup pin 2 (with high level polarity) */
#define PWR_WAKEUP_PIN3_HIGH PWR_CR3_EWUP3 /*!< Wakeup pin 3 (with high level polarity) */
#define PWR_WAKEUP_PIN4_HIGH PWR_CR3_EWUP4 /*!< Wakeup pin 4 (with high level polarity) */
#define PWR_WAKEUP_PIN5_HIGH PWR_CR3_EWUP5 /*!< Wakeup pin 5 (with high level polarity) */
#define PWR_WAKEUP_PIN1_LOW (uint32_t)((PWR_CR4_WP1<<PWR_WUP_POLARITY_SHIFT) | PWR_CR3_EWUP1) /*!< Wakeup pin 1 (with low level polarity) */
#define PWR_WAKEUP_PIN2_LOW (uint32_t)((PWR_CR4_WP2<<PWR_WUP_POLARITY_SHIFT) | PWR_CR3_EWUP2) /*!< Wakeup pin 2 (with low level polarity) */
#define PWR_WAKEUP_PIN3_LOW (uint32_t)((PWR_CR4_WP3<<PWR_WUP_POLARITY_SHIFT) | PWR_CR3_EWUP3) /*!< Wakeup pin 3 (with low level polarity) */
#define PWR_WAKEUP_PIN4_LOW (uint32_t)((PWR_CR4_WP4<<PWR_WUP_POLARITY_SHIFT) | PWR_CR3_EWUP4) /*!< Wakeup pin 4 (with low level polarity) */
#define PWR_WAKEUP_PIN5_LOW (uint32_t)((PWR_CR4_WP5<<PWR_WUP_POLARITY_SHIFT) | PWR_CR3_EWUP5) /*!< Wakeup pin 5 (with low level polarity) */
失能唤醒引脚:void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
失能之后,该引脚将不再具备唤醒 MCU 的能力
可设置的值如下:
#define PWR_WAKEUP_PIN1 PWR_CR3_EWUP1 /*!< Wakeup pin 1 (with high level polarity) */
#define PWR_WAKEUP_PIN2 PWR_CR3_EWUP2 /*!< Wakeup pin 2 (with high level polarity) */
#define PWR_WAKEUP_PIN3 PWR_CR3_EWUP3 /*!< Wakeup pin 3 (with high level polarity) */
#define PWR_WAKEUP_PIN4 PWR_CR3_EWUP4 /*!< Wakeup pin 4 (with high level polarity) */
#define PWR_WAKEUP_PIN5 PWR_CR3_EWUP5 /*!< Wakeup pin 5 (with high level polarity) */
注意:我使用的 L433RC 没有 WAKEUP_PIN3
-
进入睡眠模式
这里的进入的睡眠模式包含了普通的睡眠模式和低功耗睡眠模式
void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
Regulator : 电压域的选择。可选择的有两个,PWR_MAINREGULATOR_ON 和 PWR_LOWPOWERREGULATOR_ON。很明显的能知道是进入的哪个睡眠模式
SLEEPEntry : 睡眠模式进入的方式。两个选项,PWR_SLEEPENTRY_WFI 和 PWR_SLEEPENTRY_WFE -
进入停止模式
void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
这个函数只能进入 STOP0 或 STOP1
Regulator : 电压域的选择。可选择的有两个,PWR_MAINREGULATOR_ON 和 PWR_LOWPOWERREGULATOR_ON。当选择 PWR_LOWPOWERREGULATOR_ON 时进入 STOP1,反之则进入 STOP0
SLEEPEntry : 睡眠模式进入的方式。两个选项,PWR_SLEEPENTRY_WFI 和 PWR_SLEEPENTRY_WFE -
进入待机模式
void HAL_PWR_EnterSTANDBYMode(void)
立刻进入待机模式 -
退出中断后立刻进入睡眠模式
前面的文章已经提到了,睡眠模式会在接收到任何中断之后立刻退出睡眠模式。有时候需要在退出中断的时候不会唤醒 MCU, 在退出中断之后再次进入低功耗模式。
void HAL_PWR_EnableSleepOnExit(void);
: 调用该函数后,MCU 在退出中断后会立刻进入睡眠,不会被唤醒
void HAL_PWR_DisableSleepOnExit(void);
: 调用该函数后,MCU 会在中断后退出后,立刻唤醒 MCU -
配置中断引脚是否可以唤醒 MCU
void HAL_PWR_EnableSEVOnPend(void);
// 被屏蔽的中断也会唤醒MCU,例如引脚开了中断,但是没有使能中断也可以唤醒MCU
void HAL_PWR_DisableSEVOnPend(void);
// 被屏蔽的中断无法唤醒MCU,例如引脚开了中断,但是没有使能中断就不可以唤醒MCU了
举例说明:
__HAL_RCC_GPIOC_CLK_ENABLE();
/*Configure GPIO pin : PC13 */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* EXTI interrupt init*/
// HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
如果使用 : HAL_PWR_EnableSEVOnPend , 这里只是配置了引脚的会触发中断,但是并没有使能中断,在使用按键时可以唤醒 MCU
如果使用 : HAL_PWR_DisableSEVOnPend, 这里只是配置了引脚的会触发中断,如果没有使能中断,在使用按键时不会唤醒 MCU
三,总结
这里的API 全部都来自 stm32l4xx_hal_pwr.c
, 要熟练的掌握 STM32L4 的超低功耗,这里的 API 必要要熟悉,也要知道每个 API 的作用及使用场合。