硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3201|回复: 3
收起左侧

[客户分享] STM32F4(PVD)

[复制链接]

19

主题

15

回帖

72

积分

初级会员

积分
72
发表于 2018-6-1 00:42:06 | 显示全部楼层 |阅读模式
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 文件
  1. /**
  2.   ******************************************************************************
  3.   * @file    PVD.h
  4.   * @author  XinLi
  5.   * @version v1.0
  6.   * @date    24-October-2017
  7.   * @brief   Header file for PVD.c module.
  8.   ******************************************************************************
  9.   * @attention
  10.   *
  11.   * <h2><center>Copyright &#169; 2017 XinLi</center></h2>
  12.   *
  13.   * This program is free software: you can redistribute it and/or modify
  14.   * it under the terms of the GNU General Public License as published by
  15.   * the Free Software Foundation, either version 3 of the License, or
  16.   * (at your option) any later version.
  17.   *
  18.   * This program is distributed in the hope that it will be useful,
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.   * GNU General Public License for more details.
  22.   *
  23.   * You should have received a copy of the GNU General Public License
  24.   * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  25.   *
  26.   ******************************************************************************
  27.   */

  28. #ifndef __PVD_H
  29. #define __PVD_H

  30. #ifdef __cplusplus
  31. extern "C" {
  32. #endif

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

  35. /* Macro definitions ---------------------------------------------------------*/
  36. #define PVD_IRQ_PreemptionPriority  (0)
  37. #define PVD_IRQ_SubPriority         (0)

  38. /* Type definitions ----------------------------------------------------------*/
  39. typedef enum
  40. {
  41.   PVD_Level_2V0 = PWR_PVDLevel_0,
  42.   PVD_Level_2V1 = PWR_PVDLevel_1,
  43.   PVD_Level_2V3 = PWR_PVDLevel_2,
  44.   PVD_Level_2V5 = PWR_PVDLevel_3,
  45.   PVD_Level_2V6 = PWR_PVDLevel_4,
  46.   PVD_Level_2V7 = PWR_PVDLevel_5,
  47.   PVD_Level_2V8 = PWR_PVDLevel_6,
  48.   PVD_Level_2V9 = PWR_PVDLevel_7
  49. }PVD_Level;

  50. typedef enum
  51. {
  52.   PVD_Output_High = 0,
  53.   PVD_Output_Low  = 1
  54. }PVD_Output;

  55. typedef void (*PVD_Callback)(PVD_Output output);

  56. /* Variable declarations -----------------------------------------------------*/
  57. /* Variable definitions ------------------------------------------------------*/
  58. /* Function declarations -----------------------------------------------------*/
  59. void PVD_Init(PVD_Level level, PVD_Callback function);
  60. void PVD_DeInit(void);

  61. void PVD_SetLevel(PVD_Level level);
  62. PVD_Level PVD_GetLevel(void);

  63. void PVD_SetCallback(PVD_Callback function);
  64. PVD_Callback PVD_GetCallback(void);

  65. PVD_Output PVD_GetOutput(void);

  66. /* Function definitions ------------------------------------------------------*/

  67. #ifdef __cplusplus
  68. }
  69. #endif

  70. #endif /* __PVD_H */
复制代码

      PVD.c 文件
  1. /**
  2.   ******************************************************************************
  3.   * @file    PVD.c
  4.   * @author  XinLi
  5.   * @version v1.0
  6.   * @date    24-October-2017
  7.   * @brief   Power voltage detector driver.
  8.   ******************************************************************************
  9.   * @attention
  10.   *
  11.   * <h2><center>Copyright &#169; 2017 XinLi</center></h2>
  12.   *
  13.   * This program is free software: you can redistribute it and/or modify
  14.   * it under the terms of the GNU General Public License as published by
  15.   * the Free Software Foundation, either version 3 of the License, or
  16.   * (at your option) any later version.
  17.   *
  18.   * This program is distributed in the hope that it will be useful,
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.   * GNU General Public License for more details.
  22.   *
  23.   * You should have received a copy of the GNU General Public License
  24.   * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  25.   *
  26.   ******************************************************************************
  27.   */

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

  31. /* Macro definitions ---------------------------------------------------------*/
  32. /* Type definitions ----------------------------------------------------------*/
  33. /* Variable declarations -----------------------------------------------------*/
  34. /* Variable definitions ------------------------------------------------------*/
  35. static __IO PVD_Callback callback = NULL;

  36. /* Function declarations -----------------------------------------------------*/
  37. /* Function definitions ------------------------------------------------------*/

  38. /**
  39.   * @brief  Power voltage detector initialize.
  40.   * @param  [in] level:    Power voltage detector level.
  41.   * @param  [in] function: Power voltage detector callback.
  42.   * @return None.
  43.   */
  44. void PVD_Init(PVD_Level level, PVD_Callback function)
  45. {
  46.   EXTI_InitTypeDef EXTI_InitStructure = {0};
  47.   NVIC_InitTypeDef NVIC_InitStructure = {0};
  48.   
  49.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  50.   
  51.   EXTI_InitStructure.EXTI_Line    = EXTI_Line16;
  52.   EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Interrupt;
  53.   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
  54.   EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  55.   EXTI_Init(&EXTI_InitStructure);
  56.   
  57.   NVIC_InitStructure.NVIC_IRQChannel                   = PVD_IRQn;
  58.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PVD_IRQ_PreemptionPriority;
  59.   NVIC_InitStructure.NVIC_IRQChannelSubPriority        = PVD_IRQ_SubPriority;
  60.   NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
  61.   NVIC_Init(&NVIC_InitStructure);
  62.   
  63.   PWR_PVDLevelConfig(level);
  64.   PWR_PVDCmd(ENABLE);
  65.   
  66.   callback = function;
  67. }

  68. /**
  69.   * @brief  Power voltage detector deinitializes.
  70.   * @param  None.
  71.   * @return None.
  72.   */
  73. void PVD_DeInit(void)
  74. {
  75.   EXTI_InitTypeDef EXTI_InitStructure = {0};
  76.   NVIC_InitTypeDef NVIC_InitStructure = {0};
  77.   
  78.   EXTI_InitStructure.EXTI_Line    = EXTI_Line16;
  79.   EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Interrupt;
  80.   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
  81.   EXTI_InitStructure.EXTI_LineCmd = DISABLE;
  82.   EXTI_Init(&EXTI_InitStructure);
  83.   
  84.   NVIC_InitStructure.NVIC_IRQChannel                   = PVD_IRQn;
  85.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PVD_IRQ_PreemptionPriority;
  86.   NVIC_InitStructure.NVIC_IRQChannelSubPriority        = PVD_IRQ_SubPriority;
  87.   NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;
  88.   NVIC_Init(&NVIC_InitStructure);
  89.   
  90.   PWR_PVDCmd(DISABLE);
  91.   
  92.   callback = NULL;
  93. }

  94. /**
  95.   * @brief  Set power voltage detector level.
  96.   * @param  [in] level: Power voltage detector level.
  97.   * @return None.
  98.   */
  99. void PVD_SetLevel(PVD_Level level)
  100. {
  101.   PWR_PVDLevelConfig(level);
  102. }

  103. /**
  104.   * @brief  Get power voltage detector level.
  105.   * @param  None.
  106.   * @return Power voltage detector level.
  107.   */
  108. PVD_Level PVD_GetLevel(void)
  109. {
  110.   uint32_t tmpreg = PWR->CR;
  111.   
  112.   return (PVD_Level)(tmpreg & 0xE0);
  113. }

  114. /**
  115.   * @brief  Set power voltage detector callback.
  116.   * @param  [in] function: Power voltage detector callback.
  117.   * @return None.
  118.   */
  119. void PVD_SetCallback(PVD_Callback function)
  120. {
  121.   callback = function;
  122. }

  123. /**
  124.   * @brief  Get power voltage detector callback.
  125.   * @param  None.
  126.   * @return Power voltage detector callback.
  127.   */
  128. PVD_Callback PVD_GetCallback(void)
  129. {
  130.   return callback;
  131. }

  132. /**
  133.   * @brief  Get power voltage detector output.
  134.   * @param  None.
  135.   * @return Power voltage detector output.
  136.   */
  137. PVD_Output PVD_GetOutput(void)
  138. {
  139.   uint32_t tmpreg = PWR->CSR;
  140.   
  141.   return (PVD_Output)((tmpreg >> 2) & 0x01);
  142. }

  143. /**
  144.   * @brief  This function handles the PVD Output interrupt request.
  145.   * @param  None.
  146.   * @return None.
  147.   */
  148. void PVD_IRQHandler(void)
  149. {
  150.   if(EXTI_GetITStatus(EXTI_Line16) != RESET)
  151.   {
  152.     EXTI_ClearITPendingBit(EXTI_Line16);
  153.    
  154.     if(callback != NULL)
  155.     {
  156.       callback(PVD_GetOutput());
  157.     }
  158.   }
  159. }
复制代码


      main.c 文件

  1. /**
  2.   ******************************************************************************
  3.   * @file    main.c
  4.   * @author  XinLi
  5.   * @version v1.0
  6.   * @date    24-October-2017
  7.   * @brief   Main program body.
  8.   ******************************************************************************
  9.   * @attention
  10.   *
  11.   * <h2><center>Copyright &#169; 2017 XinLi</center></h2>
  12.   *
  13.   * This program is free software: you can redistribute it and/or modify
  14.   * it under the terms of the GNU General Public License as published by
  15.   * the Free Software Foundation, either version 3 of the License, or
  16.   * (at your option) any later version.
  17.   *
  18.   * This program is distributed in the hope that it will be useful,
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.   * GNU General Public License for more details.
  22.   *
  23.   * You should have received a copy of the GNU General Public License
  24.   * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  25.   *
  26.   ******************************************************************************
  27.   */

  28. /* Header includes -----------------------------------------------------------*/
  29. #include "main.h"
  30. #include "PVD.h"
  31. #include "LED.h"

  32. /* Macro definitions ---------------------------------------------------------*/
  33. /* Type definitions ----------------------------------------------------------*/
  34. /* Variable declarations -----------------------------------------------------*/
  35. /* Variable definitions ------------------------------------------------------*/
  36. /* Function declarations -----------------------------------------------------*/
  37. static void PowerDownProtect(PVD_Output output);

  38. /* Function definitions ------------------------------------------------------*/

  39. /**
  40.   * @brief  Main program.
  41.   * @param  None.
  42.   * @return None.
  43.   */
  44. int main(void)
  45. {
  46.   LED_SetStatus(LED_Pin1, LED_On);
  47.   LED_SetStatus(LED_Pin2, LED_Off);
  48.   
  49.   PVD_Init(PVD_Level_2V5, PowerDownProtect);
  50.   
  51.   for(;;)
  52.   {
  53.    
  54.   }
  55. }

  56. /**
  57.   * @brief  Power voltage detector callback.
  58.   * @param  [in] output: Power voltage detector output.
  59.   * @return None.
  60.   */
  61. static void PowerDownProtect(PVD_Output output)
  62. {
  63.   if(output == PVD_Output_High)
  64.   {
  65.     LED_SetStatus(LED_Pin1, LED_On);
  66.     LED_SetStatus(LED_Pin2, LED_Off);
  67.   }
  68.   else
  69.   {
  70.     LED_SetStatus(LED_Pin1, LED_Off);
  71.     LED_SetStatus(LED_Pin2, LED_On);
  72.   }
  73. }
复制代码




评分

参与人数 1金币 +50 收起 理由
eric2013 + 50 很给力!

查看全部评分

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107101
QQ
发表于 2018-6-1 01:58:49 | 显示全部楼层
谢谢楼主分享。
回复

使用道具 举报

2

主题

28

回帖

34

积分

新手上路

积分
34
发表于 2019-9-5 12:14:47 | 显示全部楼层
假如有的数据在存在外部EEPROM或SD卡中,MCU检测到断电时,来及得把数据写到外部存储器么??检测到断电时的电压可能不能支持外部存储器正常工作会不会。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107101
QQ
发表于 2019-9-5 12:28:56 | 显示全部楼层
兵哥哥 发表于 2019-9-5 12:14
假如有的数据在存在外部EEPROM或SD卡中,MCU检测到断电时,来及得把数据写到外部存储器么??检测到断电时 ...

如果有备份电源或者超级电容的话,可以续命。如果没有的话,可以用备份sram,完全来得及存储,不过需要给rtc加电池供电
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-17 15:23 , Processed in 0.171608 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表