[讨论] STM32L476停机模式下设置唤醒功耗很大

xcjldtp   2018-1-15 16:39 楼主
遇到一个棘手的问题,大家帮忙出出点子解决,非常感谢! STM32L476最小系统板,单纯进入关机模式,不设置唤醒的功耗大概是40nA IMG_20180115_151755.jpg 当设置PC13为唤醒引脚进行唤醒时,进入关机模式的功耗竟然高达28uA IMG_20180115_151450.jpg /* Set all GPIO in analog state to reduce power consumption */ GPIO_AnalogState_Config(); /* Disable all used wakeup sources: WKUP pin */ HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN2); /* Clear wake up Flag */ __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2); /* Enable wakeup pin WKUP2 */ HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_LOW); /* Ensure that MSI is wake-up system clock */ __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI); /* Enter the SHUTDOWN mode */ HAL_PWREx_EnterSHUTDOWNMode(); 调试发现HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_LOW);只要屏蔽这个使能就降到40nA,打开这个使能就28uA 不知道大家是怎么设置外部中断唤醒的,这个使能没有遇到这样的情况吗? 本帖最后由 xcjldtp 于 2018-1-15 16:44 编辑

回复评论 (9)

这个没有研究过,不过,这套测试设备很好,值得点个赞了
点赞  2018-1-15 16:43
把完整代码发上来看下
虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2018-1-15 19:27
可以参考一下这个官方例程
STM32Cube_FW_L4_V1.10.0\Projects\STM32L476RG-Nucleo\Examples\PWR\PWR_SHUTDOWN
  1. /**
  2.   ******************************************************************************
  3.   * @file    PWR/PWR_SHUTDOWN/Src/main.c
  4.   * @author  MCD Application Team
  5.   * [url=home.php?mod=space&uid=159083]@brief[/url]   This sample code shows how to use STM32L4xx PWR HAL API to enter
  6.   *          and exit the shutdown mode with a wakeup pin or external reset.
  7.   ******************************************************************************
  8.   * @attention
  9.   *
  10.   * <h2><center>© COPYRIGHT(c) 2017 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. /* Includes ------------------------------------------------------------------*/
  37. #include "main.h"

  38. /** @addtogroup STM32L4xx_HAL_Examples
  39.   * @{
  40.   */

  41. /** @addtogroup PWR_SHUTDOWN
  42.   * @{
  43.   */

  44. /* Private typedef -----------------------------------------------------------*/
  45. /* Private define ------------------------------------------------------------*/
  46. /* Delay set between each LED turn-on/off while LED is toggling */
  47. #define LED_TOGGLE_DELAY         100
  48. /* Delay set to keep LED turned on when out-of-shutdown detected */
  49. #define LED_FREEZE_DELAY         50
  50. /* Private macro -------------------------------------------------------------*/
  51. /* Private variables ---------------------------------------------------------*/
  52. static __IO uint32_t TimingDelay;
  53. static __IO uint32_t counter;             /* ad-hoc counter set to keep LED
  54.                                              on for about 4 sec. when out-of-
  55.                                              shutdown exit detected */
  56. static __IO uint32_t out_of_shutdown;     /* flag initialized at 0, set when
  57.                                              exit from shutdown detected */

  58. /* Private function prototypes -----------------------------------------------*/
  59. void SystemClock_Config(void);

  60. /* Private functions ---------------------------------------------------------*/

  61. /**
  62.   * @brief  Main program
  63.   * @param  None
  64.   * @retval None
  65.   */
  66. int main(void)
  67. {
  68.   out_of_shutdown = 0;
  69.   counter = LED_FREEZE_DELAY;
  70.   
  71.   /* STM32L4xx HAL library initialization:
  72.        - Configure the Flash prefetch
  73.        - Systick timer is configured by default as source of time base, but user
  74.          can eventually implement his proper time base source (a general purpose
  75.          timer for example or other time source), keeping in mind that Time base
  76.          duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
  77.          handled in milliseconds basis.
  78.        - Set NVIC Group Priority to 4
  79.        - Low Level Initialization
  80.      */
  81.   HAL_Init();

  82.   /* Configure the system clock to 80 MHz */
  83.   SystemClock_Config();

  84.   /* Configure LED2 */
  85.   BSP_LED_Init(LED2);

  86.     /* Enable Power Clock */
  87.   __HAL_RCC_PWR_CLK_ENABLE();
  88.   HAL_PWR_EnableBkUpAccess();
  89.   
  90.   /* Check if the system was resumed from shutdown mode,
  91.      resort to RTC back-up register RTC_BKP31R to verify
  92.      whether or not shutdown entry flag was set by software
  93.      before entering shutdown mode.  */
  94.   if (READ_REG(RTC->BKP31R) == 1)
  95.   {
  96.      WRITE_REG( RTC->BKP31R, 0x0 );  /* reset back-up register */
  97.      out_of_shutdown = 1;            /* out of shutdown detected */
  98.     /* Wait that user release the User push-button */
  99.     BSP_PB_Init(BUTTON_USER, BUTTON_MODE_GPIO);
  100.     while(BSP_PB_GetState(BUTTON_USER) == GPIO_PIN_RESET){}
  101.   }

  102.    /* Check and Clear the Wakeup flag */
  103.   if (__HAL_PWR_GET_FLAG(PWR_FLAG_WUF2) != RESET)
  104.   {
  105.     __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);
  106.   }
  107.   
  108.   /* Initialize the User push-button to generate external interrupts */
  109.   BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
  110.   
  111.   /* Turn on LED2 */
  112.   BSP_LED_On(LED2);
  113.   
  114.   while (1)
  115.   {
  116.   }
  117. }

  118. /**
  119.   * @brief  System Clock Configuration
  120.   *         The system Clock is configured as follows :
  121.   *            System Clock source            = PLL (MSI)
  122.   *            SYSCLK(Hz)                     = 80000000
  123.   *            HCLK(Hz)                       = 80000000
  124.   *            AHB Prescaler                  = 1
  125.   *            APB1 Prescaler                 = 1
  126.   *            APB2 Prescaler                 = 1
  127.   *            MSI Frequency(Hz)              = 4000000
  128.   *            PLL_M                          = 1
  129.   *            PLL_N                          = 40
  130.   *            PLL_R                          = 2
  131.   *            PLL_P                          = 7
  132.   *            PLL_Q                          = 4
  133.   *            Flash Latency(WS)              = 4
  134.   * @param  None
  135.   * @retval None
  136.   */
  137. void SystemClock_Config(void)
  138. {
  139.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  140.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};

  141.   /* MSI is enabled after System reset, activate PLL with MSI as source */
  142.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
  143.   RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  144.   RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
  145.   RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
  146.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  147.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
  148.   RCC_OscInitStruct.PLL.PLLM = 1;
  149.   RCC_OscInitStruct.PLL.PLLN = 40;
  150.   RCC_OscInitStruct.PLL.PLLR = 2;
  151.   RCC_OscInitStruct.PLL.PLLP = 7;
  152.   RCC_OscInitStruct.PLL.PLLQ = 4;
  153.   if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  154.   {
  155.     /* Initialization Error */
  156.     while(1);
  157.   }
  158.   
  159.   /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
  160.      clocks dividers */
  161.   RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  162.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  163.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  164.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;  
  165.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;  
  166.   if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
  167.   {
  168.     /* Initialization Error */
  169.     while(1);
  170.   }
  171. }


  172. /**
  173.   * @brief  This function is executed in case of error occurrence.
  174.   * @param  None
  175.   * @retval None
  176.   */
  177. void Error_Handler(void)
  178. {
  179.   while(1)
  180.   {
  181.     /* In case of error, LED2 transmits a sequence of three dots, three dashes, three dots */
  182.     BSP_LED_On(LED2);
  183.     HAL_Delay(300);
  184.     BSP_LED_Off(LED2);
  185.     HAL_Delay(300);
  186.     BSP_LED_On(LED2);
  187.     HAL_Delay(300);
  188.     BSP_LED_Off(LED2);
  189.     HAL_Delay(300);  
  190.     BSP_LED_On(LED2);
  191.     HAL_Delay(300);
  192.     BSP_LED_Off(LED2);
  193.     HAL_Delay(300);   
  194.     BSP_LED_On(LED2);
  195.     HAL_Delay(700);
  196.     BSP_LED_Off(LED2);
  197.     HAL_Delay(700);
  198.     BSP_LED_On(LED2);
  199.     HAL_Delay(700);
  200.     BSP_LED_Off(LED2);
  201.     HAL_Delay(700);  
  202.     BSP_LED_On(LED2);
  203.     HAL_Delay(700);
  204.     BSP_LED_Off(LED2);
  205.     HAL_Delay(700);
  206.     BSP_LED_On(LED2);
  207.     HAL_Delay(300);
  208.     BSP_LED_Off(LED2);
  209.     HAL_Delay(300);
  210.     BSP_LED_On(LED2);
  211.     HAL_Delay(300);
  212.     BSP_LED_Off(LED2);
  213.     HAL_Delay(300);  
  214.     BSP_LED_On(LED2);
  215.     HAL_Delay(300);
  216.     BSP_LED_Off(LED2);
  217.     HAL_Delay(800);
  218.   }
  219. }


  220. /**
  221.   * @brief SYSTICK callback
  222.   * @param None
  223.   * @retval None
  224.   */
  225. void HAL_SYSTICK_Callback(void)
  226. {
  227.   HAL_IncTick();
  228.   if (TimingDelay != 0)
  229.   {
  230.     TimingDelay--;
  231.   }
  232.   else
  233.   {
  234.     /* Keep LED2 on for about 4 sec. when out-of-shutdown detected */
  235.     if ((out_of_shutdown == 1) && (counter > 0))
  236.     {
  237.       BSP_LED_On(LED2);           
  238.       counter--;
  239.     }
  240.     else
  241.     {
  242.     /* Toggle LED2 */
  243.     BSP_LED_Toggle(LED2);      
  244.     }
  245.     TimingDelay = LED_TOGGLE_DELAY;
  246.   }
  247.   
  248. }
  249.    
  250.    
  251. /**
  252.   * @brief EXTI line detection callbacks
  253.   * @param GPIO_Pin: Specifies the pins connected EXTI line
  254.   * @retval None
  255.   */
  256. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  257. {
  258.   if (GPIO_Pin == USER_BUTTON_PIN)
  259.   {   
  260.     /* Wait that user release the User push-button */
  261.     while(BSP_PB_GetState(BUTTON_USER) == GPIO_PIN_RESET){}

  262.     /* Disable all used wakeup sources: WKUP pin */
  263.     HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN2);
  264.    

  265.     /* Clear wake up Flag */
  266.     __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF2);
  267.    
  268.     /* Enable wakeup pin WKUP2 */
  269.     HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_LOW);
  270.    
  271.     /* Set RTC back-up register RTC_BKP31R to indicate
  272.        later on that system has entered shutdown mode  */
  273.     WRITE_REG( RTC->BKP31R, 0x1 );
  274.     /* Enter shutdown mode */
  275.     HAL_PWREx_EnterSHUTDOWNMode();
  276.   }
  277. }   

  278. #ifdef  USE_FULL_ASSERT
  279. /**
  280.   * @brief  Reports the name of the source file and the source line number
  281.   *         where the assert_param error has occurred.
  282.   * @param  file: pointer to the source file name
  283.   * @param  line: assert_param error line source number
  284.   * @retval None
  285.   */
  286. void assert_failed(char *file, uint32_t line)
  287. {
  288.   /* User can add his own implementation to report the file name and line number,
  289.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  290.   /* Infinite loop */
  291.   while (1)
  292.   {
  293.   }
  294. }
  295. #endif

  296. /**
  297.   * @}
  298.   */

  299. /**
  300.   * @}
  301.   */

  302. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2018-1-15 19:32
引用: littleshrimp 发表于 2018-1-15 19:32
可以参考一下这个官方例程
STM32Cube_FW_L4_V1.10.0\Projects\STM32L476RG-Nucleo\Examples\PWR\PWR_SHUTD ...

我只有一块最小核心板,也是在官方这个例程上改上,进入停机模式就是28uA,代码是兼容的,你们有开发板的帮忙验证一下是哪个出问题?
PWR_SHUTDOWN.zip (14.71 KB)
(下载次数: 26, 2018-1-15 21:26 上传)

点赞  2018-1-15 21:26
引用: xcjldtp 发表于 2018-1-15 21:26
我只有一块最小核心板,也是在官方这个例程上改上,进入停机模式就是28uA,代码是兼容的,你们有开发板的 ...

你直接跑官方例程 不做改动电流正常吗
点赞  2018-1-16 12:26
引用: littleshrimp 发表于 2018-1-16 12:26
你直接跑官方例程 不做改动电流正常吗

发现问题了。我的板子是最小系统板,IO外部都没有上拉电阻,程序只把PC13中断脚设置为内部上拉,其它设为模拟输入。看了一下官方的板子是按键上拉了4.7K的电阻,我刚刚飞了根线也上拉了个10K电阻,不设置内部上拉就正常了。

现在有两个问题:
1、内部上拉电阻和外部上拉10K电阻差别很大吗?
2、我的程序里保持用内部上拉不变,但是屏蔽掉这条语句功耗就正常了HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_LOW);。
用外部上拉使用这条语句又正常,是哪里消耗了电流?
点赞  2018-1-16 14:41
引用: xcjldtp 发表于 2018-1-16 14:41
发现问题了。我的板子是最小系统板,IO外部都没有上拉电阻,程序只把PC13中断脚设置为内部上拉,其它设为 ...

是不是作为唤醒引脚时内部上拉无法使用?
点赞  2018-1-16 14:49
引用: xcjldtp 发表于 2018-1-16 14:41
发现问题了。我的板子是最小系统板,IO外部都没有上拉电阻,程序只把PC13中断脚设置为内部上拉,其它设为 ...

比如在只使用内部上拉的时候量一下引脚的电平
点赞  2018-1-16 14:58
引用: littleshrimp 发表于 2018-1-16 14:49
是不是作为唤醒引脚时内部上拉无法使用?

可以使用,设置内部上拉也可以正常唤醒,不知道功耗为什么会这么大。
官方例程只初始化了这个中断脚BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
我的板子把gpioinitstruct.Pull  = GPIO_NOPULL;改为GPIO_PULLUP,用内部上拉就28uA.
点赞  2018-1-16 15:03
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复