概述
物联网设备常需电池供电,睡眠模式是降低功耗的核心手段。Ai-WB2 支持 Deep Sleep(深睡眠,大白话:开发板像人睡着一样,CPU 停转、外设关闭,几乎不耗电):仅保留 4KB Retention RAM(保留内存,大白话:睡觉时也一直供电、不会丢数据的小内存)与 RTC(实时时钟,大白话:芯片内置的"闹钟",到点自动叫醒开发板)唤醒能力,功耗可低至 µA 级(微安,电流单位,深睡眠时约等于一节纽扣电池用数年)。本教程演示 按键进入深睡眠 + 定时自动唤醒,并用保留 RAM 验证唤醒后的数据保持。
用大白话讲:深睡眠就像你晚上睡觉——人睡着后几乎不耗能量,但体内的生物钟(相当于开发板的 RTC 闹钟)到点会把你叫醒,醒来你还记得睡前的事(相当于保留 RAM 里的数据没丢)。本教程就是让开发板"睡 10 秒再醒",醒来看看睡前记的数据还在不在。
本教程基于安信可官方 SDK(Ai-Thinker-Open/Ai-Thinker-WB2,版本
release_bl_iot_sdk_1.6.40)的官方示例applications/system/deep_sleep编写,代码可在本地 SDK 中直接找到。
按官方示例接线:
| 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),本教程按键用4(ENTER_SLEEP_PIN)pullup:是否使能内部上拉,可选值:1使能 /0关闭(本示例传0,按键需外接上拉电阻)pulldown:是否使能内部下拉,可选值: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 秒)
返回值:不返回(调用即睡,唤醒后程序重新启动)
完整代码
以下为 deep_sleep/main.c 完整源码,与官方示例(applications/system/deep_sleep/deep_sleep/main.c)完全一致:
📜 点击展开 deep_sleep/main.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

