STM32F4(PVD)

STM32F4(PVD)

GitHub 仓库:https://github.com/XinLiGH/STM32F4xx_PVD_Example

PS:博文不再更新,后续更新会在 GitHub 仓库进行。


      在实际的产品需求中,常常需要产品在断电时保存一些参数或做一些断电保护,这就需要 MCU 能够检测到断电的过程,STM32 片上有电源电压检测器(PVD)给工程师的开发提供了方便,可以比较简单的检测到产品断电的过程。


1,开发环境

     1,固件库:STM32F4xx_DSP_StdPeriph_Lib_V1.8.0

     2,编译器:ARMCC V5.06

     3,IDE:Keil uVision5

     4,操作系统:Windows 10 专业版


2,程序源码

      PVD.h 文件

/**
  ******************************************************************************
  * @file    PVD.h
  * @author  XinLi
  * @version v1.0
  * @date    24-October-2017
  * @brief   Header file for PVD.c module.
  ******************************************************************************
  * @attention
  *
  * <h2><center>Copyright &copy; 2017 XinLi</center></h2>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  *
  ******************************************************************************
  */

#ifndef __PVD_H
#define __PVD_H

#ifdef __cplusplus
extern "C" {
#endif

/* Header includes -----------------------------------------------------------*/
#include "stm32f4xx.h"

/* Macro definitions ---------------------------------------------------------*/
#define PVD_IRQ_PreemptionPriority  (0)
#define PVD_IRQ_SubPriority         (0)

/* Type definitions ----------------------------------------------------------*/
typedef enum
{
  PVD_Level_2V0 = PWR_PVDLevel_0,
  PVD_Level_2V1 = PWR_PVDLevel_1,
  PVD_Level_2V3 = PWR_PVDLevel_2,
  PVD_Level_2V5 = PWR_PVDLevel_3,
  PVD_Level_2V6 = PWR_PVDLevel_4,
  PVD_Level_2V7 = PWR_PVDLevel_5,
  PVD_Level_2V8 = PWR_PVDLevel_6,
  PVD_Level_2V9 = PWR_PVDLevel_7
}PVD_Level;

typedef enum
{
  PVD_Output_High = 0,
  PVD_Output_Low  = 1
}PVD_Output;

typedef void (*PVD_Callback)(PVD_Output output);

/* Variable declarations -----------------------------------------------------*/
/* Variable definitions ------------------------------------------------------*/
/* Function declarations -----------------------------------------------------*/
void PVD_Init(PVD_Level level, PVD_Callback function);
void PVD_DeInit(void);

void PVD_SetLevel(PVD_Level level);
PVD_Level PVD_GetLevel(void);

void PVD_SetCallback(PVD_Callback function);
PVD_Callback PVD_GetCallback(void);

PVD_Output PVD_GetOutput(void);

/* Function definitions ------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif /* __PVD_H */


      PVD.c 文件

/**
  ******************************************************************************
  * @file    PVD.c
  * @author  XinLi
  * @version v1.0
  * @date    24-October-2017
  * @brief   Power voltage detector driver.
  ******************************************************************************
  * @attention
  *
  * <h2><center>Copyright &copy; 2017 XinLi</center></h2>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  *
  ******************************************************************************
  */

/* Header includes -----------------------------------------------------------*/
#include "PVD.h"
#include <string.h>

/* Macro definitions ---------------------------------------------------------*/
/* Type definitions ----------------------------------------------------------*/
/* Variable declarations -----------------------------------------------------*/
/* Variable definitions ------------------------------------------------------*/
static __IO PVD_Callback callback = NULL;

/* Function declarations -----------------------------------------------------*/
/* Function definitions ------------------------------------------------------*/

/**
  * @brief  Power voltage detector initialize.
  * @param  [in] level:    Power voltage detector level.
  * @param  [in] function: Power voltage detector callback.
  * @return None.
  */
void PVD_Init(PVD_Level level, PVD_Callback function)
{
  EXTI_InitTypeDef EXTI_InitStructure = {0};
  NVIC_InitTypeDef NVIC_InitStructure = {0};
  
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  
  EXTI_InitStructure.EXTI_Line    = EXTI_Line16;
  EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
  
  NVIC_InitStructure.NVIC_IRQChannel                   = PVD_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PVD_IRQ_PreemptionPriority;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority        = PVD_IRQ_SubPriority;
  NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  PWR_PVDLevelConfig(level);
  PWR_PVDCmd(ENABLE);
  
  callback = function;
}

/**
  * @brief  Power voltage detector deinitializes.
  * @param  None.
  * @return None.
  */
void PVD_DeInit(void)
{
  EXTI_InitTypeDef EXTI_InitStructure = {0};
  NVIC_InitTypeDef NVIC_InitStructure = {0};
  
  EXTI_InitStructure.EXTI_Line    = EXTI_Line16;
  EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
  EXTI_InitStructure.EXTI_LineCmd = DISABLE;
  EXTI_Init(&EXTI_InitStructure);
  
  NVIC_InitStructure.NVIC_IRQChannel                   = PVD_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PVD_IRQ_PreemptionPriority;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority        = PVD_IRQ_SubPriority;
  NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  PWR_PVDCmd(DISABLE);
  
  callback = NULL;
}

/**
  * @brief  Set power voltage detector level.
  * @param  [in] level: Power voltage detector level.
  * @return None.
  */
void PVD_SetLevel(PVD_Level level)
{
  PWR_PVDLevelConfig(level);
}

/**
  * @brief  Get power voltage detector level.
  * @param  None.
  * @return Power voltage detector level.
  */
PVD_Level PVD_GetLevel(void)
{
  uint32_t tmpreg = PWR->CR;
  
  return (PVD_Level)(tmpreg & 0xE0);
}

/**
  * @brief  Set power voltage detector callback.
  * @param  [in] function: Power voltage detector callback.
  * @return None.
  */
void PVD_SetCallback(PVD_Callback function)
{
  callback = function;
}

/**
  * @brief  Get power voltage detector callback.
  * @param  None.
  * @return Power voltage detector callback.
  */
PVD_Callback PVD_GetCallback(void)
{
  return callback;
}

/**
  * @brief  Get power voltage detector output.
  * @param  None.
  * @return Power voltage detector output.
  */
PVD_Output PVD_GetOutput(void)
{
  uint32_t tmpreg = PWR->CSR;
  
  return (PVD_Output)((tmpreg >> 2) & 0x01);
}

/**
  * @brief  This function handles the PVD Output interrupt request.
  * @param  None.
  * @return None.
  */
void PVD_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line16) != RESET)
  {
    EXTI_ClearITPendingBit(EXTI_Line16);
    
    if(callback != NULL)
    {
      callback(PVD_GetOutput());
    }
  }
}


      main.c 文件

/**
  ******************************************************************************
  * @file    main.c
  * @author  XinLi
  * @version v1.0
  * @date    24-October-2017
  * @brief   Main program body.
  ******************************************************************************
  * @attention
  *
  * <h2><center>Copyright &copy; 2017 XinLi</center></h2>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  *
  ******************************************************************************
  */

/* Header includes -----------------------------------------------------------*/
#include "main.h"
#include "PVD.h"
#include "LED.h"

/* Macro definitions ---------------------------------------------------------*/
/* Type definitions ----------------------------------------------------------*/
/* Variable declarations -----------------------------------------------------*/
/* Variable definitions ------------------------------------------------------*/
/* Function declarations -----------------------------------------------------*/
static void PowerDownProtect(PVD_Output output);

/* Function definitions ------------------------------------------------------*/

/**
  * @brief  Main program.
  * @param  None.
  * @return None.
  */
int main(void)
{
  LED_SetStatus(LED_Pin1, LED_On);
  LED_SetStatus(LED_Pin2, LED_Off);
  
  PVD_Init(PVD_Level_2V5, PowerDownProtect);
  
  for(;;)
  {
    
  }
}

/**
  * @brief  Power voltage detector callback.
  * @param  [in] output: Power voltage detector output.
  * @return None.
  */
static void PowerDownProtect(PVD_Output output)
{
  if(output == PVD_Output_High)
  {
    LED_SetStatus(LED_Pin1, LED_On);
    LED_SetStatus(LED_Pin2, LED_Off);
  }
  else
  {
    LED_SetStatus(LED_Pin1, LED_Off);
    LED_SetStatus(LED_Pin2, LED_On);
  }
}

猜你喜欢

转载自blog.csdn.net/u012325601/article/details/80532217