stm32的掉电检测机制——PVD

有时在一些应用中,我们需要检测系统是否掉电了,或者要在掉电的瞬间需要做一些处理。

STM32内部自带PVD功能,用于对MCU供电电压VDD进行监控。

STM32就有这样的掉电检测机制------PVD(Programmable Voltage Detecter),即可编程电压检测器。通过PVD我们可以设定一个基准电压,当芯片的供电电压高于或低于该基准电压时便产生PVD中断,我们可以在PVD中断里做一些处理。

本文以STM32L051为例,来说明PVD的使用。

以下是STM32L051用户手册中对PVD的描述,根据这张图我们可以知道,PVD中断在内部是连接在中断线16的,软件上可以配置

PVD总共可以设置7个等级, 可以通过PWR_CR寄存器的PLS[2:0]来设置。 通过电源控制寄存器中的PLS[2:0]位可以用来设定监控电压的阀值,通过对外部电压进行比较来监控电源。当条件触发,需要系统进入特别保护状态,执行紧急关闭任务:对系统的一些数据保存起来,同时对外设进行相应的保护操作。

下面是PLS的描述, 其中最后一个等级是特殊的, 它使用PB7引脚的电压和内部基准电压进行比较, 使用这一等级时, PB7必须设置成模拟输入。 一般而言, 我们用前6个等级就足够了, 具体选择哪个等级需要根据自己板子的实际情况来定夺, 例如当MCU是3.3V供电且电源非常稳定时, 就可以选择将阈值设置成3.1V, 这样在掉电时就可以更早的触发PVD中断做紧急处理。

同时也要注意电路上储能电容是否够大, 这会影响PVD中断能处理多少代码, 因为系统很快就要完全断电了。

在软件编程上, PVD的使用非常的简单, 下面是一份HAL库的例子。 PVD的初始化只需要提供2个参数, 一个是PVDLevel, 也就是上文提到的7个等级; 另一个参数是Mode, 即中断的边沿选择或事件的边沿选择, 一般用中断就足够了, 事件没用过。 当设置为双边沿中断时, 可以通过PWR_CSR的PVDO位来判断是上升沿还是下降沿, HAL库已经封装好了相应的宏:

__HAL_PWR_GET_FLAG, 通过__HAL_PWR_GET_FLAG( PWR_FLAG_PVDO )就可以获取PVDO位的状态, 为0则是VDD高于阈值(上电的情况), 为1则是VDD小于阈值(掉电的情况) 。

实测在掉电时, MCU会多次进入PVD中断, 这应该是因为掉电瞬间电压不稳定导致的。 因此如果在掉电前要做一些紧急操作, 要记得加个静态变量标记, 使紧急操作只执行一次。

操作流程:使用HAL库版本

/* 初始化PVD */

void PVD_Init(void)

{

PWR_PVDTypeDef PvdStruct;

HAL_PWR_EnablePVD(); /* 使能PVD */

PvdStruct.PVDLevel = PWR_PVDLEVEL_6; /* PVD阈值3.1V */

PvdStruct.Mode = PWR_PVD_MODE_IT_RISING; /* 检测掉电 */

HAL_PWR_ConfigPVD(&PvdStruct);

HAL_NVIC_SetPriority(PVD_IRQn, 0, 0); /* 配置PVD中断优先级 */

HAL_NVIC_EnableIRQ(PVD_IRQn); /* 使能PVD中断 */

}

/* PVD中断处理 */

void PVD_IRQHandler(void)

{

if(__HAL_PWR_GET_FLAG( PWR_FLAG_PVDO )) /* 1为VDD小于PVD阈值,掉电情况 */

{

/* 掉电前的紧急处理 */

}

}

操作流程:不使用HAL库版本

1)、系统启动后启动PVD,并开启相应的中断。

PWR_PVDLevelConfig(PWR_PVDLevel_2V8); // 设定监控阀值

PWR_PVDCmd(ENABLE); // 使能PVD

EXTI_StructInit(&EXTI_InitStructure);

EXTI_InitStructure.EXTI_Line = EXTI_Line16; // PVD连接到中断线16上

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //使用中断模式

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Raising;//电压低于阀值时产生中断

EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 使能中断线

EXTI_Init(&EXTI_InitStructure); // 初始

EXTI_InitStructure.EXTI_Trigger的赋值可选项:

EXTI_Trigger_Rising---表示电压从高下降到低于设定阀值时产生中断;

EXTI_Trigger_Falling---表示电压从低上升到高于设定阀值时产生中断;

EXTI_Trigger_Rising_Falling---表示电压上升或下降越过设定阀值时都产生中断。

2)、当工作电压低于设定阀值时,将产生PVD中断,在中断程序中进行相应的处理: void PVD_IRQHandler(void)

{

EXTI_ClearITPendingBit(EXTI_Line16);

...... // 用户添加紧急处理代码处

}

最后顺便说下哪些应用场合会用到PVD, 以下是我工作中遇到过得一些场景。

1.记录设备掉电时间。 这个很好理解, 可能业务上就有这个需求, 或者可以利用这一点来完成低功耗设备的待机时长测试。

2.通知其他处理离线。 假如设备中有由干电池供电的MCU1和由锂电池供电的MCU2, MCU1的部分功能可能需要MCU2来完成, MCU1需要知道MCU2是否离线(因为锂电池可拔插, 可能随时被拔) 。 这种情况就可以在MCU2上利用PVD来通知MCU1。 通知的方式有很多, 例如串口直接通知另一方自己将要断电了。 不过要注意低功耗下的使用场景, 例如STM32进入STOP模式时, 系统时钟是关闭的, 此时串口发送的数据波特率可能不是期望的波特率, 被通知方收到的数据可能是错的, 因此建议将通知方的串口时钟源配置成HSI, 并且将低功耗唤醒后的默认时钟配成HSI, 这样一旦在低功耗状态下进入PVD, 串口发送的数据也不会有问题。

3.PVD所对应的时钟需要使能;对于stm32的外设或者模块的操作(配置、使用),在前期的配置中,基本上都是需要使能相应的时钟。

相关推荐
sinat_360704826 小时前
STM32 RTC 实时时钟说明
stm32·单片机
YE_lou7 小时前
【蓝桥杯嵌入式】8_IIC通信-eeprom读写
stm32·嵌入式硬件·蓝桥杯
亿道电子Emdoor8 小时前
【ARM】解决ArmDS Fast Models 中部分内核无法上电的问题
arm开发·stm32·单片机
木燚垚13 小时前
物联网水质监测系统设计与实现/基于STM32的水产养殖云监控系统设计
stm32·嵌入式硬件·物联网·智能家居
云山工作室15 小时前
基于单片机的电子式单项智能电表设计(论文+源码)
stm32·单片机·嵌入式硬件·毕业设计·毕设
yyqzjw1 天前
【STM32】ADC|多通道ADC采集
stm32·单片机·嵌入式硬件
sinat_360704821 天前
STM32_USART通用同步/异步收发器
stm32·单片机·嵌入式硬件
嘿·嘘1 天前
第二章 STM32启动流程
stm32·单片机·嵌入式硬件
雯宝1 天前
STM32系统架构介绍
stm32·嵌入式硬件·系统架构
沐欣工作室_lvyiyi1 天前
基于fpga的数字频率计(论文+源码)
stm32·单片机·深度学习·物联网·fpga开发·毕业设计