STM32CubeMX系列教程14:电源控制器(PWR)

2023-11-10 07:59

本文主要是介绍STM32CubeMX系列教程14:电源控制器(PWR),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

STM32CubeMX系列教程14:电源控制器(PWR)

摘要: 本章介绍STM32Fxx系统低功耗模式。

https://www.waveshare.net/study/article-653-1.html

以及STM32CubeMX系列教程

https://www.waveshare.net/study/portal.php?mod=list&catid=40&page=1

一.低功耗模式介绍

        系统提供了多个低功耗模式,可在 CPU 不需要运行时(例如等待外部事件时)节省功耗。由用户根据应用选择具体的低功耗模式,以在低功耗、短启动时间和可用唤醒源之间寻求最佳平衡。
        当系统断电时,仍然可以通过电池供电保留备份域的数据。备份域中包含RTC实时时钟,4KB备份SRAM以及调压器,调压器为备份域和待机电路以外数字电路供电,输出电压约为1.2V。

器件有三个低功耗模式:
  •     睡眠模式( Cortex®-M7 内核停止,外设保持运行)
  •     停止模式(所有时钟都停止)
  •     待机模式(1.2 V 域断电)
此外,可通过下列方法之一降低运行模式的功耗:
  •     降低系统时钟速度
  •     不使用 APBx 和 AHBx 外设时,将对应的外设时钟关闭。
睡眠模式只是内核停止,外接还能继续工作,I/O管脚状态没有改变。
停止模式是在睡眠模式的基础上把所有的时钟都停止了,振荡器也被禁止。此时所有外设已经停止工作。
待机模式基于 Cortex®-M7 深度睡眠模式,此时内核停止,外设也停止工作,1.2V域断电。除备份域和待机电路中的寄存器外,其他全部停止工作,SRAM和寄存器内容将丢失。只是备份域中RTC继续工作,备份ARAM数据不会丢失继续保存。此时三种低功耗模式中,待机模式可达到最低功耗。

转存失败重新上传取消

进入低功耗模式
        当 MCU 执行 WFI(等待中断)或 WFE(等待事件)指令,或者当 Cortex®-M7 系统控制寄存器中的 SLEEPONEXIT 位在从 ISR 恢复期间置 1 时,将进入低功耗模式。仅当没有中断和事件挂起时,才能通过 WFI 或 WFE 进入低功耗模式。
退出低功耗模式
在睡眠和停止模式下, MCU 根据进入低功耗模式的方式退出低功耗模式。
     如果使用 WFI 指令或从 ISR 恢复的方式进入低功耗模式,则通过 NVIC 应答的任何外设中断均可唤醒器件
     如果使用 WFE 指令进入低功耗模式,则 MCU 会在事件发生时立即退出低功耗模式
在待机模式下, MCU 退出低功耗模式的方式包括:外部复位(NRST 引脚)、 IWDG(独立看门狗) 复位、已使能WKUPx 引脚之一的上升沿或者 RTC 事件。stm32F7xx有六个WKUP 引脚(PA0/PA2/PC1/PC13/PI8/PI11)。
二.实验例程
        本章程序在串口printf工程的基础上修改,复制串口printf的工程,修改文件夹名。击STM32F746I.ioc打开STM32cubeMX的工程文件重新配置。RTC选择内部唤醒开启RTC。PA0(WAKEUP管脚)配置为中断外部中断引脚,同时配置LED管脚。

配置RTC时间和日期,其他为默认配置。Wake UP唤醒设置在程序中设置,在此不作设置。

 

开启外部中断0号线中断。

 

生成报告以及代码,编译程序。在stm32f7xx_hal_pwr.h头文件中可以看到低功耗控制函数。
下载这两个应用程序文件,c文件放在工程目录下Src文件夹中,头文件放在Inc文件中,并在工程中添加刚才的应用程序文件。

stm32f7xx_lp_modes.zip

 

 

打开stm32fxx_lp_modes.c文件中,里面有五个低功耗测试程序。在stm32fxx_lp_modes.h文件中,可以看到函数声明和宏定义低功耗模式。而已通过去掉相应行的注释选择一种低功耗模式。
01/* Exported constants --------------------------------------------------------*/
02#if !defined (SLEEP_MODE) && !defined (STOP_MODE) && !defined (STANDBY_MODE)\
03 && !defined (STANDBY_RTC_MODE) && !defined (STANDBY_BKPSRAM_MODE)
04/* Uncomment the corresponding line to select the STM32F7xx Low Power mode */
05//#define SLEEP_MODE
06#define STOP_MODE
07//#define STANDBY_MODE
08//#define STANDBY_RTC_MODE
09//#define STANDBY_BKPSRAM_MODE
10#endif
11  
12#if !defined (SLEEP_MODE) && !defined (STOP_MODE) && !defined (STANDBY_MODE)\
13 && !defined (STANDBY_RTC_MODE) && !defined (STANDBY_BKPSRAM_MODE)
14 #error "Please select first the target STM32F7xx Low Power mode to be measured (in stm32f7xx_lp_modes.h file)"
15#endif
16  
17/* Exported macro ------------------------------------------------------------*/
18/* Exported functions ------------------------------------------------------- */
19void SleepMode_Measure(void);
20void StopMode_Measure(void);
21void StandbyMode_Measure(void);
22void StandbyRTCMode_Measure(void);
23void StandbyBKPSRAMMode_Measure(void);
在这里补充一下C语言的语法知识.#if ... #endif为调节编译语句,只有满足条件时才编译中间部分的语句。
第一个#if #endif语句的意思是如果没有宏定义相应低功耗模式的则编译中间的宏定义。
第二个#if #endif语句的意思是如果还是没有相应的低功耗模式宏定义,则提示错误。此时编译程序时会提示上面的错误提示信息。
在main.c文件前面添加头文件,定义用户按键标志变化和声明错误处理函数。
01/* USER CODE BEGIN Includes */
02#include "stm32f7xx_lp_modes.h"
03/* USER CODE END Includes */
04 
05/* USER CODE BEGIN PV */
06/* Private variables ---------------------------------------------------------*/
07__IO uint8_t UserButtonStatus = 0;
08/* USER CODE END PV */
09  
10/* Private function prototypes -----------------------------------------------*/
11void SystemClock_Config(void);
12  
13/* USER CODE BEGIN PFP */
14/* Private function prototypes -----------------------------------------------*/
15void Error_Handler(void);
16/* USER CODE END PFP */
在main.c文件后面添加外部中断回调函数和错误处理函数。中断回调函数将按键标志位置1,错误处理函数打印错误信息,然后进行while循环。
01/* USER CODE BEGIN 4 */
02/**
03  * @brief  This function is executed in case of error occurrence.
04  * @param  None
05  * @retval None
06  */
07void Error_Handler(void)
08{
09  printf("something wrong !!!\r\n");
10  while(1)
11  {
12  }
13}
14/**
15  * @brief  EXTI line detection callbacks
16  * @param  GPIO_Pin: Specifies the pins connected EXTI line
17  * @retval None
18  */
19void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
20{
21  UserButtonStatus = 1;
22}
23/* USER CODE END 4 */
        在main.c主函数中添加应用测试程序。程序中不断读取用户按键标志,同时LED1不断闪烁。但有WAKEUP按键按下时,跳出循环,然后等待按键释放,关闭LED1。最后根据stm32fxx_lp_modes.h中的宏定义,进入对应的低功耗模式测试函数。
01  /* USER CODE BEGIN 2 */
02  printf("\r\n********    STM32F7 LowPower Test  *******\r\n");
03  /* USER CODE END 2 */
04  
05  /* Infinite loop */
06  /* USER CODE BEGIN WHILE */
07  while (1)
08  {
09  /* USER CODE END WHILE */
10  
11  /* USER CODE BEGIN 3 */
12    printf("Press WAKEUP button to enter LP modes \r\n\r\n");
13  
14    UserButtonStatus = 0;
15  
16    /* Wait until USER button is pressed to enter the Low Power mode */
17    while(UserButtonStatus == 0x00)
18    {
19      /* Toggle LED1 */
20      HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
21        
22      /* Inserted Delay */
23      HAL_Delay(200);
24    }
25      
26    /* Loop while User button is maintained pressed */
27    while(HAL_GPIO_ReadPin(WAKEUP_GPIO_Port,WAKEUP_Pin) != RESET)
28    {
29    }
30          
31    /* Turn off LED1 */
32    HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
33    
34#if defined (SLEEP_MODE)
35    /* Sleep Mode Entry
36    - System Running at PLL (216MHz)
37    - Flash 5 wait state
38    - Instruction and Data caches ON
39    - Prefetch ON
40    - Code running from Internal FLASH
41    - All peripherals disabled.
42    - Wake-up using EXTI Line (USER Button)
43    */
44    printf("SleepMode!\r\nPress WAKE_UP button to wake up ...\r\n");
45    SleepMode_Measure();
46    printf("\r\nSLEEP_MODE wake up,system running continue ... \r\n");
47          
48#elif defined (STOP_MODE)
49    /* STOP Mode Entry
50    - RTC Clocked by LSI
51    - Regulator in LP mode
52    - HSI, HSE OFF and LSI OFF if not used as RTC Clock source 
53    - No IWDG
54    - FLASH in deep power down mode
55    - Automatic Wake-up using RTC clocked by LSI (after ~20s)
56    */
57    printf("StopMode!\r\nAutomatic Wake-up using RTC clocked by LSI (after ~20s) ...\r\n");
58    StopMode_Measure();
59    MX_USART1_UART_Init();
60    printf("\r\nStopMode wake up ,system running continue \r\n");
61          
62#elif defined (STANDBY_MODE)
63    /* STANDBY Mode Entry
64    - Backup SRAM and RTC OFF
65    - IWDG and LSI OFF
66    - Wake-up using WakeUp Pin (PI.11)
67    */
68    printf("StandbyMode!\r\nPress WAKE_UP button to wake up ...\r\n");
69    StandbyMode_Measure();
70    printf("StandbyMode wake up ,this will  never be running ,something wrong!! \r\n");
71#elif defined (STANDBY_RTC_MODE)
72    /* STANDBY Mode with RTC on LSI Entry
73    - RTC Clocked by LSI
74    - IWDG OFF and LSI OFF if not used as RTC Clock source
75    - Backup SRAM OFF
76    - Automatic Wake-up using RTC clocked by LSI (after ~20s)
77    */
78    printf("StandbyRTCMode!\r\nPress WAKE_UP button to wake up ...\r\n");
79    StandbyRTCMode_Measure();
80    printf("StandbyMode wake up ,this will  never be running ,something wrong!! \r\n");
81      
82#elif defined (STANDBY_BKPSRAM_MODE)
83    /* STANDBY Mode Entry
84    - Backup SRAM ON
85    - IWDG OFF
86    - Wake-up using WakeUp Pin (PI.11)
87    */
88    printf("StandbyBKPSRAMMode!\r\nPress WAKE_UP button to wake up ...\r\n");
89    StandbyBKPSRAMMode_Measure();
90    printf("StandbyBKPSRAMMode wake up ,this will  never be running ,something wrong!! \r\n");
91#endif
92  }
93  /* USER CODE END 3 */
94}
        此处也用到条件编译语句。例如stm32fxx_lp_modes.h头文件中宏定义STOP_MODE。则程序编译的时候只会编译STOP_MODE选项中的语句。其他的语句不会编译进程序,不会写入stm32的flash中。可以在stm32fxx_lp_modes.h头开启不同的宏选择编译对应不同的语句。
下面我们来详细分析一下各种低功耗模式的运行流程。
1.SLEEP_MODE

  php代码:

01/**
02  * @brief  This function configures the system to enter Sleep mode for
03  *         current consumption measurement purpose.
04  *         Sleep Mode
05  *         ========== 
06  *            - System Running at PLL (216MHz)
07  *            - Flash 5 wait state
08  *            - Instruction and Data caches ON
09  *            - Prefetch ON  
10  *            - Code running from Internal FLASH
11  *            - Wakeup using EXTI Line (USER Button)
12  * @param  None
13  * @retval None
14  */
15void SleepMode_Measure(void)
16{
17  
18  /* Suspend Tick increment to prevent wakeup by Systick interrupt.
19     Otherwise the Systick interrupt will wake up the device within 1ms (HAL time base) */
20  HAL_SuspendTick();
21    
22  /* Request to enter SLEEP mode */
23  HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
24    
25  /* Resume Tick interrupt if disabled prior to sleep mode entry */
26  HAL_ResumeTick();
27    
28}
        睡眠模式Cortex®-M7 内核停止,程序以WFI指令进入睡眠模式,所以只要产生任意中断都会退出睡眠模式。所以进入睡眠模式前先调用HAL_SuspendTick()函数挂起系统滴答定时器,否则将会被系统滴答定时器(SysTick)中断在1ms内唤醒。程序运行到HAL_PWR_EnterSLEEPMode()函数时,系统进入睡眠模式,程序停止运行。当按下WAKEUP按键时,触发外部中断0,此时系统被唤醒。继续执行HAL_ResumeTick()语句回复系统滴答定时器。
2.STOP_MODE
01/**
02  * @brief  This function configures the system to enter Stop mode with RTC
03  *         clocked by LSE or LSI  for current consumption measurement purpose.
04  *         STOP Mode with RTC clocked by LSE/LSI
05  *         =====================================  
06  *           - RTC Clocked by LSE or LSI
07  *           - Regulator in LP mode
08  *           - HSI, HSE OFF and LSI OFF if not used as RTC Clock source
09  *           - No IWDG
10  *           - FLASH in deep power down mode
11  *           - Automatic Wakeup using RTC clocked by LSE/LSI (~20s)
12  * @param  None
13  * @retval None
14  */
15void StopMode_Measure(void)
16{
17  RTCHandle.Instance = RTC;
18      
19  /* Configure RTC prescaler and RTC data registers as follow:
20  - Hour Format = Format 24
21  - Asynch Prediv = Value according to source clock
22  - Synch Prediv = Value according to source clock
23  - OutPut = Output Disable
24  - OutPutPolarity = High Polarity
25  - OutPutType = Open Drain */
26  RTCHandle.Init.HourFormat = RTC_HOURFORMAT_24;
27  RTCHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
28  RTCHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV;
29  RTCHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
30  RTCHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
31  RTCHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
32    
33  if(HAL_RTC_Init(&RTCHandle) != HAL_OK)
34  {
35    /* Initialization Error */
36    Error_Handler();
37  }
38    
39  /*## Configure the Wake up timer ###########################################*/
40  /*  RTC Wakeup Interrupt Generation:
41      Wakeup Time Base = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSI))
42      Wakeup Time = Wakeup Time Base * WakeUpCounter
43                  = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSI)) * WakeUpCounter
44      ==> WakeUpCounter = Wakeup Time / Wakeup Time Base
45  
46      To configure the wake up timer to 20s the WakeUpCounter is set to 0xA017:
47        RTC_WAKEUPCLOCK_RTCCLK_DIV = RTCCLK_Div16 = 16
48        Wakeup Time Base = 16 /(~32.768KHz) = ~0,488 ms
49        Wakeup Time = ~20s = 0,488ms  * WakeUpCounter
50        ==> WakeUpCounter = ~20s/0,488ms = 40983 = 0xA017 */
51  HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, 0xA017, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
52  
53  /* FLASH Deep Power Down Mode enabled */
54  HAL_PWREx_EnableFlashPowerDown();
55  
56  /* Enter Stop Mode */
57  HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
58  
59  /* Configures system clock after wake-up from STOP: enable HSE, PLL and select
60  PLL as system clock source (HSE and PLL are disabled in STOP mode) */
61  SYSCLKConfig_STOP();
62    
63  /* Disable Wake-up timer */
64  if(HAL_RTCEx_DeactivateWakeUpTimer(&RTCHandle) != HAL_OK)
65  {
66    /* Initialization Error */
67    Error_Handler();
68  }
69}
       
 停止模式Cortex®-M7 内核停止,外设也停止工作,所有外设时钟也关闭。此处设置了RTC唤醒。RTC时钟配置为外部时钟,频率为32.768KHz。经过16分频后的时基为16 /(~32.768KHz) = ~0,488 ms。若要20s后唤醒,则唤醒计数器的值为~20s/0,488ms = 40983 = 0xA017。由于停止模式PLL、HSI、HSE RC振荡器均被禁止,所以系统被唤醒(RTC唤醒或WAKUP按键外部中断唤醒)后需要重新配置系统时钟,同时关闭WAKEUP定时器。
        由于外设时钟停止,所以程序返回main()函数中也需要重新初始化串口才能打印输出信息。
01#elif defined (STOP_MODE)
02    /* STOP Mode Entry
03    - RTC Clocked by LSI
04    - Regulator in LP mode
05    - HSI, HSE OFF and LSI OFF if not used as RTC Clock source 
06    - No IWDG
07    - FLASH in deep power down mode
08    - Automatic Wake-up using RTC clocked by LSI (after ~20s)
09    */
10    printf("StopMode!\r\nAutomatic Wake-up using RTC clocked by LSI (after ~20s) ...\r\n");
11    StopMode_Measure();
12    MX_USART1_UART_Init();
13    printf("\r\nStopMode wake up ,system running continue \r\n");
3.STANDBY_MODE
01/**
02  * @brief  This function configures the system to enter Standby mode for
03  *         current consumption measurement purpose.
04  *         STANDBY Mode
05  *         ============
06  *           - Backup SRAM and RTC OFF
07  *           - IWDG and LSI OFF
08  *           - Wakeup using WakeUp Pin (PI.11)
09  * @param  None
10  * @retval None
11  */
12void StandbyMode_Measure(void)
13{
14  /* Disable all used wakeup sources: Pin1(PA.0) */
15  HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
16    
17  /* Clear the related wakeup pin flag */
18  __HAL_PWR_CLEAR_WAKEUP_FLAG(PWR_WAKEUP_PIN_FLAG1);
19    
20  /* Re-enable all used wakeup sources: Pin1(PA.0) */
21  HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
22  
23  /* Request to enter STANDBY mode  */
24  HAL_PWR_EnterSTANDBYMode();
25}
        待机模式Cortex®-M7 深度睡眠模式,此时内核停止,外设也停止工作,1.2V域断电,SRAM和寄存器内容将丢失。待机模式唤醒后是重新运行程序,相当于重启,而不是在程序原来的位置继续运行。待机模式只能从WAKEUP引脚上升沿或下降沿,RTC,复位引脚,IWDG(独立看门狗) 复位唤醒。不能通过其他中断唤醒。前面睡眠模式和停止模式可以通过WAKEUP引脚的外部中断唤醒,但是待机模式不能通过外部中断唤醒。
        程序中先失能WAKUP引脚,清除唤醒引脚标志,然后使能WAKEUP 1号管脚,即PA0.stm32F7xx WAKEUP引脚一共有五个,分别为PA0/PA2/PC1/PC13/PI8/PI11。
        待机模式中只有备份域还在工作,可以通过RTC唤醒和通过备SRAM备份数据。具体可以参考程序中STANDBY_RTC_MODE和STANDBY_BKPSRAM_MODE。这里不在详细讲解。
        修改stm32fxx_lp_modes.h头文件中的宏定义注释选择对应低功耗模式,编译程序并下载到开发板。打开串口调试助手,设置波特率为115200。按下Open746I开发板中WAKEUP按键进入低功耗模式,再次按下按键或者等待20s退出低功耗模式。

这篇关于STM32CubeMX系列教程14:电源控制器(PWR)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/381380

相关文章

Ubuntu固定虚拟机ip地址的方法教程

《Ubuntu固定虚拟机ip地址的方法教程》本文详细介绍了如何在Ubuntu虚拟机中固定IP地址,包括检查和编辑`/etc/apt/sources.list`文件、更新网络配置文件以及使用Networ... 1、由于虚拟机网络是桥接,所以ip地址会不停地变化,接下来我们就讲述ip如何固定 2、如果apt安

PyCharm 接入 DeepSeek最新完整教程

《PyCharm接入DeepSeek最新完整教程》文章介绍了DeepSeek-V3模型的性能提升以及如何在PyCharm中接入和使用DeepSeek进行代码开发,本文通过图文并茂的形式给大家介绍的... 目录DeepSeek-V3效果演示创建API Key在PyCharm中下载Continue插件配置Con

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

Spring Boot整合log4j2日志配置的详细教程

《SpringBoot整合log4j2日志配置的详细教程》:本文主要介绍SpringBoot项目中整合Log4j2日志框架的步骤和配置,包括常用日志框架的比较、配置参数介绍、Log4j2配置详解... 目录前言一、常用日志框架二、配置参数介绍1. 日志级别2. 输出形式3. 日志格式3.1 PatternL

MySQL8.2.0安装教程分享

《MySQL8.2.0安装教程分享》这篇文章详细介绍了如何在Windows系统上安装MySQL数据库软件,包括下载、安装、配置和设置环境变量的步骤... 目录mysql的安装图文1.python访问网址2javascript.点击3.进入Downloads向下滑动4.选择Community Server5.

CentOS系统Maven安装教程分享

《CentOS系统Maven安装教程分享》本文介绍了如何在CentOS系统中安装Maven,并提供了一个简单的实际应用案例,安装Maven需要先安装Java和设置环境变量,Maven可以自动管理项目的... 目录准备工作下载并安装Maven常见问题及解决方法实际应用案例总结Maven是一个流行的项目管理工具

本地私有化部署DeepSeek模型的详细教程

《本地私有化部署DeepSeek模型的详细教程》DeepSeek模型是一种强大的语言模型,本地私有化部署可以让用户在自己的环境中安全、高效地使用该模型,避免数据传输到外部带来的安全风险,同时也能根据自... 目录一、引言二、环境准备(一)硬件要求(二)软件要求(三)创建虚拟环境三、安装依赖库四、获取 Dee

MySql9.1.0安装详细教程(最新推荐)

《MySql9.1.0安装详细教程(最新推荐)》MySQL是一个流行的关系型数据库管理系统,支持多线程和多种数据库连接途径,能够处理上千万条记录的大型数据库,本文介绍MySql9.1.0安装详细教程,... 目录mysql介绍:一、下载 Mysql 安装文件二、Mysql 安装教程三、环境配置1.右击此电脑

在idea中使用mysql数据库超详细教程

《在idea中使用mysql数据库超详细教程》:本文主要介绍如何在IntelliJIDEA中连接MySQL数据库,并使用控制台执行SQL语句,还详细讲解了如何使用MyBatisGenerator快... 目录一、连接mysql二、使用mysql三、快速生成实体、接口、sql文件总结一、连接mysql在ID