概念先知道
- 低功耗模式:芯片不需要干活时进入“休眠”,关掉大部分电路来省电;BL616/BL618 主要分 PDS(浅层睡眠,外设掉电)与 HBN(hibernate 深层睡眠,仅 AON 域工作)两类。
- 定时唤醒:睡眠时 32K 时钟仍在走,RTC 计时到设定时间后把芯片唤醒,例程就是每 1 秒唤醒一次。
- 唤醒源:能让芯片醒来的“闹钟”,常见有 RTC 定时、GPIO 边沿/电平、BOD 掉电检测等;例程先用
pm_pds_mask_all_wakeup_src()屏蔽全部唤醒源,再通过pm_pds_mode_enter的睡眠时间参数启用 RTC 定时唤醒。 - 睡眠时间单位:
pm_pds_mode_enter的sleep_time以 32K 时钟周期为单位(32768 个周期 = 1 秒),例程写32768 * 1。
例程功能简介
本页对应博流官方 SDK 的 pds_rtc 例程(examples/pmu/bl616/pds_rtc),演示 PDS 深度睡眠 + RTC 定时唤醒:
- 进入睡眠前:关闭 USB PHY 电源开关、屏蔽全部唤醒源、浮空 RF 的 LDO15 输出、屏蔽 HBN 引脚唤醒;
- 打印
enter pds mode后调用pm_pds_mode_enter(PM_PDS_LEVEL_15, 32768 * 1)进入 PDS level 15 最深睡眠; - 每 1 秒被 RTC 定时唤醒,重新运行主流程,形成周期唤醒循环;
- 测量功耗时可以用万用表串在供电回路观察睡眠电流(PDS 比正常运行低得多)。
- 同族例程(
examples/pmu/bl616/):hbn_rtc(HBN 深层睡眠 + RTC 唤醒)、hbn_io_wakeup(HBN + GPIO 唤醒)、pds_io_wakeup(PDS + GPIO 唤醒)。
注意
进入睡眠后串口打印会停顿,唤醒瞬间才会再次打印;这是睡眠生效的表现。用串口工具观察时请勿拔掉调试线,否则调试口供电变化可能影响功耗测量。
操作步骤
本页不需要额外接线。在终端进入 SDK 的 PDS 睡眠例程目录(前提:已按快速开始(Linux)或Windows搭建好环境):
cd examples/pmu/bl616/pds_rtc执行编译命令。Ai-M62(BL616)与 Ai-M61(BL618)同属一个系列,统一填写引脚最少的 bl616 即可:
make CHIP=bl616 BOARD=bl616dk用 USB 线连接开发板,按住 BOOT 键(Ai-M61-32S-Kit 为 IO2)不放、短按 EN/RST 进入下载模式,然后执行烧录(把串口号换成实际值):
make flash CHIP=bl616 COMX=/dev/ttyUSB0打开串口助手(波特率 2000000)。程序打印 enter pds mode 后进入 PDS 深度睡眠,1 秒后由 RTC 定时唤醒,唤醒后打印同样的提示并再次入睡,形成每 1 秒唤醒一次的循环;可以串口观察周期性的打印。
代码执行流程
例程从启动到进入睡眠、再被定时唤醒的完整流程如下(图中的循环箭头表示反复执行):
例程调用的 API 介绍
BL_RD_REG / BL_CLR_REG_BIT / BL_WR_REG(base, reg / bit / val)
寄存器位操作宏:BL_RD_REG 读寄存器、BL_CLR_REG_BIT 清某一位、BL_WR_REG 写回寄存器。例程用它们关闭 USB PHY 的电源开关位 PDS_REG_PU_USB20_PSW。
参数:
base:寄存器基地址(例程PDS_BASE)reg:寄存器偏移(例程PDS_USB_PHY_CTRL)val:写入值 / 位号
返回值:BL_RD_REG 返回寄存器值;宏本身无返回值
pm_pds_mask_all_wakeup_src()
屏蔽(关闭)全部 PDS 唤醒源,避免意外唤醒。例程随后仅通过 pm_pds_mode_enter 的定时参数实现 RTC 定时唤醒。
参数:无
返回值:无
HBN_Pin_WakeUp_Mask(0xF)
屏蔽 HBN(AON)引脚唤醒:0xF 表示 4 个唤醒引脚(IO16~IO19)全部屏蔽。
参数:
maskVal:引脚掩码,置 1 的位对应引脚被屏蔽
返回值:BL_Err_Type
pm_pds_mode_enter(pds_level, sleep_time)
进入 PDS 睡眠。sleep_time 单位为 32K 时钟周期(32768 = 1 秒);为 0 时不做 RTC 定时唤醒,只能靠其他唤醒源(如 GPIO)。
参数:
pds_level:睡眠等级,例程PM_PDS_LEVEL_15(最深)sleep_time:睡眠时长(32K 周期数),例程32768 * 1(1 秒)
返回值:无
完整代码
以下为 pds_rtc/main.c 完整源码,与官方示例(examples/pmu/bl616/pds_rtc)逐字一致,默认折叠,点击展开:
📜 点击展开 pds_rtc/main.c 完整代码
#include "bflb_mtimer.h"
#include "board.h"
#include "log.h"
#include "bl616_glb.h"
#include "bl616_pds.h"
#include "bl616_hbn.h"
#include "bl616_aon.h"
#include "bl616_pm.h"
int main(void)
{
uint32_t tmpVal = 0;
board_init();
/* rf808_usb20_psw_rref output off */
tmpVal = BL_RD_REG(PDS_BASE, PDS_USB_PHY_CTRL);
tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_REG_PU_USB20_PSW);
BL_WR_REG(PDS_BASE, PDS_USB_PHY_CTRL, tmpVal);
pm_pds_mask_all_wakeup_src();
AON_Output_Float_LDO15_RF();
HBN_Pin_WakeUp_Mask(0xF);
printf("enter pds mode\r\n");
bflb_mtimer_delay_ms(100);
/* Wake up every 1 seconds by pds15 */
pm_pds_mode_enter(PM_PDS_LEVEL_15, 32768 * 1);
while (1) {
}
}FAQ
进入睡眠后无法唤醒
检查唤醒源配置:pm_pds_mode_enter 的 sleep_time 为 0 时不会定时唤醒,需要配置 GPIO 等唤醒源;同时确认没有误调用 pm_pds_mask_all_wakeup_src() 之后又忘记打开所需的唤醒源。
唤醒周期不是 1 秒
sleep_time 单位是 32K 时钟周期。若 32K 时钟不准(RC 32K 未校准),实际唤醒间隔会有偏差;对时间精度要求高时可用外部 32.768K 晶振或调用 pm_rc32k_auto_cal() 校准。
PDS 与 HBN 有什么区别
PDS 睡眠更浅、唤醒更快,外设断电但 SRAM 内容保持;HBN(hibernate)只保留 AON 域,功耗更低。电池供电的间歇上报场景常组合使用:平时 HBN,事件到来再启动到 PDS 处理任务。
遇到问题?
如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions

