stm32g0 电源监控-踩坑总结
目录
一、背景
1. mcu 和 sdk 库
stm32g0 系列单片机stm32 hal 库2. 应用背景
在硬件产品运行的过程中,可能会遇到异常情况,导致mcu 供电电压突然变化,如果程序不能快速响应,可能会导致设备出现异常。传统的依靠adc 检测外部电压的方法,会存在检测不及时的问题。
3. stm32g0 提供的电源监控方案
stm32g0 系列单片机对电源监控提供了两类处理方案:
二、电源监控器-复位
POR)PDR)BOR)POR/PDR 在所有功率模式下都有效。BOR 只能通过选项字节使能或禁止,其在关断模式下不可用。
1. 电气特征

2. 上电复位(POR)
上电复位(POR ,power-on reset )在mcu 电压低于1.70v 时,即会产生上电复位,如果mcu 一直处于这个电压,mcu 会一直处于复位状态。
3. 掉电复位( PDR)
掉电复位( PDR, power-drop reset)当mcu 在正常工作状态时,供电电压低于 1.69v 时,即会产生掉电复位。
4. 欠压复位(BOR)
上电复位和掉电复位的电压是固定的,可以理解成 mcu正常工作的极限情况。mcu 也提供了欠压复位(BOR, Brownout reset)的机制。
欠压复位允许在选项字寄存器配置欠压复位的阈值,并且提供了上升沿阈值电压和下降沿阈值电压可配置。
上升沿电压
| 阈值 | |
|---|---|
| 上升沿电压1 | 约2.1v |
| 上升沿电压2 | 约2.3v |
| 上升沿电压3 | 约2.6v |
| 上升沿电压4 | 约2.9v |
下降沿电压
| 阈值 | |
|---|---|
| 下降沿电压1 | 约2.0v |
| 下降沿电压2 | 约2.2v |
| 下降沿电压3 | 约2.5v |
| 下降沿电压4 | 约2.8v |
三、可编程电压检测器(PVD)
1.概念
可编程电压检测器 ( PVD, Programmable voltage detector) : 用户可以在程序中设置需要检测的电压等级,当电压上升或下降到该等级时,mcu 会产生标志位或者中断。
中断
PVD 产生的事件在内部连接到EXTI16。
2. 电源电压检测器阈值
2.1上升阈值
| 阈值电压 | |
|---|---|
| level0 | 约2.1v |
| level1 | 约2.2v |
| level2 | 约2.5v |
| level3 | 约2.6v |
| level4 | 约2.7v |
| level5 | 约2.9v |
| level6 | 约3.0v |
2.2下降阈值
| 阈值电压 | |
|---|---|
| level0 | 约2.0v |
| level1 | 约2.2v |
| level2 | 约2.4v |
| level3 | 约2.5v |
| level4 | 约2.6v |
| level5 | 约2.8v |
| level6 | 约2.9v |
3. 编程实现
3.1 配置pvd
void device_pvd_conf( void )
{
PWR_PVDTypeDef pvd_conf = {0, 0};
__HAL_RCC_PWR_CLK_ENABLE();
HAL_NVIC_SetPriority( PVD_VDDIO2_IRQn, 0, 0 );
HAL_NVIC_EnableIRQ( PVD_VDDIO2_IRQn );
//falling
pvd_conf.Mode = PWR_PVD_MODE_IT_FALLING;
//level 6 ,vol = 2.9v
pvd_conf.PVDLevel = PWR_PVDLEVEL_FALLING_6;
HAL_PWREx_ConfigPVD( &pvd_conf );
HAL_PWREx_EnablePVD();
}
3.3 实现中断接口
void HAL_PWREx_PVD_PVM_Falling_Callback( void )
{
// input your code
HAL_PWREx_DisablePVD();
}
3.3.1 满足阈值电压时,接口函数没回调
我在中断接口这里踩了个坑。
HAL_PWREx_PVD_PVM_Falling_Callback 本来是stm32g0xx_hal_pwr_ex.c 里面定义的一个弱函数,它由HAL_PWREx_PVD_PVM_IRQHandler 调用。
我一开始以为实现了这个弱函数,功能就实现了。谁知道,当电压满足阈值电压时,并没有调用这个函数。
3.3.2找exti 的中断响应函数
查看exti 的中断响应函数,发现只有 EXTI0_1_IRQHandler 、 EXTI2_3_IRQHandler 、EXTI4_15_IRQHandler 发现并没有 pvd 事件对应的line16 处理函数。
3.3.3查看 库函数 HAL_PWREx_PVD_PVM_IRQHandler 的注释

上面注释提到,HAL_PWREx_PVD_PVM_IRQHandler 函数需要被 PVD_IRQHandler 函数调用。我参照注释的说明做了,也没效果。其实没效果也是对的。PVD_IRQHandler 并不是系统认可的中断向量表的成员,产生中断也不会调用它。看来st 的工程师也喜欢复制粘贴。
3.3.4查看启动文件的中断向量表,找到了解决办法
向量表如下所示

pvd 事件,对应中断向量表的是 PVD_VDDIO2_IRQHandler 函数,所以HAL_PWREx_PVD_PVM_IRQHandler 需要在 PVD_VDDIO2_IRQHandler 下面调用。
pvd 中断对应的中断号是
PVD_VDDIO2_IRQn = 1, /*!< PVD through EXTI line 16, PVM (monit. VDDIO2) through EXTI line 34*/
3.4 pvd 事件对于的中断服务函数
void PVD_VDDIO2_IRQHandler( void )
{
HAL_PWREx_PVD_PVM_IRQHandler();
}
作者:gdut_llkkyy