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
扫描二维码关注公众号,回复:
2769645 查看本文章
![](/qrcode.jpg)
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 © 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 © 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 © 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);
}
}