【STM32U385RG 测评】各功耗模式的电流测试
一、软硬件准备
1.1 软件环境
开发环境用的是VSCode+CubeMX,搭建方式参考之前的帖子: 【STM32U385RG 测评】搭建基于VSCode的STM32开发环境
1.2 硬件连接
硬件连接方式如下图所示:

通过USB Type-C线连将开发板连接到PC,需要注意的是:
- 开发板接标有USB STLK的口,如图所示;
- 有的USB线PC不识别,不是驱动问题,换一根线就可以;
二、背景知识
2.1 低功耗模式
关于主控芯片STM32U385xx的低功耗模式,数据手册中有一个表格列出了:




表格下方的说明文字,翻译过来就是:
默认情况下,微控制器在系统复位或上电复位后处于运行模式(Run mode)。用户可以选择下述低功耗模式之一:
- 睡眠模式 (Sleep mode)
CPU时钟关闭,所有外设(包括Cortex®-M33内核组件,如NVIC和SysTick)可以运行,并在发生中断或事件时唤醒CPU。
- 停止模式 0、1、2 和 3 (Stop 0, Stop 1, Stop 2, and Stop 3 modes)
停止模式在保留SRAM和寄存器内容的同时实现最低功耗。SRAM可以完全或部分关闭以进一步降低功耗。内核域中的所有时钟均停止。MSI (MSIS和MSIK) RC振荡器、HSI16 RC振荡器和HSE晶体振荡器被禁用。LSE或LSI仍在运行。
- RTC可以保持活动(带RTC的停止模式,不带RTC的停止模式)。
- 一些外设是自主的,可以在停止模式下操作,在需要时请求其内核时钟及其总线(APB或AHB),以便根据外设和电源模式通过GPDMA1传输数据。
- 在停止模式0下,稳压器保持主稳压模式,可实现极快的唤醒时间,但功耗较高。
- 在停止模式1下,稳压器处于低功耗模式,整个内核域保持完全供电。所有自主外设均可工作。
- 在停止模式2下,大部分内核域(D1域)置于较低泄漏模式,保留寄存器内容,但不具备任何功能。包含APB3外设的D2域保持完全供电,因此这些外设可以保持工作状态。
- 停止模式3是具有完全保留功能的最低功耗模式,但可用的功能外设和唤醒源减少到与待机模式相同。
- 退出停止模式时的系统时钟可以是高达48 MHz的MSIS或HSI16,具体取决于软件配置。
- 待机模式 (Standby mode)
待机模式用于在开启BOR(欠压复位)的情况下实现最低功耗。内部稳压器关闭,因此内核域断电。MSI (MSIS和MSIK) RC振荡器、HSI16 RC振荡器和HSE晶体振荡器也被关闭。
- RTC可以保持活动(带RTC的待机模式,不带RTC的待机模式)。
- 欠压复位(BOR)在待机模式下始终保持活动。
- 待机模式下每个I/O的状态可通过软件选择:内部上拉、内部下拉或浮空。
- 进入待机模式后,除备份域中的寄存器和待机电路外,SRAM和寄存器内容将丢失。可选地,在待机模式下可通过低功耗稳压器供电(待机且保留SRAM2模式)保留完整的SRAM2或8 KB、24 KB、32 KB的SRAM2。
- BOR可配置为超低功耗模式,以进一步降低待机模式下的功耗。
- 当发生外部复位(NRST引脚)、IWDG(独立看门狗)提前唤醒事件或复位、WKUP引脚事件(可配置上升沿或下降沿)、RTC事件(闹钟、周期性唤醒、时间戳)、篡改检测或I3C复位模式检测时,设备将退出待机模式。
- 唤醒后的系统时钟是高达12 MHz的MSIS。
- 关机模式 (Shutdown mode)
关机模式允许实现最低功耗。内部稳压器关闭,因此内核域断电。HSI16、MSI (MSIS和MSIK)、LSI以及HSE振荡器也被关闭。
- RTC可以保持活动(带RTC的关机模式,不带RTC的关机模式)。
- 关机模式下不可用BOR。此模式下无法进行电源电压监控,因此不支持切换到备份域。
- 除备份域中的寄存器外,SRAM和寄存器内容将丢失。
- 当发生外部复位(NRST引脚)、WKUP引脚事件(可配置上升沿或下降沿)、RTC事件(闹钟、周期性唤醒、时间戳)、篡改检测或I3C复位模式检测时,设备将退出关机模式。
- 唤醒后的系统时钟是12 MHz的MSIS。
2.2 电源管理
参考手册第9章 开头部分:

其中System supply voltage regulation下方列出了两种,翻译过来就是:
System supply voltage regulation
系统供电电压调节
– SMPS step-down converter
– 开关模式电源 (SMPS = Switching Mode Power Supply) 降压转换器
– Linear voltage regulator (LDO)
– 线性稳压器 (LDO)
三、创建项目
为了方便观察,我们仍然创建一个点灯的项目,让程序正常运行状态下,执行不断闪烁LED的逻辑;进入Sleep、Stop、Standby模式之后,程序不运行,LED应该不闪烁。这样就非常方便我们观察——CPU是否真的安装我们预期的停下来了。
3.1 选择芯片型号
打开STM32CubeMX,通过菜单File→New Project打开新建项目窗口,在弹出的界面中选择“Board Selector”标签页:

其中,具体操作步骤为:
- 在Commercial Part Number栏中输入U385RG,并回车;
- 在MCUs/MPUs List下方选中Board列有NUCLEO-U385RG-Q的一行;
- 点击右上角Start Project按钮;
- 弹出TrustZone设置的话框,选择Witout TrustZone activated;

3.2 设置引脚功能
在STM32CubeMX的Pinout View中,找到PA5引脚,将其设置为GPIO_Output:

3.3 CPU时钟频率
默认的CPU时钟频率为1.5MHz,可以正常运行LED闪烁,可以不修改(CPU频率越高,功耗也会越高):

3.4 生成CMake项目
完成引脚功能修改后,在STM32CubeMX中,切到Project Manager标签页,Toolchain/IDE选择CMake,如下图:

切换到Code Generator设置,选择Copy only the necessary library files和Generate peripheral initialization as a pair of ‘.c/.h’ per peripheral,如下图:

四、电流测试
4.1 正常运行
在生成的CMake项目中,修改 Core/Src/main.c
文件中,main
函数的无限循环部分代码,修改为:
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
这样就可以正常闪烁板载LED灯,此时万用表测到的电流为1.19mA:

4.2 SMPS供电
切换到SMPS(开关电源模式)供电后,系统功耗可以进一步降低。
在刚刚的循环开始之前,添加一行代码,即可切换到SMPS供电,修改后的循环代码如下:
/* Infinite loop */
/* USER CODE BEGIN WHILE */
HAL_PWREx_ConfigSupply(PWR_SMPS_SUPPLY); // 配置 SMPS 作为电源
while (1)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
SMPS供电后,万用表测到的电流降低到0.43mA:

4.3 Standby模式
进入Standby模式的代码比较简单,一行代码即可:
HAL_PWR_EnterSTANDBYMode(); // 进入 Standby 模式
修改后的循环代码如下:
/* Infinite loop */
/* USER CODE BEGIN WHILE */
HAL_PWREx_ConfigSupply(PWR_SMPS_SUPPLY); // 配置 SMPS 作为电源
HAL_PWR_EnterSTANDBYMode(); // 进入 Standby 模式
while (1)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
此时,万用表测到的电流为0.5uA,并且LED灯不闪烁(CPU已经停止,不再执行程序):

4.4 Sleep模式
进入Sleep模式的代码稍微复杂一点,带有两个参数:
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); // 进入 Sleep 模式
两个参数可用的值,在接口注释上有说明:

进入Sleep模式后,CPU暂停执行,但会被中断唤醒,包括SysTick中断,而STM32 HAL库初始化默认会启用SysTick中断。因此,如果只加了上面的一行代码,并不能进入休眠模式,需要在前面加入一行停止SysTick的调用:
HAL_SuspendTick(); // 关闭 SysTick 中断
修改后,完整的测试循环代码如下:
/* Infinite loop */
/* USER CODE BEGIN WHILE */
HAL_PWREx_ConfigSupply(PWR_SMPS_SUPPLY); // 配置 SMPS 作为电源
// 先闪烁 10 次
for (int i = 0; i < 10; i++) {
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
HAL_Delay(500);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // 熄灭 LED
HAL_SuspendTick(); // 关闭 SysTick 中断
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); // 进入 Sleep 模式
while (1) {
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // 这里不闪烁,表示正常进入了Sleep模式,CPU暂停执行了
HAL_Delay(1000);
}
/* USER CODE END 3 */
进入Sleep模式后,万用表测到的电流为219.8uA:

4.5 Stop模式
和进入Sleep模式类似,进入Stop模式的HAL接口,也带有两个参数如下:
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERMODE_STOP0, PWR_STOPENTRY_WFI); // 进入 Stop 模式
类似的,接口注释说明了两个参数都可以使用哪些值:

相应的测试循环代码如下:
/* Infinite loop */
/* USER CODE BEGIN WHILE */
HAL_PWREx_ConfigSupply(PWR_SMPS_SUPPLY); // 配置 SMPS 作为电源
// 先闪烁 10 次
for (int i = 0; i < 10; i++) {
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
HAL_Delay(500);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // 熄灭 LED
HAL_SuspendTick(); // 关闭 SysTick 中断
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERMODE_STOP0, PWR_STOPENTRY_WFI); // 进入 Stop 0 模式
while (1) {
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
HAL_Delay(1000);
}
/* USER CODE END 3 */
进入Stop 0模式后,万用表测到的电流为76uA:

类似的,修改 HAL_PWR_EnterSTOPMode
的第一个参数,就可以进入Stop 1、Stop 2、Stop 3模式。
进入Stop 1模式后,测到的电流为71.4uA:

进入Stop 2模式后,测到的电流为5.9uA:

进入Stop 3模式后,测到的电流为2.7uA:

五、数据对比
综上,实验数据整理一下,CPU时钟频率在1.5MHz时,各个功耗模式下,测得的电流值分别为:
功耗模式 |
电流值(uA) |
正常运行(LDO供电) |
1190 |
SMPS供电 |
430 |
Sleep |
219.8 |
Stop 0 |
76 |
Stop 1 |
71.4 |
Stop 2 |
5.9 |
Stop 3 |
2.7 |
Standby |
0.5 |
绘制成柱状图,对比非常明显:

六、参考链接
- NUCLEO-U385RG-Q开发板原理图: https://www.st.com.cn/resource/en/schematic_pack/mb1841-u385rgq-e01-schematic.pdf
- STM32U3系列简介: https://www.st.com.cn/zh/microcontrollers-microprocessors/stm32u3-series.html
- STM32CubeMX下载页面: https://www.st.com.cn/zh/development-tools/stm32cubemx.html
- 【经验分享】STM32低功耗模式测试: https://shequ.stmicroelectronics.cn/thread-633881-1-1.html