请选择 进入手机版 | 继续访问电脑版

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

STM32L4R5 低功耗模式及唤醒

[复制链接]
cruelfox 提问时间:2018-3-1 23:56 /
本帖最后由 cruelfox 于 2018-3-2 01:01 编辑

  前一个帖子 https://www.stmcu.org.cn/module/forum/thread-614926-1-1.html 我已经列出了 Nucleo-L4R5 在2MHz下的运行和Sleep模式下的电流测量结果。下面测试内容是更低功耗的模式:Stop, Standby 和 Shutdown.

  进入 Sleep 模式之外的省电模式,需要设置 Cortex-m4 的 SCB_SCR 寄存器 SLEEPDEEP 位,也就是启用深度睡眠模式。对于 STM32L4R5, 再根据 PWR_CR1 寄存器中 LPMS[2:0] 位的设置来确定是哪一个低功耗模式。最后再用 WFI/WFE 方法进入休眠模式,代码也不复杂。例如要到 Stop 1模式,可以这么设置:
      SCB->SCR|=1<<SCB_SCR_SLEEPDEEP_Pos;      
      tmp=PWR->CR1;
      tmp &= ~ PWR_CR1_LPMS_Msk;
      PWR->CR1 = tmp|PWR_CR1_LPMS_STOP1;

然后在想休眠时执行 __WFI(); 或者是 __WFE(); 就可以了。

  注意,在 Stop 0/1/2 模式下,所有寄存器都是保持的,SRAM1, SRAM2 内容也是保持的,SRAM3 是否保持是可选的。但是在 Standby 和 Shutdown 模式下,绝大部分寄存器内容都丢失了,SRAM除了可以在Standby模式下选择保持之外也是要掉电的,唤醒之后系统是复位过程。保持现场是要付出功耗的代价的。
  我的测试程序中使用了一个局部变量来记录唤醒次数,堆栈在SRAM3中。在 Stop2 模式下,若不启用SRAM3内容保持,堆栈中的数据就丢掉了,于是可以看到程序打印出的数值是随机变化的。当 PWR_CR1 设置 RRSTP=1 后,记录的唤醒次数才正常。
stop2_sram3.PNG
  串口收到的字符出现乱码我怀疑是从 stop 模式唤醒后 MSI 振荡器频率还没有稳定,导致串口波特率误差大引起的。
  电流测试结果:(都没有开启 LSE, LSI等时钟)
shutdown.jpg
低功耗模式 电流
Stop 0250µA
Stop 194µA
Stop 22.70µA
Stop2 + SRAM3保持4.34µA
Standby0.11µA
Standby + SRAM2保持0.53µA
Shutdown0.02µA
  我的万用表分辨率最小只有 0.02µA,所以 Shutdown 模式的电流只能看个大概了。

  在 Stop 模式下,可以开启 LSI 或者 LSE 振荡器,给RTC或者LPUART1等设备用,应该会增加一些电流消耗,顺便测一下:
Stop 2Stop 2 + LSE Stop 2 + LSI
2.69µA3.07µA 2.95µA
  启用 LSE 增加大约0.3uA的电流消耗,和手册上数据差不多,这是要使用RTC所需要的。LSI能省一点电,但是作为时钟就不精确了。

  开启LSE, 并启用RTC之后,  电流又增加了一些。对比手册第一页上的"420nA Standby mode with RTC"来说,我的这个测试电流大了不少。
Stop 2 +RTCStandby + RTC Shutdown +RTC
3.28µA 0.75µA  0.66µA  
  奇怪了,我又仔细核对了手册中的表格数据,明白是怎么回事了:420nA那个说明是RTC部分大约带来了0.3µA 的消耗,但是没有算32k晶体振荡器的功耗  所以带上晶体一起算,按照最低的Shutdown模式看也需要0.66µA 的电流才行。我猜如果是为了定时唤醒的话,用LSI+IWDG功耗更省吧。

  测试一下从 Stop 模式唤醒的时间吧。
  Nucleo板子有一个现成的用户按钮,在L4R5这个板子上按钮是接在 PC13 脚的。用 EXTI 可以检测这个引脚的上升或下降沿,产生中断或者事件,用来唤醒CPU. 我用的是事件方式,这样少处理ISR函数,简单一点。休眠时用 __WFE(); 等待事件即可。
        RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
        EXTI->EMR1 = 1<<13;                // unmask event
        EXTI->RTSR1 = 1<<13;        // rising edge
        SYSCFG->EXTICR[3] = SYSCFG_EXTICR4_EXTI13_PC;        // use PC13 EXTI
以上代码是配置了EXTI13这条外部请求线,并选择了PORTC为输入,上升沿触发。

  从程序里面串口输出可以看唤醒次数。为了测量唤醒时间。需要请出我的数字示波器了。
probe.jpg
  示波器一个通道测按钮上的电压,另一个通道测一个随便选的GPIO,在程序中当唤醒之后立即将这个GPIO设成高电平,而在休眠之前设成低电平。

  先看下Sleep模式(2MHz)的:5个微秒多,好象有点长了。
20180301230416.png
  可能跟运行频率有关系?那用4MHz试一下,大约是缩短了一半。
20180301230656.png
  这个是Stop 0模式(进入前、唤醒后是2MHz运行)的,比Sleep模式的唤醒时间长了。
20180301230820.png
  奇怪的是 Stop 1模式居然唤醒时间还短一点。
20180301230924.png
  Stop 2模式比Stop 1模式的唤醒时间稍长一点(忘了保存截图了)。其实这个情况 Stop 0/1/2 的差别算小的了。

  下面是改变了唤醒之后运行频率的,4MHz时,Stop 2模式的唤醒时间缩短,但是没缩到2MHz的一半。
20180301231608.png
  选择唤醒后使用HSI16作为时钟,比MSI 4MHz短了一些。看来系统的准备时间限制住了。
20180301231732.png


  但是从standby和Shutdown模式不能用EXTI来唤醒了,因为中断系统已经不能用。PC13这个引叫还有 WKUP2 功能,应该还有办法来唤醒的。
pc13.PNG
  我发现在 PWR 里面把 WKUP2 唤醒功能打开就可以从 standby 唤醒了:
      PWR->CR3 |= PWR_CR3_EWUP2;

  不过,不过,和从 Sleep/Stop 模式唤醒不一样,MCU并不执行 WFE 指令之后的程序,而是——复位了,从ResetHandler开始运行的。
这个情况在我的意料之中。现在暂且想办法测一下唤醒时间吧,那就在初始化过后就把 GPIO 设一下,让示波器抓。
20180302002832.png
  这个唤醒时间就比Stop模式长了很多了,而且运行频率2MHz/4MHz的差别也不大。Shutdown模式也是同理的,都是上电重启动了。

  如果要在 Standby/Shutdown 模式唤醒后接着 WFI/WFE 指令后面开始运行,需要软件上做技术处理。也没必要一定跳转到上次的位置执行,只要程序初始化时识别出是唤醒过程而非其它原因的复位,并且能恢复之前保存的软件状态,接着做唤醒之后该做的任务就好了。用Standby模式的话,可以把SRAM2的数据保留。如果还嫌功耗大,就只能用 32 个backup register来保存最重要的变量了。


  总结,STM32L4R5 (以及以前的一些STM32L4型号,我没这么测过)的低功耗模式是挺省电的,几个到几十个微秒的唤醒时间,可以应付很多情况了。

评分

参与人数 1 ST金币 +20 收起 理由
creep + 20 赞一个!

查看全部评分

收藏 评论3 发布时间:2018-3-1 23:56

举报

3个回答
waiman 回答时间:2018-3-2 00:21:07
厉害
zero99 回答时间:2018-3-2 09:27:51
不错的文章,谢谢分享!已汇总到
https://www.stmcu.org.cn/module/forum/thread-614299-1-1.html

并且也会汇总到3月技术原创中~~
zhang7309 回答时间:2018-3-3 22:26:08
感谢分享            
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版