STM32进入standby时功耗异常分析

1. 前言

本文主要用于记录STM32单片机功耗异常的分析过程,直接看 分析原因 部分可以快速知道问题原因和解决方法。

2. 背景和现象

  • 背景:使用STM32F031系列的单片机开发锂电池应用,在电池长时间不使用时,MCU需要进入极低功耗的Standby状态。
  • 开发过程: 开发过程中没有遇到太大障碍,参考ST的官方代码,实现了Standby功能。
  • 异常现象:但是在生产测试时发现,每次烧录新的程序,单片机进入Standby状态后,功耗异常。

各场景的功耗见下表:

模式常规工作模式Standby模式(正常)Standby模式(异常)
功耗9mA2uA0.7mA

3. 分析过程

Step-1 复现异常(追踪异常的发生场景)

拿了几块功耗正常的板子,对开发与测试的场景进行了多次测试验证,发现了以下规律:

测试场景编号开发环境编译器烧录器Standby功耗
TD1Eclipse (Oxygen-4.73)Arm-GCCJ-Link偶发性异常
TD2Keil-MDK (v5.23)MDK默认编译器J-Link正常
TD3Keil-MDK (v5.23)MDK默认编译器ST-Link正常
测试场景编号生产烧录环境烧录器烧录器驱动Standby功耗
TP1STM32 ST-Link Utility (v3.7.0)ST-Linkv4.4.0全部异常
TP2SEGGER J-Flash (v5.00)J-Linkv6.10正常

本步骤结论:特定场景的软件下载方式,会触发这个异常。

补充说明:在这一步时,怀疑烧录软件配置选项有问题,于是把烧录上位机所有的选项都改了一遍,但是没有效果。

Step-2 定位与故障相关硬件(缩小排查范围)

之前测试的是整个板子的功耗,需要在这一步定位是板上的哪个器件引起的功耗异常。

因为在烧录后会引起这个故障,所以MCU的嫌疑最大。于是,用一块只贴有MCU及其外围器件的板子(MCU核心板)再次进行了Step-1的几项测试。测得MCU自身的功耗与Step-1测的板功耗结果很接近。看来,板子功耗异常是MCU引起的

使用功耗正常、功耗异常的两块MCU核心板进行对比测试,用示波器量了MCU所有管脚的状态。发现在进入Standby状态后,异常功耗MCU的SWDIO-Pin为高电平,正常的为低电平。
STM32F031F6外围电路
查看ST Reference manual(RM0091),MCU进入Standby状态,PA13(SWDIO-Pin)是高阻态。
那么,Standby状态下SWIO-Pin输出为高电平应该是个异常状态
STM32_Standby_IO_State
是因为没有固定这个脚电平?
于是,做了两个验证:

  • 外部下拉:在SWDIO脚加一个下拉电路到GND
  • 内部下拉:MCU进入Standby状态前,将SWDIO配置为下拉输入模式

结果这两种方式都没有效果。可以认定,SWDIO的高电平,与管脚电平未固定没有关系,是SWDIO自身输出(或内部上拉到)高电平。

本步骤结论:板子功耗异常是MCU引起的,此时MCU的SWDIO脚会异常输出(或内部上拉到)高电平。

Step-3 尝试恢复异常(进一步摸索异常时现象)

继续在MCU核心板上测试,尝试恢复Standby功耗异常的MCU,试了以下几种方法:

恢复方式SWDIO状态Standby功耗
唤醒信号给到Wakeup Pin (Wakeup event)高电平未恢复
拉低Reset Pin到GND1秒 (System Reset)高电平未恢复
使用Step-1中的5种方式重新烧录程序 (Download)高电平未恢复
断开板子电源后重新上电 (Power-on Reset)低电平恢复

本步骤结论:只有Power-on reset才能恢复功耗异常。

Step-4 软件Debug(定位问题)

这一步的思路是 单片机状态的差异,往往会体现在它的寄存器值上。
经过前几步的分析,得到了一些结论:

  1. 烧录软件后会触发异常。
  2. 异常与SWDIO-Pin状态有很大的相关性。
  3. Power-on reset可以恢复异常,System reset无法恢复异常。

以上这些结论指向MCU的调试功能。于是,将排查重点放到调试相关的寄存器上。
查看ST Reference manual(RM0091)对DBG寄存器的描述(下图),发现:

  • DBG相关的寄存器可以在调试/烧录时被Debugger所配置,这一点与结论1吻合。
  • DBG相关的寄存器只在Power-on reset时恢复默认值,这一点与结论3吻合。
    DBGMCU_CR
    使用Eclipse+J-Link调试功耗异常的MCU核心板,读取DBG相关的寄存器,其中DBGMCU-CR寄存器的DBG_STANDBY位为1。
    DBGMCU_REG

查看ST Reference manual(RM0091)对该位的描述(下图)。DBG_STANDBY位为1时,进入Standby模式,HCLK不会停止,而是转换为内部RC电路(内部低速晶振)作为时钟源继续运行。所以就会在异常的Standby状态下处于 比正常工作模式低,比常规standby模式高的功耗。
DBG_STANDBY
又拿了个standby模式下功耗正常的MCU核心板测了下,它的DBG_STANDBY位为0。看来很可能是这个原因。

Step-5 验证想法

在代码中增加主动将DBG_STANDBY清0的动作,放在进入Standby之前。

SET_BIT(RCC->APB2ENR, RCC_APB2ENR_DBGMCUEN);
CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);

补充说明:这里需要注意,因为DBG也是外设的一种,操作DBG寄存器前要使能其外设时钟。

将这个程序使用Step-1中的几种方式烧录到MCU中,Standby功耗都正常。
本步骤结论:DBG_STANDBY位在烧录时被Debugger配置为1,使得MCU进入Standby功耗异常。

4. 分析原因

通过以上几个步骤的排查,再结合Step-1的测试,发现与烧录上位机STM32 ST-Link Utility的设置有关。
其中有一项配置“Enable debug in low power mode”,如果勾选了。再连接MCU,点击“connect”后,会将MCU的DBG_STANDBY位写1,且在烧录完成、断开连接后不会清除。
在这里插入图片描述
又进行了4项测试:

测试编号MCU核心板类型是否勾选Enable debug in low power modeStandby功耗
1功耗正常勾选异常
2功耗正常不勾选正常
3功耗异常勾选异常
4功耗异常勾选异常

结论:

  • 使用STM32 ST-Link Utility烧录,如果在设置中勾选了“Enable debug in low power mode”,MCU进入Standby功耗会异常。
  • 如果对功耗正常的板子不勾选“Enable debug in low power mode”进行烧录,MCU进入Standby功耗正常。
  • 功耗异常的MCU无法通过不勾选“Enable debug in low power mode”再次烧录的方式恢复

5. 解决方法

在这里插入图片描述
参考ST Reference manual(RM0091), 如果MCU进入Standby功耗异常,以下三种方式可以恢复:

  1. 使用Debugger将DBG_STANDBY清0
  2. 在代码中添加了进入Standby关闭DBG_STANDBY语句,重新烧录程序(参考代码见附录)
  3. 将MCU断电,Power-on reset后恢复正常功耗

附录A:STM32进入Standby状态完整的代码

下面是STM32进入Standby模式的常规代码

void Bsp_Enter_Standby(void)
{
    /* Enable Wakeup1 pin(PA0) */
    PWR->CSR |= PWR_CSR_EWUP1;

    /* STM32F0 MCU enters standby mode*/
    PWR->CR |= PWR_CR_CWUF;                             /* Clear up wake up flag */
    PWR->CR |= PWR_CR_CSBF;                             /* Clear standby flag    */
    PWR->CR |= PWR_CR_PDDS;                             /* Select standby mode   */
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
    __WFI();                                            /* Wait for interrupt    */

    /* Then MCU will enter standby mode. After the MCU wakes up, it will run from
     * Reset_Handler */
}

下面是添加关闭DBG_STANDBY的代码

void Bsp_Enter_Standby(void)
{
    /* Enable Wakeup1 pin(PA0) */
    PWR->CSR |= PWR_CSR_EWUP1;

#if (!defined(DEBUG) || !defined(USE_DBG_STANDBY))
    /* Disable DBG_STANDBY. Prevent DBG_STANDBY from being enabled by debugger when
     * downloading programs, causing standby mode power consumption to be too high */
    SET_BIT(RCC->APB2ENR, RCC_APB2ENR_DBGMCUEN);
    CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
#endif

    /* STM32F0 MCU enters standby mode*/
    PWR->CR |= PWR_CR_CWUF;                             /* Clear up wake up flag */
    PWR->CR |= PWR_CR_CSBF;                             /* Clear standby flag    */
    PWR->CR |= PWR_CR_PDDS;                             /* Select standby mode   */
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
    __WFI();                                            /* Wait for interrupt    */

    /* Then MCU will enter standby mode. After the MCU wakes up, it will run from
     * Reset_Handler */
}
  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值