STM32f407掉电检测PVD功能

18 篇文章 0 订阅


最近在做一个项目需要用到掉电检测,然后保存数据,发现stm自带有PVD功能,就拿来用一下做个记录吧。本文测试基于stm32f407板子。

一、PVD功能介绍

有时在一些应用中,我们需要检测系统是否掉电了,或者要在掉电的瞬间需要做一些处理。STM32就有这样的掉电检测机制——PVD(Programmable Voltage Detecter),即可编程电压检测器。通过PVD我们可以设定一个基准电压,当芯片的供电电压高于或低于该基准电压时便产生PVD中断,我们可以在PVD中断里做一些处理。
在这里插入图片描述
下面是PVD输出的时序图:
在这里插入图片描述
PVD这个功能使用的不多,官方也没有太多的解释,主要在使用的时候最好加上一个存储的电容,以便程序能执行完中断程序。
在M3与M4权威指南中找到了这个功能寄存器对应的检测电压:

在这里插入图片描述

二、代码验证

在HAL库里面是有PVD相关代码的,这里直接调用就行:

/* PVD可编程电源检测器初始化配置函数*/
void PVD_Config(void)
{
   /* 配置PWR时钟 */
    __HAL_RCC_PWR_CLK_ENABLE();

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

    /* 设置PVD电平,设置中断类型:低于设置电平产生上升沿,高于设置电平产生下降沿 */
    PWR_PVDTypeDef sConfigPVD;
    sConfigPVD.PVDLevel = PWR_PVDLEVEL_7;                // LEVEL_0 - 2.0V
    sConfigPVD.Mode = PWR_PVD_MODE_IT_FALLING;    //电源欠压产生中断

     HAL_PWR_ConfigPVD(&sConfigPVD) ;
    /* 使能PVD */
    HAL_PWR_EnablePVD();
}

这里可以设置PVD是欠压还是恢复产生中断,也可以两个都设置,有以下模式:

/** @defgroup PWR_PVD_Mode PWR PVD Mode
  * @{
  */
#define PWR_PVD_MODE_NORMAL                 0x00000000U   /*!< basic mode is used */
#define PWR_PVD_MODE_IT_RISING              0x00010001U   /*!< External Interrupt Mode with Rising edge trigger detection */
#define PWR_PVD_MODE_IT_FALLING             0x00010002U   /*!< External Interrupt Mode with Falling edge trigger detection */
#define PWR_PVD_MODE_IT_RISING_FALLING      0x00010003U   /*!< External Interrupt Mode with Rising/Falling edge trigger detection */
#define PWR_PVD_MODE_EVENT_RISING           0x00020001U   /*!< Event Mode with Rising edge trigger detection */
#define PWR_PVD_MODE_EVENT_FALLING          0x00020002U   /*!< Event Mode with Falling edge trigger detection */
#define PWR_PVD_MODE_EVENT_RISING_FALLING   0x00020003U   /*!< Event Mode with Rising/Falling edge trigger detection */
/**
  * @}
  */

这里我只使用了欠压的中断回调函数,其他的也可以参考下面被注释掉的代码:

/* PVD可编程电源检测器中断回调函数*/
void HAL_PWR_PVDCallback(void)
{
    uint8_t flash_buf[0x4]={0};
          for(int i=0; i<4; i++)
          {
              flash_buf[i] = i+1;
    //                printf("flash_buf[%d]:%0.2X\r\n",i,flash_buf[i]);
          }
          fal_partition_erase(fal_partition_find("para"),0,4);
         fal_partition_write(fal_partition_find("para"),0,flash_buf,4);
         rt_kprintf("pvd power off\r\n");

//   PWR_PVDTypeDef sConfigPVD;
//   if(__HAL_PWR_GET_FLAG(PWR_FLAG_PVDO))     //判断是 欠压 OR 电压恢复
//   {
//      /* 配置判断 电源恢复的参考电平 */
//      sConfigPVD.PVDLevel = PWR_PVDLEVEL_7;                 //LEVEL_6 - 2.9V
//      sConfigPVD.Mode = PWR_PVD_MODE_IT_RISING_FALLING;
//      HAL_PWR_ConfigPVD(&sConfigPVD);
//
//      /* 当VDD低于设定阈值(欠压) 时执行的代码, */
//
//   }
//   else
//   {
//      /* 配置 判断电源欠压的参考电平 */
//      sConfigPVD.PVDLevel = PWR_PVDLEVEL_0;                 //LEVEL_0 - 2.0V
//      sConfigPVD.Mode = PWR_PVD_MODE_IT_RISING_FALLING;
//      HAL_PWR_ConfigPVD(&sConfigPVD);
//
//      /* 当VDD高于设定阈值(电源恢复)时执行的代码 */
//      rt_kprintf("pvd power on\n");
//
//   }
}

还有就是中断函数,库里面没有给出来,需要自己添加上:

void HAL_PWR_PVD_IRQHandler(void)
{
  /* Check PWR Exti flag */
  if(__HAL_PWR_PVD_EXTI_GET_FLAG() != RESET)
  {
    /* PWR PVD interrupt user callback */
    HAL_PWR_PVDCallback();
    
    /* Clear PWR Exti pending bit */
    __HAL_PWR_PVD_EXTI_CLEAR_FLAG();
  }
}
void PVD_IRQHandler(void)
{
   HAL_PWR_PVD_IRQHandler();
}

验证结果:
验证我这个板子是可以在中断的时候将数据写入内存的。
在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

k-kun

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

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

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

打赏作者

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

抵扣说明:

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

余额充值