Skip to content

概述

物联网设备常需电池供电,睡眠模式是降低功耗的核心手段。Ai-WB2 支持 Deep Sleep(深睡眠,大白话:开发板像人睡着一样,CPU 停转、外设关闭,几乎不耗电):仅保留 4KB Retention RAM(保留内存,大白话:睡觉时也一直供电、不会丢数据的小内存)与 RTC(实时时钟,大白话:芯片内置的"闹钟",到点自动叫醒开发板)唤醒能力,功耗可低至 µA 级(微安,电流单位,深睡眠时约等于一节纽扣电池用数年)。本教程演示 按键进入深睡眠 + 定时自动唤醒,并用保留 RAM 验证唤醒后的数据保持。

用大白话讲:深睡眠就像你晚上睡觉——人睡着后几乎不耗能量,但体内的生物钟(相当于开发板的 RTC 闹钟)到点会把你叫醒,醒来你还记得睡前的事(相当于保留 RAM 里的数据没丢)。本教程就是让开发板"睡 10 秒再醒",醒来看看睡前记的数据还在不在。

本教程基于安信可官方 SDKAi-Thinker-Open/Ai-Thinker-WB2,版本 release_bl_iot_sdk_1.6.40)的官方示例 applications/system/deep_sleep 编写,代码可在本地 SDK 中直接找到。

🎯本页目标通过按键触发深睡眠、定时 10 秒自动唤醒,并验证保留 RAM 中的数据在睡眠期间不丢失。
🧰前置条件① Ai-WB2 开发板一块、按键/杜邦线 ② 已按 [SDK 安装](../sdk/sdk_intro) 完成环境搭建。
🔗相关章节唤醒引脚相关输入配置见 [GPIO输入(按键)](../basic/gpio_button);系统复位见 [软件复位](./soft_reboot)。

硬件接线

按官方示例接线:

Ai-WB2 引脚 外设
IO4 按键(按下接 GND,检测进入睡眠)
IO7 唤醒引脚(悬空即可,定时唤醒无需外部触发)
GND 按键另一端

💡 官方示例 sleep_time_ms = 10000定时自动唤醒(10 秒后 RTC 唤醒);若设为 0,则只能由 IO7 电平变化唤醒(接按键按下唤醒)。唤醒引脚仅支持 GPIO7 / GPIO8。

进入示例工程

打开终端,进入官方 deep_sleep 示例工程目录:

cd ~/Ai-Thinker-WB2/applications/system/deep_sleep

说明:cd 是"进入目录"的命令,~ 表示你的用户主目录。这条命令进入 deep_sleep 示例工程,后面所有 make 命令都要在这个目录里执行;如果提示 No such file or directory(没有这个目录),说明路径不对,见文末 FAQ。

编写代码

打开 deep_sleep/main.c,本步完整代码已移至文末,见:

📜 完整代码 — 位于本页「完整代码」章节,默认折叠,点击展开,与官方示例(applications/system/deep_sleep/deep_sleep/main.c)完全一致。

代码要点:

代码 作用
#define test (*(volatile uint8_t*)0x40010000) 定义保留 RAM 中的测试变量;只有用它才能在睡眠后验证数据没丢
bl_gpio_enable_input(ENTER_SLEEP_PIN, 0, 0) 把 IO4 配成输入;不配输入模式就读不到按键按下
!bl_gpio_input_get_value(ENTER_SLEEP_PIN) 读取 IO4 电平;按键按下拉低返回 0,取反后进睡眠
test++ 每次睡眠前给计数器 +1;唤醒后数值变大了说明数据没丢
hal_hbn_init(&weakup_pin, 1) 告诉芯片用 IO7 当唤醒引脚;不设置则无法靠外部唤醒
hal_hbn_enter(sleep_time_ms) 真正"睡觉"10 秒;传 0 则不自动醒,只能等 IO7 触发

💡 保留 RAM(Retention RAM):位于 0x40010000 的 4KB 内存,Deep Sleep 期间供电保持,用于在唤醒后恢复现场。唤醒后变量值仍在,这是本示例验证睡眠功能的关键。

编译工程

在工程目录执行编译:

make -j8

说明:make 是"编译工程"的命令,把源代码翻译成开发板能运行的机器码;-j8 表示用 8 个核心并行编译,更快。

编译成功后生成固件 build_out/deep_sleep.bin(固件:编译后烧进开发板的程序,相当于开发板的"操作系统+你的程序")。

烧录固件

开发板保持 USB 连接,确认串口设备号后执行烧录:

make flash p=/dev/ttyUSB0 b=921600

说明:make flash 是"烧录"命令,把编译好的固件下载进芯片(烧录:把程序写进芯片的过程);p=/dev/ttyUSB0 是串口设备号,要换成你电脑上实际的串口(Windows 下形如 COM3),b=921600 是烧录波特率(传输速度)。

⏳ 烧录过程中按提示长按开发板 EN 键进入下载模式,等待进度条完成即烧录成功。若一直卡在等待或报串口打不开,见文末 FAQ。

运行验证

烧录完成后打开串口助手(波特率 921600),初始打印:

test:0

按下 IO4 按键,日志变为:

test:0
enter sleep

开发板进入深睡眠(整板电流降至 µA 级),10 秒后自动唤醒,再次打印:

test:1

💡 关键验证:唤醒后 test 的值从 0 变为 1,说明保留 RAM 在深睡眠期间数据未丢失。每次进入睡眠前 test++,唤醒后数值持续累加(0→1→2→…)。

⚠️ 功耗测量:用万用表串接开发板电源正极测电流,睡眠期间电流应降至 µA 级(约 10µA 以下),唤醒瞬间恢复 mA 级。

预期结果:出现 enter sleep,10 秒后自动唤醒并打印 test:1(数值递增),即验证通过。若只看到 test:0 而始终没有 enter sleep,说明没进入睡眠,见文末 FAQ。

代码执行流程

例程从启动到运行的完整流程如下(图中的循环箭头表示反复执行):


本文 API 汇总

bl_gpio_enable_input(pin, pullup, pulldown)

把指定引脚配置为数字输入模式,可读取按键、传感器高低电平(本教程用于检测按键按下进入睡眠)。

参数

  • pin:引脚号,可选值:0~22(GPIO0~GPIO22),本教程按键用 4ENTER_SLEEP_PIN
  • pullup:是否使能内部上拉,可选值:1 使能 / 0 关闭(本示例传 0,按键需外接上拉电阻)
  • pulldown:是否使能内部下拉,可选值:1 使能 / 0 关闭

返回值:成功返回 0;失败返回负值错误码

bl_gpio_input_get_value(pin)

读取指定引脚当前电平状态。

参数

  • pin:引脚号,可选值:0~22

返回值:返回电平值:1 高电平 / 0 低电平(读取失败时返回 0

hal_hbn_init(pinbuf, pinbuf_size)

配置深睡眠唤醒引脚与数量,进入睡眠前调用一次。

参数

  • pinbuf:唤醒引脚号数组指针(仅支持 GPIO7 / GPIO8),本教程为 &weakup_pin(值为 7
  • pinbuf_size:数组长度(唤醒引脚个数),可选值:0~2

返回值:成功返回 0;失败返回负值错误码

hal_hbn_enter(time)

让芯片进入 HBN 深睡眠,功耗降至 µA 级;CPU 停转、日志停止输出,唤醒后从 main 开头重新执行。

参数

  • time:睡眠时长(毫秒),可选值:0 表示仅由引脚唤醒(不定时唤醒)/ 非 0 表示 RTC 定时到点自动唤醒,本教程 10000(10 秒)

返回值:不返回(调用即睡,唤醒后程序重新启动)

vTaskDelay(ms)

让当前任务挂起指定毫秒数,期间让出 CPU 给其他任务。

参数

  • ms:延时毫秒数,可选值:任意非负整数(内部经 pdMS_TO_TICKS 换算为系统节拍)

返回值:无


完整代码

以下为 deep_sleep/main.c 完整源码,与官方示例(applications/system/deep_sleep/deep_sleep/main.c)完全一致:

📜 点击展开 deep_sleep/main.c 完整代码
c
#include <stdio.h>
#include <string.h>
#include <FreeRTOS.h>
#include <task.h>
#include <blog.h>
#include "bl_sys.h"
#include <stdint.h>
#include <string.h>
#include "bl_sys.h"
#include "FreeRTOS.h"
#include "task.h"
#include "hosal_rng.h"
#include "hal_hbn.h"
#include <bl_gpio.h>

#define ENTER_SLEEP_PIN 4
#define WEAKUP_PIN 7
#define test (*((volatile uint8_t *)0x40010000)) // Deep sleep memory (Retention RAM),  size : 4KB

void main(void)
{
    uint32_t sleep_time_ms = 10000; // deep sleep time, If you do not need to periodically wake up, set sleep_time_ms=0
    uint8_t weakup_pin;
    bl_gpio_enable_input(ENTER_SLEEP_PIN, 0, 0);
    printf("test:%d\r\n", test);
    vTaskDelay(pdMS_TO_TICKS(100));
    weakup_pin = WEAKUP_PIN;
    for (;;)
    {
        if (!bl_gpio_input_get_value(ENTER_SLEEP_PIN))
        {
            printf("enter sleep\r\n");
            test++;
            vTaskDelay(pdMS_TO_TICKS(100));
            hal_hbn_init(&weakup_pin, 1);
            hal_hbn_enter((uint32_t)sleep_time_ms);
        }
        vTaskDelay(pdMS_TO_TICKS(5));
    }
}

常见问题与踩坑提示

⚠️ 按下按键无反应(未进入睡眠)
原因:按键接线错误,或 IO4 内部无上拉导致电平抖动
解决:确认按键一端接 IO4、一端接 GND;按键需外接 10kΩ 上拉到 3V3(官方 bl_gpio_enable_input(4, 0, 0) 未开内部上拉)

⚠️ 定时唤醒不生效(一直沉睡)
原因sleep_time_ms = 0 时不会定时唤醒
解决:需要自动唤醒时传非 0 毫秒值;只想引脚唤醒则保持 0(IO7 接按键,按下唤醒)

⚠️ 唤醒后 test 值被清零
原因:睡眠期间发生 POR 复位(如外部 RESET 引脚被拉低、电源掉电)而非正常唤醒
解决:确认唤醒由 RTC 定时或 IO7 触发;测试时不要按开发板 RST 键(RST 会清零保留 RAM)

⚠️ 睡眠后无法烧录固件
原因:芯片处于深睡眠,下载模式未进入
解决:烧录时长按 EN 键(或重新上电后立即烧录),等下载模式建立后松开

⚠️ 串口打不开 / 找不到 /dev/ttyUSB0
原因:USB 转串口驱动未装、串口被占用,Linux 下还可能是没有访问权限
解决:Linux 用 lsusb 确认设备被识别,sudo chmod 666 /dev/ttyUSB0 或把用户加入 dialout 组后重试;Windows 在设备管理器查看 COM 口并安装 CH340/CP210x 驱动

⚠️ cd 报错 No such file or directory / 找不到 Makefile
原因:没进入示例工程目录就执行了 make,或 SDK 安装路径与教程不同
解决:先 cd ~/Ai-Thinker-WB2/applications/system/deep_sleep 再执行 make;若 ~/Ai-Thinker-WB2 不存在,用 find ~ -name "Ai-Thinker-WB2" 找到 SDK 实际位置

运行自检

按下 IO4 后打印 enter sleep,10 秒自动唤醒且 test 值递增,即深睡眠功能验证通过。

遇到问题?

如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions

Released under the MIT License. Build Time 2026-09-11 14:52:23