你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32L051C8进入低功耗模式电流偏大

[复制链接]
回首,相濡以沫 提问时间:2020-8-5 16:54 /
最近倒腾STM32L051C8的低功耗模式,看了官方给的例程跟一些大佬的代码,然后自己就开始琢磨。我这边是将stm32设置成stop mode with rtc,经测试发现,stm32第一次进入stop mode with rtc的电流是0.8-0.9ua(这跟手册上面的电流大小是相符的),但是从第二次进入stop mode with rtc电流就一直是2.6ua。附上程序
  1. #include "main.h"
  2. #include "led.h"

  3. /* RTC handler declaration */
  4. RTC_HandleTypeDef RTCHandle;

  5. static void Stop_rtc_config(uint32_t sleep);
  6. static void Enter_stop_rtc_mode(void);
  7. static void System_config_before_stop(void);
  8. static void SystemClock_Config(void);
  9. static void SystemClockConfig_STOP(void);


  10. int main(void)
  11. {

  12.                 HAL_Init();
  13.                 SystemClock_Config();

  14. //                LED_Init();
  15.                 while (1)
  16.                 {
  17. //                        LED_ON; //点亮LED
  18.                         HAL_Delay(3000);
  19.                         Enter_stop_rtc_mode();//进入stop whit rtc mode
  20.                 }
  21. }


  22. static void Enter_stop_rtc_mode(void)
  23. {
  24.                 //1. 配置stop之前各外设
  25.                 System_config_before_stop();

  26.                 //2.设置rtc唤醒时间(s)
  27.                 Stop_rtc_config(3);

  28.                 //3. 进入stop
  29.                 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);

  30.                 //3.退出stop后恢复时钟
  31.                 SystemClockConfig_STOP();

  32.                 //4.恢复各外设
  33. //                LED_Init();
  34. }


  35. //退出stop后重新设置时钟
  36. //static void clock_config_after_stop(void)
  37. static void SystemClock_Config(void)
  38. {
  39.                 HAL_StatusTypeDef ret = HAL_OK;
  40.                 RCC_OscInitTypeDef RCC_OscInitStructure = {0};
  41.                 RCC_ClkInitTypeDef RCC_ClkInitStructure = {0};

  42.                 /* Enable Power Control clock */
  43.                 __HAL_RCC_PWR_CLK_ENABLE();

  44.                 /* The voltage scaling allows optimizing the power consumption when the device is
  45.                    clocked below the maximum system frequency, to update the voltage scaling value
  46.                    regarding system frequency refer to product datasheet.  */
  47.                 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);//电压缩放降低当器件处于工作状态时的功耗

  48. //                /* Get the Oscillators configuration according to the internal RCC registers */
  49. //                HAL_RCC_GetOscConfig(&RCC_OscInitStructure);

  50.                 /* After wake-up from STOP reconfigure the system clock: Enable HSI and PLL */
  51.                 RCC_OscInitStructure.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  52.                 RCC_OscInitStructure.HSEState = RCC_HSE_OFF;
  53.                 RCC_OscInitStructure.HSIState = RCC_HSI_ON;
  54.                 RCC_OscInitStructure.PLL.PLLState = RCC_PLL_ON;
  55.                 RCC_OscInitStructure.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  56.                 RCC_OscInitStructure.PLL.PLLMUL = RCC_PLLMUL_4;
  57.                 RCC_OscInitStructure.PLL.PLLDIV = RCC_PLLDIV_2;
  58.                 RCC_OscInitStructure.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;               
  59.                 ret = HAL_RCC_OscConfig(&RCC_OscInitStructure);
  60.                 if (ret != HAL_OK) while (1);

  61.                 /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
  62.                    clocks dividers */
  63.                 RCC_ClkInitStructure.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  64.                 RCC_ClkInitStructure.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  65.                 RCC_ClkInitStructure.AHBCLKDivider = RCC_SYSCLK_DIV1;
  66.                 RCC_ClkInitStructure.APB1CLKDivider = RCC_HCLK_DIV1;  
  67.                 RCC_ClkInitStructure.APB2CLKDivider = RCC_HCLK_DIV1;                  
  68.                 ret = HAL_RCC_ClockConfig(&RCC_ClkInitStructure, FLASH_LATENCY_1);
  69.                 if (ret != HAL_OK) while (1);
  70. }


  71. //设置进入stop mode之后rtc唤醒时间(s)
  72. static void Stop_rtc_config(uint32_t sleep)
  73. {
  74.                 /* Disable Wakeup Counter */
  75.                 HAL_RTCEx_DeactivateWakeUpTimer(&RTCHandle);
  76.         
  77.                 /*## Set wake up timer with interrupt */
  78.                 HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, sleep, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);//选择1Hz时钟
  79. }


  80. //进入stop之前外设设置
  81. static void System_config_before_stop(void)
  82. {
  83.                 HAL_StatusTypeDef ret = HAL_OK;

  84.                 GPIO_InitTypeDef GPIO_InitStructure;
  85.         
  86.                 /* Enable Ultra low power mode */
  87.                 HAL_PWREx_EnableUltraLowPower();//VREFINT 在低功耗模式下关闭

  88.                 /* Enable the fast wake up from Ultra low power mode */
  89.                 HAL_PWREx_EnableFastWakeUp();
  90.         
  91.                 /* Select HSI as system clock source after Wake Up from Stop mode */
  92.                 __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);

  93.                 /* Enable GPIOs clock */
  94.                 __HAL_RCC_GPIOA_CLK_ENABLE();
  95.                 __HAL_RCC_GPIOB_CLK_ENABLE();
  96.                 __HAL_RCC_GPIOC_CLK_ENABLE();
  97.         
  98.                 /* Configure all GPIO port pins in Analog Input mode (floating input trigger OFF) */
  99.                 GPIO_InitStructure.Pin = GPIO_PIN_All;
  100.                 GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
  101.                 GPIO_InitStructure.Pull = GPIO_NOPULL;
  102.                 HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
  103.                 HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
  104.                 HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);

  105.                 /* Disable GPIOs clock */
  106.                 __HAL_RCC_GPIOA_CLK_DISABLE();
  107.                 __HAL_RCC_GPIOB_CLK_DISABLE();
  108.                 __HAL_RCC_GPIOC_CLK_DISABLE();

  109.                 /* Configure RTC 1Hz,LSE做RTC时钟*/
  110.                 RTCHandle.Instance = RTC;
  111.                 RTCHandle.Init.HourFormat = RTC_HOURFORMAT_24;
  112.                 RTCHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
  113.                 RTCHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV;
  114.                 RTCHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
  115.                 RTCHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  116.                 RTCHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  117.                 ret = HAL_RTC_Init(&RTCHandle);
  118.                 if (ret != HAL_OK) while (1);
  119. }


  120. /**
  121.   * @brief  System Clock Configuration
  122.   *         The system Clock is configured as follow :
  123.   *            System Clock source            = PLL (HSI)
  124.   *            SYSCLK(Hz)                     = 32000000
  125.   *            HCLK(Hz)                       = 32000000
  126.   *            AHB Prescaler                  = 1
  127.   *            APB1 Prescaler                 = 1
  128.   *            APB2 Prescaler                 = 1
  129.   *            HSI Frequency(Hz)              = 16000000
  130.   *            PLL_MUL                        = 4
  131.   *            PLL_DIV                        = 2
  132.   *            Flash Latency(WS)              = 1
  133.   *            Main regulator output voltage  = Scale1 mode
  134.   * @param  None
  135.   * @retval None
  136.   */
  137. //void systemClockConfig(void)
  138. static void SystemClockConfig_STOP(void)
  139. {
  140.                 HAL_StatusTypeDef ret = HAL_OK;
  141.                 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  142.                 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  143.                 /* Enable Power Control clock */
  144.                 __HAL_RCC_PWR_CLK_ENABLE();

  145.                 /* The voltage scaling allows optimizing the power consumption when the device is
  146.                  clocked below the maximum system frequency, to update the voltage scaling value
  147.                  regarding system frequency refer to product datasheet.  */
  148.                 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  149.                 /* Get the Oscillators configuration according to the internal RCC registers */
  150.                 HAL_RCC_GetOscConfig(&RCC_OscInitStruct);               
  151.                
  152.                 /* After wake-up from STOP reconfigure the system clock: Enable HSI and PLL */
  153.                 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  154.                 RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
  155.                 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  156.                 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  157.                 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  158.                 RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4;
  159.                 RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV2;
  160.                 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  161.                 ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
  162.                 if (ret != HAL_OK) while (1);

  163.                 /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
  164.                 clocks dividers */
  165.                 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
  166.                 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  167.                 ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
  168.                 if (ret != HAL_OK) while (1);
  169. }



复制代码
看了一些资料也没能搞清楚这多的电流是从哪里来的,有大佬知道吗
收藏 评论11 发布时间:2020-8-5 16:54

举报

11个回答
废鱼 回答时间:2020-8-5 20:25:31
估计是某些IO口的配置问题,建议楼主在进入休眠时,将IO全部设置为输入拉低。不过有的也需要看实际电路连接的情况,比如外设是连接一个上拉电阻时,输入下拉反而会耗电更多。要根据实际电路的情况,进行调整。

评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

回首,相濡以沫 回答时间:2020-8-5 22:35:18
安 发表于 2020-8-5 20:25
估计是某些IO口的配置问题,建议楼主在进入休眠时,将IO全部设置为输入拉低。不过有的也需要看实际电路连接 ...

好的,我按照这个思路再检查检查
Tcreat 回答时间:2020-8-6 08:32:23
进入STOP之前 保留需要唤醒的设置外 被开启的外设要关闭  IO根据休眠后的IO引脚状态设置   比如如果是通过MCU供电电源上拉的,这样引脚得设置为输出高电平,设置为输入模式就不合适了,类推~~

评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

回首,相濡以沫 回答时间:2020-8-6 18:23:51
折腾了一天终于解决了,是跟唤醒之后的系统时钟设置有关系。问题解决完之后把工程整理了一下,发出来给大家分享。实际测的stop mode with rtc电流在0.9uA,手册上面是1uA,但我是3.3V供电的,才导致有差异,不过还能接受。程序里面包含按键触发的外部中断部分(下降沿触发),分别是PB3、PB4、PB5、PB8
STM32L051C8T6停止模式下电流实测.jpg

STM32L051C8T6_STOP_RTC_BUTTON.rar

下载

5.21 MB, 下载次数: 23, 下载积分: ST金币 -1

陌路夕颜 回答时间:2020-8-7 09:17:33
进入低功耗需要关闭用不到的外设时钟,关闭大晶振,IO要根据外部电路进行设置,没有用到的IO最好设置成输入上拉。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

回首,相濡以沫 回答时间:2020-8-7 16:30:31
陌路夕颜 发表于 2020-8-7 09:17
进入低功耗需要关闭用不到的外设时钟,关闭大晶振,IO要根据外部电路进行设置,没有用到的IO最好设置成输入 ...

没有用到的IO口设置成模拟输入是不是更好,官方的例程上面也是设置成模拟输入。因为模拟输入阻抗是很大的,可以看成与外部电路断开。不知道我这解释对不对
Tcreat 回答时间:2020-8-7 17:29:49
回首,相濡以沫 发表于 2020-8-7 16:30
没有用到的IO口设置成模拟输入是不是更好,官方的例程上面也是设置成模拟输入。因为模拟输入阻抗是很大的 ...

没用到引脚 设置输入模式  基本都差不多
陌路夕颜 回答时间:2020-8-7 22:45:50
回首,相濡以沫 发表于 2020-8-7 16:30
没有用到的IO口设置成模拟输入是不是更好,官方的例程上面也是设置成模拟输入。因为模拟输入阻抗是很大的 ...

上拉输入有确定的电平,模拟输入阻抗大,更容易捕获外部干扰
回首,相濡以沫 回答时间:2020-8-11 10:53:16
陌路夕颜 发表于 2020-8-7 22:45
上拉输入有确定的电平,模拟输入阻抗大,更容易捕获外部干扰

设置为上拉输入难道不会造成额外的功率损耗吗?在外部干扰小的情况下,是不是模拟输入更加可行?
陌路夕颜 回答时间:2020-8-11 12:11:33
回首,相濡以沫 发表于 2020-8-11 10:53
设置为上拉输入难道不会造成额外的功率损耗吗?在外部干扰小的情况下,是不是模拟输入更加可行? ...

不会,这是CC2540的手册上写的
2.png
butterflyspring 回答时间:2020-8-12 16:51:39
陌路夕颜 发表于 2020-8-11 12:11
不会,这是CC2540的手册上写的

虽然都是MCU产品,不同厂家的设计是不同的,工艺也不同。所以相关的例程配置也会不同。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版