一、STM32 电源监控介绍
- 1.1、上电/掉电复位POR/PDR(F1)
- 1.2、可编程电压检测器(PVD)(F1)
二、PVD相关寄存器介绍(F1)
三、PVD相关HAL库驱动介绍
四、PVD的使用步骤
五、编程实战
一、STM32 电源监控介绍
电源监控在STM32芯片中起着关键作用,确保系统在电源电压异常或不稳定时能够进行适当的处理,以防止数据损坏或系统崩溃。以下是几种常见的电源监控功能:
-
POR/PDR监控器(上电/掉电复位):用于检测芯片的上电和掉电情况,并在检测到这些事件时执行相应的复位操作,以确保芯片处于可靠的初始状态。
-
PVD监控器(可编程电压检测器):监控芯片的供电电压(通常为VDD),并在电压低于或高于特定阈值时触发相应的中断或复位。这有助于防止芯片在电压异常情况下工作,从而保护系统免受损坏。
-
BOR监控器(欠压复位):在供电电压低于特定阈值时触发复位操作,以确保系统在电源电压不足时不会工作,从而避免不可预测的行为或数据损坏。
-
AVD监控器(模拟电压检测器):监控芯片的模拟供电电压(通常为VDDA),以确保模拟电路的稳定性和正确性。
-
VBAT阈值(电池电压阈值):用于监控备用电池(VBAT)的电压,并在电压低于或高于特定阈值时触发相应的中断或处理操作。这对于依赖备用电池的应用非常重要,例如实时时钟(RTC)功能。
-
温度阈值(温度检测器):监控芯片的结温,并在温度超过或低于特定阈值时触发相应的中断或处理操作。这有助于防止芯片在极端温度条件下工作,从而保护系统的稳定性和可靠性。
这些电源监控功能可以根据具体的应用需求进行配置和使用,以提高系统的稳定性和可靠性。
1.1、上电/掉电复位POR/PDR(F1)
上电/掉电复位(POR/PDR)是一种基本的电源监控机制,用于确保系统在供电电压异常情况下能够进行适当的处理,以避免数据损坏或系统故障。
-
VPOR(上电复位阈值):是在芯片供电时用于触发上电复位的电压阈值。当VDD低于VPOR阈值时,系统会进入复位状态,防止在供电电压不足的情况下发生误操作。在F1系列中,典型的VPOR阈值为1.92V。
-
VPDR(掉电复位阈值):是在掉电情况下用于触发掉电复位的电压阈值。当VDD低于VPDR阈值时,系统会保持在复位状态,以确保在电源电压不足的情况下不会发生任何意外操作。在F1系列中,典型的VPDR阈值为1.88V。
在系统正常供电情况下,如果VDD超过VPOR阈值,则系统将退出复位状态,开始正常工作。然而,如果在掉电情况下VDD降至VPDR以下,则系统将保持在复位状态,直到电源电压恢复到正常水平。
这种复位机制确保了系统对供电电压异常情况的敏感性,从而保护了系统的稳定性和可靠性。
1.2、可编程电压检测器(PVD)(F1)
可编程电压检测器(PVD)是一种用于监视供电电压(VDD)的重要功能。其主要作用包括:
-
监视供电电压:PVD持续监视芯片的供电电压,确保在电源电压异常的情况下能够及时发现并采取适当的措施。
-
产生中断通知:当供电电压下降到设定的阈值以下时,PVD会产生中断,向软件发出信号,通知系统出现了供电电压异常,需要进行紧急处理。这可以帮助系统及时应对电源问题,以避免数据损坏或系统故障。
-
上升电压的监控:当供电电压恢复到设定的阈值以上时,PVD也会产生中断,通知软件供电已经恢复正常。这样的功能可以帮助系统在电源恢复后采取必要的初始化或恢复操作。
-
阈值设定:PVD通常允许用户根据具体应用需求设置供电下降和上升的阈值。这些阈值通常有一个固定的差值,以防止在阈值上下小幅度抖动时频繁触发中断,从而提高系统的稳定性和可靠性。
通过以上功能,PVD能够有效地监控供电电压,帮助系统及时发现并处理电源问题,保障系统的正常运行和数据完整性。
二、PVD相关寄存器介绍(F1)
在STM32F1系列中,用于PVD相关功能的寄存器主要包括:
-
PWR_CR(电源控制寄存器):
- 作用:用于设置PVD检测的电压阈值以及使能PVD。
- 具体功能:可以通过配置PWR_CR寄存器来设置PVD监测的电压阈值,并使能或禁用PVD功能。
-
PWR_CSR(电源控制/状态寄存器):
- 作用:用于查看系统当前状态,包括PVD的输出状态。
- 具体功能:PWR_CSR寄存器包含了多个位域,其中包括了PVD的输出状态位,可以通过读取这些位来获取PVD的输出状态,以确定供电电压是否在设定的阈值范围内。
-
中断相关的寄存器:
- EXTI_IMR(外部中断屏蔽寄存器):用于配置外部中断的屏蔽,控制是否允许外部中断。
- EXTI_RTSR(上升沿触发选择寄存器):用于配置外部中断的触发方式,指定外部中断触发条件为上升沿。
- EXTI_FTSR(下降沿触发选择寄存器):用于配置外部中断的触发方式,指定外部中断触发条件为下降沿。
- EXTI_PR(挂起寄存器):用于读取外部中断的挂起状态,检查是否有外部中断发生。
通过这些寄存器的设置和状态检查,可以实现对PVD功能的灵活配置和状态监测,确保系统能够有效地对供电电压进行监控和管理。
三、PVD相关HAL库驱动介绍
在STM32的HAL库中,针对PVD(可编程电压检测器)功能提供了以下相关的驱动函数和结构体:
-
驱动函数:
-
__HAL_RCC_PWR_CLK_ENABLE(...)
:- 关联寄存器:RCC_APB1ENR(APB1总线时钟使能寄存器)
- 功能描述:用于使能电源时钟,确保PVD功能正常工作所需的时钟被使能。
-
HAL_PWR_ConfigPVD(...)
:- 关联寄存器:PWR_CR(电源控制寄存器)
- 功能描述:用于配置PVD相关参数,包括PVD的阈值和工作模式等。
-
HAL_PWR_EnablePVD(...)
:- 关联寄存器:PWR_CR(电源控制寄存器)
- 功能描述:用于使能PVD功能,启动PVD功能后,系统将会监视供电电压并根据配置的阈值产生中断。
-
-
PVD HAL库相关结构体:
-
PWR_PVDTypeDef
:- 结构体描述:该结构体用于配置PVD的相关参数,包括PVD的检测阈值和工作模式等。
- 成员变量:
-
PVDLevel
:PVD的检测阈值,可选项包括PWR_PVDLEVEL_0至PWR_PVDLEVEL_7。 -
Mode
:PVD的工作模式,可选项包括PWR_PVD_MODE_NORMAL和PWR_PVD_MODE_IT_RISING_FALLING等。
-
-
通过调用以上的HAL库驱动函数,并结合相关的结构体配置,可以方便地实现对PVD功能的配置和使能,从而实现对供电电压的监测和管理。
四、PVD的使用步骤
PVD(可编程电压检测器)的使用步骤,下面是更详细的说明:
-
使能电源时钟:
在使用PVD功能之前,需要确保电源时钟已经被使能,以确保PVD功能正常工作。可以通过__HAL_RCC_PWR_CLK_ENABLE()
函数来实现电源时钟的使能。 -
配置PVD:
使用HAL_PWR_ConfigPVD()
函数配置PVD的相关参数,包括电压级别和中断线边沿触发等。通过该函数,可以设置PVD的检测阈值和工作模式等。 -
使能PVD检测:
调用HAL_PWR_EnablePVD()
函数使能PVD功能,启动PVD功能后,系统将会监视供电电压并根据配置的阈值产生中断。 -
设置PVD中断优先级:
使用HAL_NVIC_SetPriority()
函数设置PVD中断的优先级,确保在发生PVD中断时能够及时响应。 -
使能PVD中断:
通过HAL_NVIC_EnableIRQ()
函数使能PVD中断,以便系统在PVD检测到电压异常时能够触发相应的中断处理函数。 -
编写中断服务函数:
编写PVD中断服务函数,处理PVD检测到电压异常时的操作。通常包括PVD_IRQHandler
和HAL_PWR_PVD_IRQHandler
函数,以及HAL_PWR_PVDCallback
回调函数。在中断服务函数中,可以根据需要进行一些紧急处理或者通知系统电压恢复正常。
通过以上步骤,可以完成对PVD功能的配置和使用,确保系统在供电电压异常时能够及时响应并采取相应的措施,保障系统的稳定运行。
五、编程实战
F1按键输入 配置PVD,实现电源监控
pwr.c
#include "./BSP/PWR/pwr.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
/* 初始化WKUP按键 */
void pwr_wkup_key_init(void)
{
GPIO_InitTypeDef gpio_init_struct;
PWR_WKUP_GPIO_CLK_ENABLE(); /* 使能WKUP引脚时钟 */
gpio_init_struct.Pin = PWR_WKUP_GPIO_PIN; /* 配置WKUP引脚 */
gpio_init_struct.Mode = GPIO_MODE_IT_RISING; /* 中断,上升沿触发 */
gpio_init_struct.Pull = GPIO_PULLDOWN; /* 下拉 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
HAL_GPIO_Init(PWR_WKUP_GPIO_PORT, &gpio_init_struct); /* 初始化WKUP引脚 */
HAL_NVIC_SetPriority(PWR_WKUP_INT_IRQn, 2, 2); /* 设置WKUP中断优先级 */
HAL_NVIC_EnableIRQ(PWR_WKUP_INT_IRQn);
}
/* WKUP中断处理函数 */
void PWR_WKUP_INT_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(PWR_WKUP_GPIO_PIN); /* 处理WKUP引脚中断 */
}
/* 外部中断回调函数 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == PWR_WKUP_GPIO_PIN)
{
/* 在此处执行WKUP中断回调的相关操作 */
}
}
/* 初始化电压监测功能 */
void pwr_pvd_init(void)
{
PWR_PVDTypeDef pwr_pvd_init_struct;
/* 1. 使能PWR时钟 */
__HAL_RCC_PWR_CLK_ENABLE();
/* 2. 配置PVD */
pwr_pvd_init_struct.PVDLevel = PWR_PVDLEVEL_7; /* 设置PVD触发电压等级 */
pwr_pvd_init_struct.Mode = PWR_PVD_MODE_IT_RISING_FALLING; /* 设置PVD触发模式 */
HAL_PWR_ConfigPVD(&pwr_pvd_init_struct); /* 配置PVD功能 */
/* 3. 使能PVD */
HAL_PWR_EnablePVD();
/* 4. 设置PVD中断优先级 */
HAL_NVIC_SetPriority(PVD_IRQn, 2, 2);
HAL_NVIC_EnableIRQ(PVD_IRQn);
}
/* PVD中断处理函数 */
void PVD_IRQHandler(void)
{
HAL_PWR_PVD_IRQHandler(); /* 处理PVD中断 */
}
/* PVD中断回调函数 */
void HAL_PWR_PVDCallback(void)
{
if (__HAL_PWR_GET_FLAG(PWR_FLAG_PVDO)) /* 电压比PLS设置的还低 */
{
printf("PVD Low Voltage \r\n");
LED1(0); /* 关闭LED1指示灯 */
}
else
{
printf("PVD Voltage OK\r\n");
LED1(1); /* 打开LED1指示灯 */
}
}
pwr.h
#ifndef __PWR_H
#define __PWR_H
#include "./SYSTEM/sys/sys.h"
#define PWR_WKUP_GPIO_PORT GPIOA
#define PWR_WKUP_GPIO_PIN GPIO_PIN_0
#define PWR_WKUP_GPIO_CLK_ENABLE() do { __HAL_RCC_GPIOA_CLK_ENABLE(); } while (0)
#define PWR_WKUP_INT_IRQn EXTI0_IRQn
#define PWR_WKUP_INT_IRQHandler EXTI0_IRQHandler
void pwr_wkup_key_init(void); /* 初始化WKUP按键 */
void pwr_pvd_init(void); /* 初始化电压监测功能 */
#endif
main.c文章来源:https://www.toymoban.com/news/detail-843169.html
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/BEEP/beep.h"
#include "./BSP/KEY/key.h"
#include "./BSP/PWR/pwr.h"
int main(void)
{
uint8_t key;
uint8_t t = 0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
usart_init(115200); /* 串口初始化 */
led_init(); /* 初始化LED */
key_init(); /* 初始化按键 */
pwr_wkup_key_init(); /* WKUP引脚初始化 */
pwr_pvd_init(); /* PVD配置 */
printf("Enter to LowPower Test \r\n");
while(1)
{
key = key_scan(0); /* 得到键值 */
if (key)
{
switch (key)
{
/* 进入待机模式 */
case KEY2_PRES:
/* 使能电源时钟 */
__HAL_RCC_PWR_CLK_ENABLE();
/* 使能WKUP上升沿的唤醒功能 */
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
/* 清除唤醒标记 */
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
printf("Enter STANDBY Mode \r\n");
HAL_PWR_EnterSTANDBYMode();
printf("Exit STANDBY Mode \r\n");
break;
/* 进入停止模式 */
case KEY1_PRES:
LED1(0); /* 点亮绿灯,提示进入停止模式 */
printf("Enter STOP Mode \r\n");
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
sys_stm32_clock_init(RCC_PLL_MUL9); /* 重新设置时钟, 72Mhz */
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);
HAL_SuspendTick();
printf("Exit STOP Mode \r\n");
LED1(1);
break;
/* 进入睡眠模式 */
case KEY0_PRES:
printf("Enter SLEEP Mode \r\n");
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
printf("Exit SLEEP Mode \r\n");
break;
}
}
if ((t % 20) == 0)
{
LED0_TOGGLE(); /* 每200ms,翻转一次LED0 */
}
delay_ms(10);
t++;
}
}
文章来源地址https://www.toymoban.com/news/detail-843169.html
到了这里,关于【正点原子STM32】PVD低功耗实验 – 电源监控(POR/PDR监控器、PVD监控器、 BOR监控器、AVD监控器、VBAT阈值、温度阈值、PVD相关寄存器和HAL库驱动、PVD的使用步骤)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!