STM32 PVD的使用(掉电检测)

有时在一些应用中,我们需要检测系统是否掉电了,或者要在掉电的瞬间需要做一些处理。STM32就有这样的掉电检测机制——PVD(Programmable Voltage Detecter),即可编程电压检测器。通过PVD我们可以设定一个基准电压,当芯片的供电电压高于或低于该基准电压时便产生PVD中断,我们可以在PVD中断里做一些处理。本文以STM32L051为例,来说明PVD的使用。

以下是STM32L051用户手册中对PVD的描述,根据这张图我们可以知道,PVD中断在内部是连接在中断线16的,软件上可以配置需要上升沿中断还是下降沿中断,也可以设置双边沿触发,这和GPIO中断有点类似。若设置了双边沿触发,则上电当VDD超过PVD阈值时产生下降沿中断;掉电时VDD低于PVD阈值产生上升沿中断。图中的100mv是滞后,所以准确地说,在掉电时是要当VDD电压小于(PVD阈值-100mv)时才会触发PVD中断。

图1 PVD介绍

PVD总共可以设置7个等级,可以通过PWR_CR寄存器的PLS[2:0]来设置。下面是PLS的描述,其中最后一个等级是特殊的,它使用PB7引脚的电压和内部基准电压进行比较,使用这一等级时,PB7必须设置成模拟输入。一般而言,我们用前6个等级就足够了,具体选择哪个等级需要根据自己板子的实际情况来定夺,例如当MCU是3.3V供电且电源非常稳定时,就可以选择将阈值设置成3.1V,这样在掉电时就可以更早的触发PVD中断做紧急处理。同时也要注意电路上储能电容是否够大,这会影响PVD中断能处理多少代码,因为系统很快就要完全断电了。

图2  PWR_CR的PLS介绍

在软件编程上,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中断,这应该是因为掉电瞬间电压不稳定导致的。因此如果在掉电前要做一些紧急操作,要记得加个静态变量标记,使紧急操作只执行一次。

/* 初始化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阈值,掉电情况 */
    {
        /* 掉电前的紧急处理 */
    }
}

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

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

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

  • 36
    点赞
  • 143
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
STM32F0系列微控制器中,可以使用PVD(电源电压检测中断检测电源电压是否低于设定的阈值。在使用PVD中断时,需要首先初始化PVD功能并配置相应的阈值和触发条件。接下来,需要编写PVD中断处理函数来执行相应的中断处理操作。 在STM32F0系列微控制器的库文件中,可以找到相应的函数和宏定义来实现PVD中断使用。例如,可以使用以下函数进行PVD的初始化和配置: ```c void HAL_PWR_PVDConfig(PWR_PVDTypeDef* sConfigPVD); ``` 通过调用该函数,可以配置PVD的阈值和触发条件。 在stm32f0xx_hal_conf.h文件中,可以找到以下宏定义来配置使用PVD中断: ```c #define HAL_PWR_MODULE_ENABLED ((uint32_t)0x00000001) #define USE_FULL_ASSERT 1 ``` 确保取消注释定义了USE_FULL_ASSERT宏,并将其设置为1,以启用运行时检查。 同时,在stm32f0xx_it.c文件中,可以编写以下代码来处理PVD中断: ```c void PVD_IRQHandler(void) { // 处理PVD中断事件 } ``` 在main函数中,需要使能PVD中断并配置相应的中断优先级: ```c HAL_PWR_EnablePVD(); HAL_NVIC_SetPriority(PVD_IRQn, 0, 0); HAL_NVIC_EnableIRQ(PVD_IRQn); ``` 总结来说,要在STM32F0上使用PVD中断,需要进行以下步骤: 1. 初始化PVD功能并配置阈值和触发条件。 2. 编写PVD中断处理函数来执行相应的操作。 3. 在main函数中使能PVD中断,并配置中断优先级。 请注意,这只是一个示例,具体的代码实现可能会有所不同,具体的配置和操作需要根据具体的需求和使用情况进行调整。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [STM32F0_HAL库驱动描述——HAL驱动程序概述](https://blog.csdn.net/weixin_30587927/article/details/97716895)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dokin丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值