Skip to content

概念先知道

  • 低功耗模式:芯片不需要干活时进入“休眠”,关掉大部分电路来省电;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_entersleep_time32K 时钟周期为单位(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 唤醒)。

注意

进入睡眠后串口打印会停顿,唤醒瞬间才会再次打印;这是睡眠生效的表现。用串口工具观察时请勿拔掉调试线,否则调试口供电变化可能影响功耗测量。

操作步骤

1
进入例程目录

本页不需要额外接线。在终端进入 SDK 的 PDS 睡眠例程目录(前提:已按快速开始(Linux)Windows搭建好环境):

cd examples/pmu/bl616/pds_rtc
2
编译工程

执行编译命令。Ai-M62(BL616)与 Ai-M61(BL618)同属一个系列,统一填写引脚最少的 bl616 即可:

make CHIP=bl616 BOARD=bl616dk
3
烧录固件

用 USB 线连接开发板,按住 BOOT 键(Ai-M61-32S-Kit 为 IO2)不放、短按 EN/RST 进入下载模式,然后执行烧录(把串口号换成实际值):

make flash CHIP=bl616 COMX=/dev/ttyUSB0
4
运行验证

打开串口助手(波特率 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 定时唤醒。

参数:无

返回值:无

AON_Output_Float_LDO15_RF()

将 RF 供电的 LDO15 输出设为浮空,睡眠时进一步降低功耗。

参数:无

返回值BL_Err_TypeSUCCESS 为 0)

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 完整代码
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_entersleep_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

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