打印
[活动专区]

【AT-START-L021 测评】一箭三星展示低功耗模式的进入/唤醒与功耗测量

[复制链接]
100|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 xhackerustc 于 2024-12-28 23:00 编辑

#申请原创#
@21小跑堂

笔者认为AT32L021系列最吸引人的就是它的低功耗特性,所以这篇评测就以低功耗为主题展开,侧重于各种低功耗模式的进入与唤醒,顺便测量下对应模式下的功耗。

1. 三种低功耗模式
AT32L021有三种低功耗模式,分别是:睡眠模式(sleep)、深睡眠模式(deepsleep)以及待机模式(standby)。其中:

1.1 sleep模式
通过执行WFI或WFE指令即可进入该模式,这应该是所有armv7m或armv8m的标准动作。该模式下只有CPU停止工作,MCU中所有外设仍处于工作状态,当发生中断等WFI/WFE唤醒事件时,CPU会被唤醒退出sleep模式。此模式下因停止工作的部件并不多,所以唤醒也是比较迅速的。任何中断都可以把cpu唤醒。笔者认为这种模式的进入与退出都很方便而且可以说几乎 没有副作用,在程序设计中不妨always enable。

1.2 deepsleep模式
通过设置Cortex-M0+的SLEEPDEEP位(此为cortex-m0+标准动作),清除PWC_CTRL的LPSEL位(这个寄存器应该是各家MCU各显神通的地方,都不一样)后再执行WFI或WFE指令(arm标准动作)即可进入该模式。该模式下,所有1.2V域的时钟都被关闭,HICK和HEXT也都被关闭,regulator以正常工作状态或低功耗工作状态给1.2V域供电,所有 I/O 管脚、sram内容以及寄存器内容都能够保持。唤醒时,因需要等待regulator稳定下来,所以唤醒延时比sleep模式大。唤醒来源是能配置成EXINT的信号,比如任意16个外部GPIO之一、ERTC alarm、i2c1/USART1/USART2等。相比sleep模式, 优点是更省电一些,但此低功耗模式的唤醒源受限,且唤醒延时大一些。

1.3 standby模式
通过设置Cortex-M0+的SLEEPDEEP位,并设置PWC_CTRL的LPSEL位并清除PWC_CTRLSTS的SWEF位(PWC_CTRLSTS这个寄存器是AT特有的,各家MCU进入standby模式方法不太一样),执行WFI或WFE指令即可进入该模式。该模式下除VDD/VDDA 域维持供电外,regulator、1.2V域、PLL、HICK以及HEXT都被断电。所以寄存器和SRAM的内容并不能保持。这种模式你有没有发现,其实和断电差不了太多,所以它的功耗极低,但它也有代价,唤醒延迟几乎和重新启动差不多了,所以唤醒延迟是三种低功耗模式中最大的一个。唤醒源是:NRST外部复位信号、WDT复位、WKUPin引脚上的一个上升沿、以及ERTC alarm/tamper/wakeup等。这种模式可以用于时间比较长的周期性的待机,比如用于手持温度计用完再延时一段时间后(这段较短时间可用sleep模式)进入standby模式,大大延长电池的使用时间。

2. 一个用例(一箭)测三种低功耗模式(三星)的进入与唤醒
官方固件库其实对三种低功耗模式都有示例,但笔者想只用一个测试用例就能展示完AT32L021的所有三种低功耗模式特性,并做功耗测量,来看看笔者怎么做到的吧。

2.1 整体设计思路
每进入一个低功耗模式后,在唤醒前用万用表测量电流,完毕后触发唤醒条件后闪烁不同的LED灯三次,然后进入下一个低功耗模式。说来也巧,AT-START-L021开发板恰好有三个LED可以由 程序控制,分别为LED2(红)、LED3(黄)和LED4(绿),咱们就用闪烁它们之一三次分别表示成功退出sleep模式、deepsleep模式以及standby模式。伪代码如下所示:

try_sleep();

blink(LED2);

try_deepsleep();

blink(LED3);

try_standby();

blink(LED4);

为做演示,sleep模式唤醒源用的是串口输入;deepsleep模式唤醒源用的是ERTC的wakeup;standby模 式用的是板载的USER按键。据原理图,USER按键接的是PA0,恰好是WKUPin之一,从这一点相信你也能 体会到官方这块开发板设计之妙。

2.2 笔者的核心流程代码如下:
  crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);

  /* config usart1 */
  usart1_config(115200);

  if(pwc_flag_get(PWC_STANDBY_FLAG) != RESET)
  {
    /* wakeup from standby */
    pwc_flag_clear(PWC_STANDBY_FLAG);
    printf("exit deepsleep mode\r\n");
    blink(LED4);
  }

  delay_ms(500);

  printf("enter sleep mode\r\n");
  try_sleep();
  printf("exit sleep mode\r\n");
  blink(LED2);

  printf("enter deepsleep mode\r\n");
  try_deepsleep();
  printf("exit deepsleep mode\r\n");
  blink(LED3);

  printf("enter standby mode\r\n");
  try_standby();


2.3 演示视频
附上视频演示下一箭(测试用例)三星(三低功耗模式)的进入与退出吧:https://www.bilibili.com/video/BV1ezChYfEAb/

由视频可知,板子重启后,很快即进入sleep模式,然后有个清脆的键盘敲击声,这是利用串口唤醒源(笔者在PC上用minicom连接了板子的串口),红灯闪烁三次,表明成功从sleep模式唤醒;随即进入deepsleep模式,然后等待16s,黄灯闪烁三次,这表明成功从deepsleep模式唤醒;唤醒后随即进入standby模式,然后按USER键一次,绿灯闪烁三次,这表明成功从standby模式唤醒。

3 各低功耗模式下的电流测量
本来测量电流,需要把R13电阻拿掉,然后利用JP3处的IDD测电流,但笔者这里偷了个懒,直接用JP2的两个引脚测了,毕竟后面想再用这块开发板还得把R13再焊上去,笔者这人做事向来是能偷懒就偷懒:D
而且这板子支持通过改动JP2的跳线连接选择MCU是3.3v还是1.8v供电,其实想都别想肯定是1.8V电流小,咱只测1.8V吧,3.3V留给读者:D

还是利用上面的测试用例,跑一遍可以把三个低功耗模式的电流消耗全部测完。

3.1 sleep模式电流

4.55mA还不错,笔者只用了串口,和官方数据也能对上。

3.2 deepsleep模式电流

0.13mA这个数据比官方给的数据大,笔者家里这万用表也不行,不知道是万用表问题呢还是程序哪里写得不太对,不过笔者以往deepsleep模式用得比较少,也不太在乎。

3.3 standby模式电流

哇!0.00mA,哈这万用表测不出来电流了,但是从上面0.13mA猜测standby模式电流应该小于个位数的uA级 ,但具体个位数是几需要上精确专业些的工具,万用表就别凑数了。


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

25

主题

84

帖子

0

粉丝