本帖最后由 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 后,记录的唤醒次数才正常。 串口收到的字符出现乱码我怀疑是从 stop 模式唤醒后 MSI 振荡器频率还没有稳定,导致串口波特率误差大引起的。 电流测试结果:(都没有开启 LSE, LSI等时钟)
在 Stop 模式下,可以开启 LSI 或者 LSE 振荡器,给RTC或者LPUART1等设备用,应该会增加一些电流消耗,顺便测一下:
开启LSE, 并启用RTC之后, 电流又增加了一些。对比手册第一页上的"420nA Standby mode with RTC"来说,我的这个测试电流大了不少。
测试一下从 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为输入,上升沿触发。 从程序里面串口输出可以看唤醒次数。为了测量唤醒时间。需要请出我的数字示波器了。 示波器一个通道测按钮上的电压,另一个通道测一个随便选的GPIO,在程序中当唤醒之后立即将这个GPIO设成高电平,而在休眠之前设成低电平。 先看下Sleep模式(2MHz)的:5个微秒多,好象有点长了。 可能跟运行频率有关系?那用4MHz试一下,大约是缩短了一半。 这个是Stop 0模式(进入前、唤醒后是2MHz运行)的,比Sleep模式的唤醒时间长了。 奇怪的是 Stop 1模式居然唤醒时间还短一点。 Stop 2模式比Stop 1模式的唤醒时间稍长一点(忘了保存截图了)。其实这个情况 Stop 0/1/2 的差别算小的了。 下面是改变了唤醒之后运行频率的,4MHz时,Stop 2模式的唤醒时间缩短,但是没缩到2MHz的一半。 选择唤醒后使用HSI16作为时钟,比MSI 4MHz短了一些。看来系统的准备时间限制住了。 但是从standby和Shutdown模式不能用EXTI来唤醒了,因为中断系统已经不能用。PC13这个引叫还有 WKUP2 功能,应该还有办法来唤醒的。 我发现在 PWR 里面把 WKUP2 唤醒功能打开就可以从 standby 唤醒了: PWR->CR3 |= PWR_CR3_EWUP2; 不过,不过,和从 Sleep/Stop 模式唤醒不一样,MCU并不执行 WFE 指令之后的程序,而是——复位了,从ResetHandler开始运行的。 这个情况在我的意料之中。现在暂且想办法测一下唤醒时间吧,那就在初始化过后就把 GPIO 设一下,让示波器抓。 这个唤醒时间就比Stop模式长了很多了,而且运行频率2MHz/4MHz的差别也不大。Shutdown模式也是同理的,都是上电重启动了。 如果要在 Standby/Shutdown 模式唤醒后接着 WFI/WFE 指令后面开始运行,需要软件上做技术处理。也没必要一定跳转到上次的位置执行,只要程序初始化时识别出是唤醒过程而非其它原因的复位,并且能恢复之前保存的软件状态,接着做唤醒之后该做的任务就好了。用Standby模式的话,可以把SRAM2的数据保留。如果还嫌功耗大,就只能用 32 个backup register来保存最重要的变量了。 总结,STM32L4R5 (以及以前的一些STM32L4型号,我没这么测过)的低功耗模式是挺省电的,几个到几十个微秒的唤醒时间,可以应付很多情况了。 |
STM32L4 超低功耗微系列及相关探索学习板介绍
STM32L476程序烧录
【NUCLEO-L476RG开发】使用STM32L4开发板玩转心率传感器
[Nucleo-L4R5] STM32L4R5 驱动OLED
[Nucleo-L4R5] STM32L4R5 基于OLED显示二维码
STM32L432KC开箱测评------OLED显示
STM32L476建工程及点亮LED
【评测站】STM32L496G-DISCO - 高性价比的智能手表解决方案
【超低功耗STM32L4系列首秀】 收到板子了,
STM32L496G-DISCO的出厂源码在哪儿可以下载?
https://www.stmcu.org.cn/module/forum/thread-614299-1-1.html
并且也会汇总到3月技术原创中~~