[开发工具] 使用Arduino开发STM32F103能使用低功耗模式吗

[复制链接]
 楼主| 捉虫天师 发表于 2024-4-19 17:17 | 显示全部楼层 |阅读模式
不知道如何在Arduino中使用低功耗模式,有前辈分享一下吗
天灵灵地灵灵 发表于 2024-4-19 17:24 | 显示全部楼层
在Arduino开发环境中,你可以使用适当的库和函数来配置STM32F103的低功耗模式。例如,你可以使用STM32的库函数来设置特定的低功耗模式,然后通过在程序中调用相应的函数来进入和退出低功耗模式。例如,你可以使用 STM32F1 库中的 standby() 函数来使STM32F103进入待机模式。
天灵灵地灵灵 发表于 2024-4-19 17:25 | 显示全部楼层
  1. #include <STM32LowPower.h>

  2. const int buttonPin = PA0;  // Button connected to pin PA0
  3. const int ledPin = PC13;    // LED connected to pin PC13

  4. void setup() {
  5.   pinMode(buttonPin, INPUT_PULLUP);
  6.   pinMode(ledPin, OUTPUT);
  7. }

  8. void loop() {
  9.   // Check if button is pressed
  10.   if (digitalRead(buttonPin) == LOW) {
  11.     // Button pressed, enter low power mode
  12.     digitalWrite(ledPin, HIGH); // Turn on LED
  13.     delay(100);  // Wait for button debounce
  14.     while (digitalRead(buttonPin) == LOW) {}  // Wait for button release
  15.     delay(100);  // Wait for button debounce
  16.     digitalWrite(ledPin, LOW);  // Turn off LED
  17.     STM32LowPower.standby();  // Enter standby mode
  18.   }
  19. }
天灵灵地灵灵 发表于 2024-4-19 17:25 | 显示全部楼层
安装低功耗函数库就可以使用这个头文件了。
天灵灵地灵灵 发表于 2024-4-19 17:26 | 显示全部楼层
在此示例中,我们使用了 STM32LowPower 库来进入待机模式。当按钮按下时,LED亮起,然后等待按钮释放,并且进入待机模式。待机模式中,微控制器的大部分功能都被关闭以降低功耗。当再次按下按钮时,LED灭掉,微控制器唤醒并从 standby() 函数返回,继续执行 loop() 函数中的代码。
天灵灵地灵灵 发表于 2024-4-19 17:26 | 显示全部楼层
  1. /**
  2. ******************************************************************************
  3. * [url=home.php?mod=space&uid=288409]@file[/url]    STM32LowPower.h
  4. * [url=home.php?mod=space&uid=187600]@author[/url]  Frederic Pillon
  5. * [url=home.php?mod=space&uid=247401]@brief[/url]   Provides a STM32 Low Power interface with Arduino
  6. *
  7. ******************************************************************************
  8. * @attention
  9. *
  10. * <h2><center>&copy; COPYRIGHT(c) 2020 STMicroelectronics</center></h2>
  11. *
  12. * Redistribution and use in source and binary forms, with or without modification,
  13. * are permitted provided that the following conditions are met:
  14. *   1. Redistributions of source code must retain the above copyright notice,
  15. *      this list of conditions and the following disclaimer.
  16. *   2. Redistributions in binary form must reproduce the above copyright notice,
  17. *      this list of conditions and the following disclaimer in the documentation
  18. *      and/or other materials provided with the distribution.
  19. *   3. Neither the name of STMicroelectronics nor the names of its contributors
  20. *      may be used to endorse or promote products derived from this software
  21. *      without specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  27. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  29. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  30. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  31. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  32. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ******************************************************************************
  35. */

  36. #ifndef _STM32_LOW_POWER_H_
  37. #define _STM32_LOW_POWER_H_

  38. #include <Arduino.h>

  39. #include "low_power.h"

  40. // Check if PWR HAL enable in variants/board_name/stm32yzxx_hal_conf.h
  41. #ifndef HAL_PWR_MODULE_ENABLED
  42.   #error "PWR configuration is missing. Check flag HAL_PWR_MODULE_ENABLED in variants/board_name/stm32yzxx_hal_conf.h"
  43. #endif

  44. #include "STM32RTC.h"

  45. enum LP_Mode : uint8_t {
  46.   IDLE_MODE,
  47.   SLEEP_MODE,
  48.   DEEP_SLEEP_MODE,
  49.   SHUTDOWN_MODE
  50. };

  51. typedef void (*voidFuncPtrVoid)(void) ;

  52. class STM32LowPower {
  53.   public:
  54.     STM32LowPower();

  55.     void begin(void);

  56.     void idle(uint32_t ms = 0);
  57.     void idle(int ms)
  58.     {
  59.       idle((uint32_t)ms);
  60.     }

  61.     void sleep(uint32_t ms = 0);
  62.     void sleep(int ms)
  63.     {
  64.       sleep((uint32_t)ms);
  65.     }

  66.     void deepSleep(uint32_t ms = 0);
  67.     void deepSleep(int ms)
  68.     {
  69.       deepSleep((uint32_t)ms);
  70.     }

  71.     void shutdown(uint32_t ms = 0);
  72.     void shutdown(int ms)
  73.     {
  74.       shutdown((uint32_t)ms);
  75.     }

  76.     void attachInterruptWakeup(uint32_t pin, voidFuncPtrVoid callback, uint32_t mode, LP_Mode LowPowerMode = SHUTDOWN_MODE);

  77.     void enableWakeupFrom(HardwareSerial *serial, voidFuncPtrVoid callback);
  78.     void enableWakeupFrom(STM32RTC *rtc, voidFuncPtr callback, void *data = NULL);

  79.   private:
  80.     bool _configured;     // Low Power mode initialization status
  81.     serial_t *_serial;    // Serial for wakeup from deep sleep
  82.     bool _rtc_wakeup;     // Is RTC wakeup?
  83.     void programRtcWakeUp(uint32_t ms, LP_Mode lp_mode);
  84.     void setAlarmTime(uint32_t ms, STM32RTC &rtc);

  85. };

  86. extern STM32LowPower LowPower;

  87. #endif // _STM32_LOW_POWER_H_
天灵灵地灵灵 发表于 2024-4-19 17:27 | 显示全部楼层
  1. /**
  2. ******************************************************************************
  3. * @file    STM32LowPower.cpp
  4. * @author  Frederic Pillon
  5. * @brief   Provides a STM32 Low Power interface with Arduino
  6. *
  7. ******************************************************************************
  8. * @attention
  9. *
  10. * <h2><center>&copy; COPYRIGHT(c) 2020 STMicroelectronics</center></h2>
  11. *
  12. * Redistribution and use in source and binary forms, with or without modification,
  13. * are permitted provided that the following conditions are met:
  14. *   1. Redistributions of source code must retain the above copyright notice,
  15. *      this list of conditions and the following disclaimer.
  16. *   2. Redistributions in binary form must reproduce the above copyright notice,
  17. *      this list of conditions and the following disclaimer in the documentation
  18. *      and/or other materials provided with the distribution.
  19. *   3. Neither the name of STMicroelectronics nor the names of its contributors
  20. *      may be used to endorse or promote products derived from this software
  21. *      without specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  27. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  29. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  30. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  31. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  32. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ******************************************************************************
  35. */

  36. #include "STM32LowPower.h"

  37. STM32LowPower LowPower;


  38. STM32LowPower::STM32LowPower()
  39. {
  40.   _configured = false;
  41.   _serial = NULL;
  42.   _rtc_wakeup = false;
  43. }

  44. /**
  45.   * @brief  Initializes the low power mode
  46.   * @param  None
  47.   * @retval None
  48.   */
  49. void STM32LowPower::begin(void)
  50. {
  51.   LowPower_init();
  52.   _configured = true;
  53. }

  54. /**
  55.   * @brief  Enable the idle low power mode (STM32 sleep). Exit this mode on
  56.   *         interrupt or in n milliseconds.
  57.   * @param  ms: optional delay before leave the idle mode (default: 0).
  58.   * @retval None
  59.   */
  60. void STM32LowPower::idle(uint32_t ms)
  61. {
  62.   if ((ms != 0) || _rtc_wakeup) {
  63.     programRtcWakeUp(ms, IDLE_MODE);
  64.   }
  65.   LowPower_sleep(PWR_MAINREGULATOR_ON);
  66. }

  67. /**
  68.   * @brief  Enable the sleep low power mode (STM32 sleep). Exit this mode on
  69.   *         interrupt or in n milliseconds.
  70.   * @param  ms: optional delay before leave the sleep mode (default: 0).
  71.   * @retval None
  72.   */
  73. void STM32LowPower::sleep(uint32_t ms)
  74. {
  75.   if ((ms != 0) || _rtc_wakeup) {
  76.     programRtcWakeUp(ms, SLEEP_MODE);
  77.   }
  78. #if defined(PWR_LOWPOWERREGULATOR_ON)
  79.   LowPower_sleep(PWR_LOWPOWERREGULATOR_ON);
  80. #else
  81.   LowPower_sleep(PWR_MAINREGULATOR_ON);
  82. #endif

  83. }

  84. /**
  85.   * @brief  Enable the deepsleep low power mode (STM32 stop). Exit this mode on
  86.   *         interrupt or in n milliseconds.
  87.   * @param  ms: optional delay before leave the deepSleep mode (default: 0).
  88.   * @retval None
  89.   */
  90. void STM32LowPower::deepSleep(uint32_t ms)
  91. {
  92.   if ((ms != 0) || _rtc_wakeup) {
  93.     programRtcWakeUp(ms, DEEP_SLEEP_MODE);
  94.   }
  95.   LowPower_stop(_serial);
  96. }

  97. /**
  98.   * @brief  Enable the shutdown low power mode (STM32 shutdown or standby mode).
  99.   *          Exit this mode on interrupt or in n milliseconds.
  100.   * @param  ms: optional delay before leave the shutdown mode (default: 0).
  101.   * @retval None
  102.   */
  103. void STM32LowPower::shutdown(uint32_t ms)
  104. {
  105.   if ((ms != 0) || _rtc_wakeup) {
  106.     programRtcWakeUp(ms, SHUTDOWN_MODE);
  107.   }
  108.   /* Get the rtc object to know if it is configured */
  109.   STM32RTC &rtc = STM32RTC::getInstance();
  110.   LowPower_shutdown(rtc.isConfigured());
  111. }

  112. /**
  113.   * @brief  Enable GPIO pin in interrupt mode. If the pin is a wakeup pin, it is
  114.   *         configured as wakeup source.
  115.   * @param  pin:  pin number
  116.   * @param  callback: pointer to callback function.
  117.   * @param  mode: pin interrupt mode (HIGH, LOW, RISING, FALLING or CHANGE)
  118.   * @param  LowPowerMode: Low power mode which will be used
  119.   *         (IDLE_MODE, SLEEP_MODE, DEEP_SLEEP_MODE, SHUTDOWN_MODE)
  120.   *         In case of SHUTDOWN_MODE only, Wakeup pin capability is activated
  121.   * @retval None
  122.   */
  123. void STM32LowPower::attachInterruptWakeup(uint32_t pin, voidFuncPtrVoid callback, uint32_t mode, LP_Mode LowPowerMode)
  124. {
  125.   attachInterrupt(pin, callback, mode);

  126.   if (LowPowerMode == SHUTDOWN_MODE) {
  127.     // If Gpio is a Wake up pin activate it for shutdown (standby or shutdown stm32)
  128.     LowPower_EnableWakeUpPin(pin, mode);
  129.   }
  130. }

  131. /**
  132.   * @brief  Enable a serial interface as a wakeup source.
  133.   * @param  serial: pointer to a HardwareSerial
  134.   * @param  callback: pointer to callback function called when leave the low power
  135.   *                   mode.
  136.   * @retval None
  137.   */
  138. void STM32LowPower::enableWakeupFrom(HardwareSerial *serial, voidFuncPtrVoid callback)
  139. {
  140.   if (serial != NULL) {
  141.     _serial = &(serial->_serial);
  142.     // Reconfigure serial for low power mode (using HSI as clock source)
  143.     serial->configForLowPower();
  144.     LowPower_EnableWakeUpUart(_serial, callback);
  145.   }
  146. }

  147. /**
  148.   * @brief  Attach a callback to a RTC alarm.
  149.   * @param  rtc: pointer to a STM32RTC. Can be NULL as RTC is a Singleton.
  150.   * @param  callback: pointer to callback function called when leave the low power
  151.   *                   mode.
  152.   * @param  data: optional pointer to callback data parameters (default NULL).
  153.   * @retval None
  154.   */
  155. void STM32LowPower::enableWakeupFrom(STM32RTC *rtc, voidFuncPtr callback, void *data)
  156. {
  157.   if (rtc == NULL) {
  158.     rtc = &(STM32RTC::getInstance());
  159.   }
  160.   _rtc_wakeup = true;
  161.   rtc->attachInterrupt(callback, data);
  162. }

  163. /**
  164.   * @brief  Configure the RTC alarm
  165.   * @param  ms: time of the alarm in milliseconds.
  166.   * @param  lp_mode: low power mode targeted.
  167.   * @retval None
  168.   */
  169. void STM32LowPower::programRtcWakeUp(uint32_t ms, LP_Mode lp_mode)
  170. {
  171.   STM32RTC &rtc = STM32RTC::getInstance();
  172.   STM32RTC::Source_Clock clkSrc = rtc.getClockSource();

  173.   switch (lp_mode) {
  174.     case IDLE_MODE:
  175.     case SLEEP_MODE:
  176.       break;
  177.     // LSI or LSE must be selected as clock source to wakeup the device.
  178.     case DEEP_SLEEP_MODE:
  179.       clkSrc = (clkSrc == STM32RTC::HSE_CLOCK) ? STM32RTC::LSI_CLOCK : clkSrc;
  180.       break;
  181.     default:
  182.     case SHUTDOWN_MODE:
  183. #if defined(PWR_CR1_LPMS)
  184.       // For shutdown mode LSE have to be used
  185.       clkSrc = STM32RTC::LSE_CLOCK;
  186. #else
  187.       // LSE or LSI
  188.       clkSrc = (clkSrc == STM32RTC::HSE_CLOCK) ? STM32RTC::LSI_CLOCK : clkSrc;
  189. #endif
  190.       break;
  191.   }
  192.   rtc.configForLowPower(clkSrc);

  193.   setAlarmTime(ms, rtc);
  194. }

  195. static bool isLeapYear(uint8_t year2k)
  196. {
  197.   int year = year2k + 2000;

  198.   // if year not divisible by 4 - not a leap year
  199.   // else if year divisible by 4 and not by 100 - a leap year
  200.   // else if year divisible by 400 - a leap year
  201.   return (year % 4 != 0) ? false : (year % 100 != 0) ? true : year % 400 == 0;
  202. }

  203. void STM32LowPower::setAlarmTime(uint32_t ms, STM32RTC &rtc)
  204. {
  205.   if (ms != 0) {
  206.     uint16_t subSecondsToAdd = ms % 1000;

  207.     ms = ms / 1000;
  208.     uint8_t daysToAdd = ms / 86400;
  209.     uint8_t hoursToAdd = (ms - daysToAdd * 86400) / 3600;
  210.     uint8_t minutesToAdd = (ms - daysToAdd * 86400 - hoursToAdd * 3600) / 60;
  211.     uint8_t secondsToAdd = (ms - daysToAdd * 86400 - hoursToAdd * 3600 - minutesToAdd * 60);

  212.     uint8_t hrCurrent, minCurrent, secCurrent;
  213.     uint32_t subSecondsCurrent;
  214.     STM32RTC::AM_PM period;
  215.     rtc.getTime(&hrCurrent, &minCurrent, &secCurrent, &subSecondsCurrent, &period);

  216.     uint8_t weekDay, currentDay, currentMonth, currentYear;
  217.     rtc.getDate(&weekDay, &currentDay, &currentMonth, &currentYear);

  218.     uint32_t ss = subSecondsCurrent + subSecondsToAdd;
  219.     if (ss >= 1000) {
  220.       ss -= 1000;
  221.       secondsToAdd++;
  222.     }

  223.     if (secondsToAdd >= 60) {
  224.       secondsToAdd = 0;
  225.       minutesToAdd++;
  226.     }
  227.     uint8_t s = secCurrent + secondsToAdd;
  228.     if (s >= 60) {
  229.       s -= 60;
  230.       minutesToAdd++;
  231.     }

  232.     if (minutesToAdd >= 60) {
  233.       minutesToAdd -= 60;
  234.       hoursToAdd++;
  235.     }
  236.     uint8_t m = minCurrent + minutesToAdd;
  237.     if (m >= 60) {
  238.       m -= 60;
  239.       hoursToAdd++;
  240.     }

  241.     if (hoursToAdd >= 24) {
  242.       hoursToAdd -= 24;
  243.       daysToAdd++;
  244.     }
  245.     uint8_t h = hrCurrent + hoursToAdd;
  246.     if (rtc._format == STM32RTC::Hour_Format::HOUR_12) {
  247.       if (h >= 24) {
  248.         h -= 24;
  249.         daysToAdd++;
  250.       } else if (h >= 12) {
  251.         if (period == STM32RTC::AM_PM::AM) {
  252.           period = STM32RTC::AM_PM::PM;
  253.         } else {
  254.           period = STM32RTC::AM_PM::AM;
  255.           daysToAdd++;
  256.         }

  257.         if (h > 12) {
  258.           h -= 12;
  259.         }
  260.       }
  261.     } else if (h >= 24) {
  262.       h -= 24;
  263.       daysToAdd++;
  264.     }

  265.     // numbers of days in each month (february is calculated based on leap year)
  266.     static uint8_t daysInMonths[] = {31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  267.     uint8_t endDay;
  268.     if (currentMonth == 2) {
  269.       endDay = isLeapYear(currentYear) ? 29 : 28;
  270.     } else {
  271.       endDay = daysInMonths[currentMonth - 1];
  272.     }

  273.     uint8_t d = currentDay + daysToAdd;
  274.     if (d > endDay) {
  275.       d -= endDay;
  276.     }

  277.     // month-year overflow isn't handled because its not supported by RTC's alarm

  278.     rtc.setAlarmTime(h, m, s, ss, period);
  279.     rtc.setAlarmDay(d);
  280.     rtc.enableAlarm(STM32RTC::Alarm_Match::MATCH_DHHMMSS);
  281.   }
  282. }
天灵灵地灵灵 发表于 2024-4-19 17:27 | 显示全部楼层
  1. /**
  2.   ******************************************************************************
  3.   * @file    LowPower.c
  4.   * @author  Frederic Pillon
  5.   * @brief   Provides a Low Power interface
  6.   *
  7.   ******************************************************************************
  8.   * @attention
  9.   *
  10.   * Copyright (c) 2020-2021, STMicroelectronics
  11.   * All rights reserved.
  12.   *
  13.   * This software component is licensed by ST under BSD 3-Clause license,
  14.   * the "License"; You may not use this file except in compliance with the
  15.   * License. You may obtain a copy of the License at:
  16.   *                        opensource.org/licenses/BSD-3-Clause
  17.   *
  18.   ******************************************************************************
  19.   */

  20. #include "Arduino.h"
  21. #include "low_power.h"
  22. #include "stm32yyxx_ll_pwr.h"

  23. #if defined(HAL_PWR_MODULE_ENABLED) && !defined(HAL_PWR_MODULE_ONLY)

  24. #if defined(HAL_UART_MODULE_ENABLED) && !defined(HAL_UART_MODULE_ONLY) \
  25.   && (defined(UART_IT_WUF) || defined(LPUART1_BASE))
  26.   #define UART_WKUP_SUPPORT
  27. #endif

  28. #ifdef __cplusplus
  29. extern "C" {
  30. #endif

  31. #if defined(UART_WKUP_SUPPORT)
  32. /* Save UART handler for callback */
  33. static UART_HandleTypeDef *WakeUpUart = NULL;
  34. #endif
  35. /* Save callback pointer */
  36. static void (*WakeUpUartCb)(void) = NULL;

  37. #if defined(PWR_FLAG_WUF)
  38. #define PWR_FLAG_WU PWR_FLAG_WUF
  39. #elif defined(PWR_WAKEUP_ALL_FLAG)
  40. #define PWR_FLAG_WU PWR_WAKEUP_ALL_FLAG
  41. #endif
  42. #if defined(PWR_FLAG_SBF)
  43. #define PWR_FLAG_SB PWR_FLAG_SBF
  44. #endif

  45. /**
  46.   * @brief  Initialize low power mode
  47.   * @param  None
  48.   * @retval None
  49.   */
  50. void LowPower_init()
  51. {
  52. #if defined(__HAL_RCC_PWR_CLK_ENABLE)
  53.   /* Enable Power Clock */
  54.   __HAL_RCC_PWR_CLK_ENABLE();
  55. #endif

  56. #if defined(PWR_CR_DBP) || defined(PWR_CR1_DBP) || defined(PWR_DBPR_DBP)
  57.   /* Allow access to Backup domain */
  58.   HAL_PWR_EnableBkUpAccess();
  59. #endif

  60. #ifdef __HAL_RCC_WAKEUPSTOP_CLK_CONFIG
  61.   /* Ensure that HSI is wake-up system clock */
  62.   __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);
  63. #endif
  64.   /* Check if the system was resumed from StandBy mode */
  65.   if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET) {
  66.     /* Clear Standby flag */
  67.     __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
  68.   }

  69.   /* Clear all related wakeup flags */
  70.   __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
  71. }

  72. /**
  73.   * @brief  Configure a pin as wakeup source if compatible.
  74.   * @param  pin: pin to configure
  75.   * @param  mode: pin mode (edge or state). The configuration have to be compatible.
  76.   * @retval None
  77.   */
  78. void LowPower_EnableWakeUpPin(uint32_t pin, uint32_t mode)
  79. {
  80. #if !defined(PWR_WAKEUP_PIN1_HIGH)
  81.   UNUSED(mode);
  82. #endif
  83.   uint32_t wkup_pin = 0;
  84.   PinName p = digitalPinToPinName(pin);
  85.   if (p != NC) {
  86. #ifdef PWR_WAKEUP_PIN1
  87.     if ((p == SYS_WKUP1)
  88. #ifdef PWR_WAKEUP_PIN1_1
  89.         || (p == SYS_WKUP1_1)
  90. #endif
  91. #ifdef PWR_WAKEUP_PIN1_2
  92.         || (p == SYS_WKUP1_2)
  93. #endif
  94.        ) {
  95.       wkup_pin = PWR_WAKEUP_PIN1;
  96. #ifdef PWR_WAKEUP_PIN1_HIGH
  97.       if (mode != RISING) {
  98.         wkup_pin = PWR_WAKEUP_PIN1_LOW;
  99.       }
  100. #endif
  101.     }
  102. #endif /* PWR_WAKEUP_PIN1 */
  103. #ifdef PWR_WAKEUP_PIN2
  104.     if ((p == SYS_WKUP2)
  105. #ifdef PWR_WAKEUP_PIN2_1
  106.         || (p == SYS_WKUP2_1)
  107. #endif
  108. #ifdef PWR_WAKEUP_PIN2_2
  109.         || (p == SYS_WKUP2_2)
  110. #endif
  111.        ) {
  112.       wkup_pin = PWR_WAKEUP_PIN2;
  113. #ifdef PWR_WAKEUP_PIN2_HIGH
  114.       if (mode != RISING) {
  115.         wkup_pin = PWR_WAKEUP_PIN2_LOW;
  116.       }
  117. #endif
  118.     }
  119. #endif /* PWR_WAKEUP_PIN2 */
  120. #ifdef PWR_WAKEUP_PIN3
  121.     if ((p == SYS_WKUP3)
  122. #ifdef PWR_WAKEUP_PIN3_1
  123.         || (p == SYS_WKUP3_1)
  124. #endif
  125. #ifdef PWR_WAKEUP_PIN3_2
  126.         || (p == SYS_WKUP3_2)
  127. #endif
  128.        ) {
  129.       wkup_pin = PWR_WAKEUP_PIN3;
  130. #ifdef PWR_WAKEUP_PIN3_HIGH
  131.       if (mode != RISING) {
  132.         wkup_pin = PWR_WAKEUP_PIN3_LOW;
  133.       }
  134. #endif
  135.     }
  136. #endif /* PWR_WAKEUP_PIN3 */
  137. #ifdef PWR_WAKEUP_PIN4
  138.     if ((p == SYS_WKUP4)
  139. #ifdef PWR_WAKEUP_PIN4_1
  140.         || (p == SYS_WKUP4_1)
  141. #endif
  142. #ifdef PWR_WAKEUP_PIN4_2
  143.         || (p == SYS_WKUP4_2)
  144. #endif
  145.        ) {
  146.       wkup_pin = PWR_WAKEUP_PIN4;
  147. #ifdef PWR_WAKEUP_PIN4_HIGH
  148.       if (mode != RISING) {
  149.         wkup_pin = PWR_WAKEUP_PIN4_LOW;
  150.       }
  151. #endif
  152.     }
  153. #endif /* PWR_WAKEUP_PIN4 */
  154. #ifdef PWR_WAKEUP_PIN5
  155.     if ((p == SYS_WKUP5)
  156. #ifdef PWR_WAKEUP_PIN5_1
  157.         || (p == SYS_WKUP5_1)
  158. #endif
  159. #ifdef PWR_WAKEUP_PIN5_2
  160.         || (p == SYS_WKUP5_2)
  161. #endif
  162.        ) {
  163.       wkup_pin = PWR_WAKEUP_PIN5;
  164. #ifdef PWR_WAKEUP_PIN5_HIGH
  165.       if (mode != RISING) {
  166.         wkup_pin = PWR_WAKEUP_PIN5_LOW;
  167.       }
  168. #endif
  169.     }
  170. #endif /* PWR_WAKEUP_PIN5 */
  171. #ifdef PWR_WAKEUP_PIN6
  172.     if ((p == SYS_WKUP6)
  173. #ifdef PWR_WAKEUP_PIN6_1
  174.         || (p == SYS_WKUP6_1)
  175. #endif
  176. #ifdef PWR_WAKEUP_PIN6_2
  177.         || (p == SYS_WKUP6_2)
  178. #endif
  179.        ) {
  180.       wkup_pin = PWR_WAKEUP_PIN6;
  181. #ifdef PWR_WAKEUP_PIN6_HIGH
  182.       if (mode != RISING) {
  183.         wkup_pin = PWR_WAKEUP_PIN6_LOW;
  184.       }
  185. #endif
  186.     }
  187. #endif /* PWR_WAKEUP_PIN6 */
  188. #ifdef PWR_WAKEUP_PIN7
  189.     if ((p == SYS_WKUP7)
  190. #ifdef PWR_WAKEUP_PIN7_1
  191.         || (p == SYS_WKUP7_1)
  192. #endif
  193. #ifdef PWR_WAKEUP_PIN7_2
  194.         || (p == SYS_WKUP7_2)
  195. #endif
  196.        ) {
  197.       wkup_pin = PWR_WAKEUP_PIN7;
  198.     }
  199. #endif /* PWR_WAKEUP_PIN7 */
  200. #ifdef PWR_WAKEUP_PIN8
  201.     if ((p == SYS_WKUP8)
  202. #ifdef PWR_WAKEUP_PIN8_1
  203.         || (p == SYS_WKUP8_1)
  204. #endif
  205. #ifdef PWR_WAKEUP_PIN8_2
  206.         || (p == SYS_WKUP8_2)
  207. #endif
  208.        ) {
  209.       wkup_pin = PWR_WAKEUP_PIN8;
  210.     }
  211. #endif /* PWR_WAKEUP_PIN8 */
  212.     if (IS_PWR_WAKEUP_PIN(wkup_pin)) {
  213.       HAL_PWR_EnableWakeUpPin(wkup_pin);
  214.     }
  215.   }
  216. }

  217. #if defined(PWR_CSR_REGLPF)
  218. /**
  219.   * @brief  For STM32L0 and STM32L1, running in LowPower Sleep requires
  220.   *         to slow down frequency to MSI range1.
  221.   * @retval None
  222.   */
  223. void SystemClock_Decrease(void)
  224. {
  225.   RCC_OscInitTypeDef RCC_OscInitStruct = {};
  226.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {};

  227.   /** Configure the main internal regulator output voltage
  228.   */
  229.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  230.   /** Initializes the RCC Oscillators according to the specified parameters
  231.   * in the RCC_OscInitTypeDef structure.
  232.   */
  233.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
  234.   RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  235.   RCC_OscInitStruct.MSICalibrationValue = 0;
  236.   RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_1;
  237.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  238.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
  239.     Error_Handler();
  240.   }

  241.   /** Initializes the CPU, AHB and APB buses clocks
  242.   */
  243.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
  244.                                 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  245.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
  246.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  247.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  248.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  249.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) {
  250.     Error_Handler();
  251.   }
  252. }

  253. #elif defined(STM32L4xx) || defined(STM32L5xx) || defined(STM32WBxx) || defined(STM32WLxx)
  254. /**
  255.   * @brief  For STM32L4, STM32L5, STM32WB and STM32WL
  256.   *         running in LowPower Sleep requires to slow down frequency to 2MHz max.
  257.   * @retval None
  258.   */
  259. void SystemClock_Decrease(void)
  260. {
  261.   RCC_OscInitTypeDef RCC_OscInitStruct = {};
  262.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {};

  263.   /** Configure the main internal regulator output voltage
  264.   */

  265. #if (defined(STM32WBxx) && defined(PWR_CR1_VOS)) || !defined(STM32WBxx)
  266. #if defined(STM32L4xx) || defined(STM32WBxx)
  267.   if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
  268. #elif defined(STM32L5xx) || defined(STM32WLxx)
  269.   if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2) != HAL_OK)
  270. #endif
  271.   {
  272.     Error_Handler();
  273.   }
  274. #endif

  275.   /** Initializes the RCC Oscillators according to the specified parameters
  276.   * in the RCC_OscInitTypeDef structure.
  277.   */
  278.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
  279.   RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  280.   RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
  281.   RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
  282.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  283.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
  284.     Error_Handler();
  285.   }

  286.   /** Initializes the CPU and buses clocks
  287.   */
  288. #if defined(STM32WBxx)
  289.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK4 | RCC_CLOCKTYPE_HCLK2
  290.                                 | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
  291.                                 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  292.   RCC_ClkInitStruct.AHBCLK2Divider = RCC_SYSCLK_DIV1;
  293.   RCC_ClkInitStruct.AHBCLK4Divider = RCC_SYSCLK_DIV1;
  294. #elif defined(STM32WLxx)
  295.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK3 | RCC_CLOCKTYPE_HCLK
  296.                                 | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1
  297.                                 | RCC_CLOCKTYPE_PCLK2;
  298.   RCC_ClkInitStruct.AHBCLK3Divider = RCC_SYSCLK_DIV1;
  299. #elif defined(STM32L4xx)
  300.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
  301.                                 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  302. #endif
  303.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
  304.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  305.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  306.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  307.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) {
  308.     Error_Handler();
  309.   }
  310. }

  311. #elif defined(STM32G0xx) || defined(STM32G4xx)
  312. /**
  313.   * @brief  For STM32G0 and STM32G4
  314.   *         running in LowPower Sleep requires to slow down frequency to 2MHz max.
  315.   * @retval None
  316.   */
  317. void SystemClock_Decrease(void)
  318. {
  319.   RCC_OscInitTypeDef RCC_OscInitStruct = {};
  320.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {};

  321.   /** Configure the main internal regulator output voltage
  322.   */
  323.   HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);

  324.   /** Initializes the RCC Oscillators according to the specified parameters
  325.   * in the RCC_OscInitTypeDef structure.
  326.   */
  327.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  328.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  329. #if defined(STM32G0xx)
  330.   RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
  331. #endif
  332.   RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  333.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  334.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
  335.     Error_Handler();
  336.   }

  337.   /** Initializes the CPU, AHB and APB buses clocks
  338.   */
  339. #if defined(STM32G4xx)
  340.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
  341.                                 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  342.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  343. #elif defined(STM32G0xx)
  344.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
  345.                                 | RCC_CLOCKTYPE_PCLK1;
  346. #endif
  347.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  348.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV8;
  349.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  350.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) {
  351.     Error_Handler();
  352.   }
  353. }
  354. #endif

  355. /**
  356.   * @brief  Enable the sleep mode.
  357.   * @param  None
  358.   * @retval None
  359.   */
  360. void LowPower_sleep(uint32_t regulator)
  361. {

  362. #if defined(PWR_LOWPOWERREGULATOR_ON) && \
  363.     (defined(PWR_CSR_REGLPF) || defined(PWR_SR2_REGLPF))
  364.   // When LowPower regulator sleep mode is used, it is necessary to decrease CPU Frequency
  365.   if (regulator == PWR_LOWPOWERREGULATOR_ON) {
  366.     SystemClock_Decrease();
  367.   }
  368. #endif

  369.   /*
  370.    * Suspend Tick increment to prevent wakeup by Systick interrupt.
  371.    * Otherwise the Systick interrupt will wake up the device within
  372.    * 1ms (HAL time base)
  373.    */
  374.   HAL_SuspendTick();

  375.   /* Enter Sleep Mode , wake up is done once User push-button is pressed */
  376.   HAL_PWR_EnterSLEEPMode(regulator, PWR_SLEEPENTRY_WFI);

  377. #if defined(PWR_LOWPOWERREGULATOR_ON) && \
  378.     (defined(PWR_CSR_REGLPF) || defined(PWR_SR2_REGLPF))
  379.   // In case of LowPower Regulator used for sleep, restore Main regulator on exit
  380.   if (regulator == PWR_LOWPOWERREGULATOR_ON) {
  381. #if defined(__HAL_RCC_PWR_CLK_ENABLE)
  382.     __HAL_RCC_PWR_CLK_ENABLE();
  383. #endif
  384.     HAL_PWREx_DisableLowPowerRunMode();

  385.     // Restore systemClock which has been decreased by SystemClock_Decrease()
  386.     SystemClock_Config();
  387.   }
  388. #endif

  389.   /* Resume Tick interrupt if disabled prior to SLEEP mode entry */
  390.   HAL_ResumeTick();

  391.   if (WakeUpUartCb != NULL) {
  392.     WakeUpUartCb();
  393.   }
  394. }

  395. /**
  396.   * @brief  Enable the stop mode.
  397.   * @param  obj : pointer to serial_t structure
  398.   * @retval None
  399.   */
  400. void LowPower_stop(serial_t *obj)
  401. {
  402.   __disable_irq();

  403. #if defined(UART_WKUP_SUPPORT)
  404.   if (WakeUpUart != NULL) {
  405.     HAL_UARTEx_EnableStopMode(WakeUpUart);
  406.   }
  407. #endif

  408. #if defined(PWR_CR_ULP)
  409.   /* Enable Ultra low power mode */
  410.   HAL_PWREx_EnableUltraLowPower();
  411. #endif
  412. #if defined(PWR_CR1_ULPMEN) || defined(PWR_CR3_ULPMEN)
  413.   /* Enable Ultra low power mode */
  414.   HAL_PWREx_EnableUltraLowPowerMode();
  415. #endif
  416. #if defined(PWR_CR_FWU)
  417.   /* Enable the fast wake up from Ultra low power mode */
  418.   HAL_PWREx_EnableFastWakeUp();
  419. #endif
  420. #ifdef __HAL_RCC_WAKEUPSTOP_CLK_CONFIG
  421.   /* Select MSI or HSI as system clock source after Wake Up from Stop mode */
  422. #ifdef RCC_STOP_WAKEUPCLOCK_MSI
  423.   __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI);
  424. #else
  425.   __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);
  426. #endif
  427. #endif
  428. #if defined(STM32WBxx)
  429.   /* Set low-power mode of CPU2 */
  430.   /* Note: Typically, action performed by CPU2 on a dual core application.
  431.            Since this example is single core, perform it by CPU1. */
  432.   /* Note: On STM32WB, both CPU1 and CPU2 must be in low-power mode
  433.            to set the entire System in low-power mode, corresponding to
  434.            the deepest low-power mode possible.
  435.            For example, CPU1 in Stop2 mode and CPU2 in Shutdown mode
  436.            will make system enter in Stop2 mode. */
  437. #if defined(LL_PWR_MODE_STOP2)
  438.   LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STOP2);
  439. #else
  440.   LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
  441. #endif
  442. #endif
  443.   /* Enter Stop mode */
  444. #if defined(UART_WKUP_SUPPORT) && (defined(PWR_CPUCR_RETDS_CD) \
  445. || defined(PWR_CR1_LPMS_STOP2) || defined(PWR_LOWPOWERMODE_STOP2) \
  446. || defined(LL_PWR_STOP2_MODE))
  447.   if ((WakeUpUart == NULL)
  448.       || (WakeUpUart->Instance == (USART_TypeDef *)LPUART1_BASE)
  449. #ifdef LPUART2_BASE
  450.       || (WakeUpUart->Instance == (USART_TypeDef *)LPUART2_BASE)
  451. #endif
  452.      ) {
  453. #if defined(PWR_CR1_RRSTP)
  454.     // STM32L4+ must keep SRAM3 content when entering STOP2 lowpower mode
  455.     HAL_PWREx_EnableSRAM3ContentRetention();
  456. #endif /* PWR_CR1_RRSTP */
  457.     // STM32L4xx supports STOP2 mode which halves consumption
  458.     HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
  459.   } else
  460. #endif
  461.   {
  462. #if defined(PWR_LOWPOWERREGULATOR_ON)
  463.     HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
  464. #else
  465.     HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);
  466. #endif
  467.   }

  468.   /* Exit Stop mode reset clocks */
  469.   SystemClock_ConfigFromStop();
  470. #if defined(UART_WKUP_SUPPORT)
  471.   if (WakeUpUart != NULL) {
  472.     /* In case of WakeUp from UART, reset its clock source to HSI */
  473.     uart_config_lowpower(obj);
  474.     HAL_UARTEx_DisableStopMode(WakeUpUart);
  475.   }
  476. #else
  477.   UNUSED(obj);
  478. #endif
  479.   __enable_irq();

  480.   HAL_Delay(10);

  481.   if (WakeUpUartCb != NULL) {
  482.     WakeUpUartCb();
  483.   }
  484. }

  485. /**
  486.   * @brief  Enable the standby mode. The board reset when leaves this mode.
  487.   * @param  None
  488.   * @retval None
  489.   */
  490. void LowPower_standby()
  491. {
  492.   __disable_irq();

  493.   /* Clear wakeup flags */
  494. #if defined(PWR_FLAG_WU)
  495.   __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
  496. #elif defined(PWR_CPUCR_CSSF)
  497.   __HAL_PWR_CLEAR_FLAG(PWR_CPUCR_CSSF);
  498. #elif defined(PWR_MPUCR_CSSF)
  499.   __HAL_PWR_CLEAR_FLAG(PWR_MPUCR_CSSF);
  500. #endif

  501. #if defined(PWR_CR_ULP)
  502.   /* Enable Ultra low power mode */
  503.   HAL_PWREx_EnableUltraLowPower();
  504. #endif
  505. #if defined(PWR_CR_FWU)
  506.   /* Enable the fast wake up from Ultra low power mode */
  507.   HAL_PWREx_EnableFastWakeUp();
  508. #endif
  509. #if defined(STM32WBxx)
  510.   /* Set low-power mode of CPU2 */
  511.   /* Note: Typically, action performed by CPU2 on a dual core application.
  512.            Since this example is single core, perform it by CPU1. */
  513.   /* Note: On STM32WB, both CPU1 and CPU2 must be in low-power mode
  514.            to set the entire System in low-power mode, corresponding to
  515.            the deepest low-power mode possible.
  516.            For example, CPU1 in Stop2 mode and CPU2 in Shutdown mode
  517.            will make system enter in Stop2 mode. */
  518.   LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STANDBY);
  519. #endif
  520.   HAL_PWR_EnterSTANDBYMode();
  521. }

  522. /**
  523.   * @brief  Enable the shutdown mode.The board reset when leaves this mode.
  524.   *         If shutdown mode not available, use standby mode instead.
  525.   * @param  boolean true if RTC is configured, in that case LSE is required
  526.   * @retval None
  527.   */
  528. void LowPower_shutdown(bool isRTC)
  529. {
  530.   __disable_irq();

  531.   /* Clear wakeup flags */
  532. #if defined(PWR_FLAG_WU)
  533.   __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
  534. #elif defined(PWR_CPUCR_CSSF)
  535.   __HAL_PWR_CLEAR_FLAG(PWR_CPUCR_CSSF);
  536. #elif defined(PWR_MPUCR_CSSF)
  537.   __HAL_PWR_CLEAR_FLAG(PWR_MPUCR_CSSF);
  538. #endif
  539. #if defined(STM32WBxx)
  540.   /* Set low-power mode of CPU2 */
  541.   /* Note: Typically, action performed by CPU2 on a dual core application.
  542.            Since this example is single core, perform it by CPU1. */
  543.   /* Note: On STM32WB, both CPU1 and CPU2 must be in low-power mode
  544.            to set the entire System in low-power mode, corresponding to
  545.            the deepest low-power mode possible.
  546.            For example, CPU1 in Stop2 mode and CPU2 in Shutdown mode
  547.            will make system enter in Stop2 mode. */
  548.   LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
  549. #endif
  550. #if defined(LL_PWR_SHUTDOWN_MODE) || defined(LL_PWR_MODE_SHUTDOWN)
  551.   /* LSE must be on to use shutdown mode within RTC else fallback to standby */
  552.   if ((!isRTC) || (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == SET)) {
  553.     HAL_PWREx_EnterSHUTDOWNMode();
  554.   } else
  555. #else
  556.   UNUSED(isRTC);
  557. #endif
  558.   {
  559.     LowPower_standby();
  560.   }
  561. }

  562. /**
  563.   * @brief  Configure the UART as a wakeup source. A callback can be called when
  564.   *         the chip leaves the low power mode. See board datasheet to check
  565.   *         with which low power mode the UART is compatible.
  566.   * Warning This function will change UART clock source to HSI
  567.   * @param  serial: pointer to serial
  568.   * @param  FuncPtr: pointer to callback
  569.   * @retval None
  570.   */
  571. void LowPower_EnableWakeUpUart(serial_t *serial, void (*FuncPtr)(void))
  572. {
  573. #if defined(UART_WKUP_SUPPORT)
  574. #ifdef IS_UART_WAKEUP_SELECTION
  575.   UART_WakeUpTypeDef WakeUpSelection;
  576.   if (serial == NULL) {
  577.     return;
  578.   }
  579.   /* Save Uart handler and Serial object */
  580.   WakeUpUart = &(serial->handle);

  581.   /* make sure that no UART transfer is on-going */
  582.   while (__HAL_UART_GET_FLAG(WakeUpUart, USART_ISR_BUSY) == SET);
  583.   /* make sure that UART is ready to receive
  584.    * (test carried out again later in HAL_UARTEx_StopModeWakeUpSourceConfig) */
  585.   while (__HAL_UART_GET_FLAG(WakeUpUart, USART_ISR_REACK) == RESET);

  586.   /* set the wake-up event:
  587.    * specify wake-up on RXNE flag
  588.    */
  589.   WakeUpSelection.WakeUpEvent = UART_WAKEUP_ON_READDATA_NONEMPTY;
  590.   HAL_UARTEx_StopModeWakeUpSourceConfig(WakeUpUart, WakeUpSelection);
  591. #endif
  592. #if defined(UART_IT_WUF)
  593.   /* Enable the UART Wake UP from STOPx mode Interrupt */
  594.   __HAL_UART_ENABLE_IT(WakeUpUart, UART_IT_WUF);
  595. #endif
  596. #else
  597.   UNUSED(serial);
  598. #endif
  599.   /* Save callback */
  600.   WakeUpUartCb = FuncPtr;
  601. }

  602. /**
  603.   * @brief  Configures system clock and system IP clocks after wake-up from STOP
  604.   * [url=home.php?mod=space&uid=536309]@NOTE[/url]   Weaked function which can be redefined by user at the sketch level.
  605.   *         By default, call 'SystemClock_Config()'.
  606.   * @param  None
  607.   * @retval None
  608.   */
  609. WEAK void SystemClock_ConfigFromStop(void)
  610. {
  611.   configIPClock();
  612.   SystemClock_Config();
  613. }

  614. #ifdef __cplusplus
  615. }
  616. #endif

  617. #endif /* HAL_PWR_MODULE_ENABLED  && !HAL_PWR_MODULE_ONLY */

  618. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
天灵灵地灵灵 发表于 2024-4-19 17:27 | 显示全部楼层
  1. /**
  2.   ******************************************************************************
  3.   * @file    LowPower.h
  4.   * @author  Frederic Pillon
  5.   * @brief   Header for Low Power module
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * <h2><center>&copy; COPYRIGHT(c) 2020 STMicroelectronics</center></h2>
  10.   *
  11.   * Redistribution and use in source and binary forms, with or without modification,
  12.   * are permitted provided that the following conditions are met:
  13.   *   1. Redistributions of source code must retain the above copyright notice,
  14.   *      this list of conditions and the following disclaimer.
  15.   *   2. Redistributions in binary form must reproduce the above copyright notice,
  16.   *      this list of conditions and the following disclaimer in the documentation
  17.   *      and/or other materials provided with the distribution.
  18.   *   3. Neither the name of STMicroelectronics nor the names of its contributors
  19.   *      may be used to endorse or promote products derived from this software
  20.   *      without specific prior written permission.
  21.   *
  22.   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23.   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  25.   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  26.   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  28.   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  29.   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  30.   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  31.   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32.   *
  33.   ******************************************************************************
  34.   */

  35. /* Define to prevent recursive inclusion -------------------------------------*/
  36. #ifndef __LOW_POWER_H
  37. #define __LOW_POWER_H

  38. /* Includes ------------------------------------------------------------------*/
  39. #include "stm32_def.h"
  40. #include "uart.h"

  41. #if defined(HAL_PWR_MODULE_ENABLED) && !defined(HAL_PWR_MODULE_ONLY)

  42. #ifdef __cplusplus
  43. extern "C" {
  44. #endif

  45. /* Exported types ------------------------------------------------------------*/
  46. /* Exported constants --------------------------------------------------------*/
  47. /* Exported macro ------------------------------------------------------------*/
  48. /* Exported functions ------------------------------------------------------- */

  49. void LowPower_init();
  50. void LowPower_EnableWakeUpPin(uint32_t pin, uint32_t mode);
  51. void LowPower_EnableWakeUpUart(serial_t *serial, void (*FuncPtr)(void));
  52. void LowPower_sleep(uint32_t regulator);
  53. void LowPower_stop(serial_t *obj);
  54. void LowPower_standby();
  55. void LowPower_shutdown(bool isRTC);
  56. /* Weaked function */
  57. void SystemClock_ConfigFromStop(void);
  58. #ifdef __cplusplus
  59. }
  60. #endif

  61. #endif /* HAL_PWR_MODULE_ENABLED  && !HAL_PWR_MODULE_ONLY */

  62. #endif /* __LOW_POWER_H */
yutingwei 发表于 2024-8-31 22:31 | 显示全部楼层
ATmega328P 具有几种低功耗模式,包括休眠模式、ADC 噪声减少模式等。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

212

主题

3272

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部

212

主题

3272

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部