Skip to main content

Seeed Studio XIAO nRF54L15(Sense) 入门指南

Seeed Studio XIAO nRF54L15Seeed Studio XIAO nRF54L15 Sense

介绍

Seeed Studio XIAO nRF54L15 是一款紧凑、高性能的开发板,搭载了前沿的 Nordic nRF54L15 芯片。这款下一代 SoC 集成了超低功耗多协议 2.4 GHz 无线电和包含 128 MHz Arm® Cortex®-M33 处理器以及用于高级电源管理的 Arm® Cortex®-M0+ 的 MCU。它提供高达 1.5 MB NVM 和 256 KB RAM 的可扩展内存,以及显著延长电池寿命的内部超低功耗设计。其强大的无线电支持 Bluetooth® 6.0(包括信道探测)、Matter、Thread、Zigbee,以及高达 4 Mbps 的高吞吐量 2.4 GHz 专有模式。该开发板包含全面的外设集、集成的 128 MHz RISC-V 协处理器,以及诸如 TrustZone® 隔离和加密引擎保护等高级安全功能。凭借内置锂离子电池管理,XIAO nRF54L15 非常适合紧凑、安全且节能的物联网解决方案,如智能可穿戴设备、工业传感器和高级人机界面。

规格参数

项目XIAO nRF54L15XIAO nRF54L15 Sense
MCUArm Cortex-M33 128 MHz
RISC-V 协处理器 128 MHz FLPR
Arm Cortex-M33 128 MHz
RISC-V 协处理器 128 MHz FLPR
无线连接

Bluetooth LE 6.0(包括信道探测)
NFC
Thread
Zigbee
Matter
Amazon Sidewalk
专有 2.4 GHz 协议

Bluetooth LE 6.0(包括信道探测)
NFC
Thread
Zigbee
Matter
Amazon Sidewalk
专有 2.4 GHz 协议

内存NVM 1.5 MB + RAM256 KBNVM 1.5 MB + RAM256 KB
内置传感器6 轴 IMU(LSM6DS3TR-C)
麦克风 (MSM261DGT006)
发射功率+8 dBm+8 dBm
接收灵敏度-96 dBm-96 dBm
重点外设14 位 ADC,全局 RTC14 位 ADC,全局 RTC
电源

USB Type-C 接口供电
内部 PMIC 支持锂电池供电
支持锂电池电量采集

USB Type-C 接口供电
内部 PMIC 支持锂电池供电
支持锂电池电量采集

工作温度-40 到 105°C-40 到 105°C
供电电压范围3.7 到 5 V3.7 到 5 V
ESB 和 2.4 GHz 专有协议高达 4 Mbps高达 4 Mbps
篡改检测器
蓝牙信道探测

特性

  • 强大的 CPU:128 MHz Arm® Cortex®-M33 处理器,支持 DSP 指令和 FPU 浮点运算,32 位 RISC 架构,集成 128 MHz RISC-V 协处理器。
  • 超低功耗:专为卓越的超低功耗设计,显著延长电池寿命,包含高级电源管理。
  • 多模式无线传输:集成 2.4 GHz 多协议无线收发器,支持低功耗蓝牙(包括信道探测)、802.15.4-2020、Matter、Thread、Zigbee 和 2.4 GHz 专有模式(高达 4 Mbps)。
  • 强大的安全性:高级安全功能,包括 TrustZone® 隔离、篡改检测和加密引擎侧的信道泄漏保护。
  • 丰富的片上资源:可扩展的内存配置,高达 1.5 MB NVM 和 256 KB RAM,提供充足的存储空间。
  • 丰富的接口:全面的外设集,包括新的全局 RTC(在系统关闭模式下可用)、14 位 ADC 和高速串行接口。内置锂电池管理。

硬件概述

XIAO nRF54L15 引脚列表
XIAO nRF54L15 正面示意图
XIAO nRF54L15 背面示意图

nRFConnect SDK 使用

nRF Connect SDK (NCS) 是 Nordic Semiconductor 提供的可扩展、统一的软件开发套件,专门为基于 Nordic nRF52、nRF53、nRF54、nRF70 和 nRF91 系列的无线设备构建低功耗无线应用而设计。

NCS 提供了丰富的现成示例应用程序、协议栈、库和硬件驱动程序生态系统,旨在简化开发过程并加快产品上市时间。其模块化和可配置的特性为开发人员提供了灵活性,既可以为内存受限的设备构建尺寸优化的软件,也可以为更高级和复杂的应用程序构建强大的功能。NCS 是托管在 GitHub 上的开源项目,为 Visual Studio Code 等集成开发环境提供出色的支持。

使用 Vscode 安装

提前了解 nRF Connect SDK 安装知识

本文档详细介绍了如何在 Windows 11 计算机上安装 nRF Connect SDK 开发环境。以下是需要安装的工具概述

  • Visual Studio Code
  • nRF Command Line Tools
  • nRF Connect for Desktop
  • Git
git --version
  • Python
python --version
  • Ninja
ninja --version
  • CMake
cmake --version
  • Zephyr SDK
west --version
  • nRF Connect SDK
  • VSCode nRF Connect 插件

如果您的计算机上已经预装了这些工具,您可以通过以下命令检查工具的版本号

1
VScode 配置开发板并构建烧录文件。

1.安装 VS Studio Code Visual Studio Code - Code Editing .Redefined

2.打开 VS Code 并在插件中心搜索 nRF Connect for VS Code Extension Pack。此插件包将自动安装 nRF Connect 所需的其他 VS Code 插件。

nRF Connect for VS Code 扩展使开发人员能够利用流行的 Visual Studio Code 集成开发环境(VS Code IDE)来开发、构建、调试和部署基于 Nordic 的 nRF Connect SDK(软件开发套件)的嵌入式应用程序。该扩展包括有用的开发工具,如编译器接口、链接器、完整的构建系统、支持 RTOS 的调试器、与 nRF Connect SDK 的无缝接口、设备树可视化编辑器和集成串行终端。 nRF Connect for VS Code 扩展包包括以下组件:

  • nRF Connect for VS Code:主扩展包含构建系统和 nRF Connect SDK 之间的接口,以及管理 nRF Connect SDK 版本和工具链的接口。
  • nRF DeviceTree:提供设备树语言支持和设备树可视化编辑器。
  • nRF Kconfig:提供 Kconfig 语言支持。
  • nRF Terminal:串行和 RTT 终端。
  • Microsoft C/C++:为 C/C++ 添加语言支持,包括 IntelliSense 功能。
  • CMake:CMake 语言支持。
  • GNU Linker Mapping Files:支持链接器映射文件。 我们可以通过扩展下载任何首选版本的 nRF Connect SDK 及其工具链。完整的 nRF Connect for VS Code 文档可在 https://docs.nordicsemi.com/bundle/nrf-connect-vscode/page/index.html 获取。
2
安装工具链

工具链是一组协同工作以构建 nRF Connect SDK 应用程序的工具,包括汇编器、编译器、链接器和 CMake 组件。 第一次打开 nRF Connect for VS Code 时,系统会提示您安装工具链。如果扩展在您的计算机上未检测到任何已安装的工具链,通常会发生这种情况。 点击安装工具链,将列出可以下载并安装到您计算机上的工具链版本列表。选择与您计划使用的 nRF Connect SDK 版本匹配的工具链版本。我们始终建议使用 nRF Connect SDK 的最新标记版本。

默认情况下,nRF Connect for VS Code 仅显示工具链的已发布选项卡(即稳定版本)。如果您正在评估新功能并希望使用预览选项卡或其他类型的选项卡(例如客户采样 -cs),请点击"显示所有工具链版本",如下所示:

note

这里的 ToolChain 是 3.0.1 或以上版本

3
安装 nRF Connect SDK

在 VS Code 的 nRF Connect 扩展中,点击管理 SDK。从管理 SDK 菜单中,我们可以安装或卸载 nRF Connect SDK 版本。由于这是我们第一次使用该扩展,界面将仅显示两个选项。

点击安装 SDK 将列出所有可以下载并本地安装的可用 nRF Connect SDK 版本。选择您项目开发所需的 nRF Connect SDK 版本。

如果您已在 VS Code 中打开了 SDK 文件夹,您将看到管理 west 工作区而不是管理 SDK 菜单选项。要解决此问题,请在 VS Code 中打开另一个窗口或文件夹。

note

这里的 nRF Connect SDK 是 3.0.1 或以上版本

tip

如果您没有看到这些选项中的任何一个,请确保您已安装最新版本的 nRF Connect for VS Code 扩展包。 需要注意的是,nRF Connect SDK 是独立于 IDE 的,这意味着您可以选择使用任何 IDE 或根本不使用。nRF Connect SDK 可通过 https://www.nordicsemi.com/Products/Development-tools/nRF-Util (nrfutil) 命令行界面 (CLI) 下载和安装 nRF Connect。但是,我们强烈建议将我们的 nRF Connect for VS Code 扩展与 VS Code 一起使用,因为它不仅集成了便捷的图形用户界面 (GUI) 和高效的命令行界面 (CLI),还包括许多将大大简化固件开发的功能。配置其他 IDE 以与 nRF Connect SDK 配合使用需要额外的手动步骤,超出了本课程的范围。

4
创建用户程序

在本练习中,我们将基于 blinky 示例编写一个简单的应用程序来控制开发板上的闪烁 LED。这同样适用于所有支持的 NordicSemiconductor 开发板(nRF54、nRF53、nRF52、nRF70 或 nRF91 系列)。目标是确保正确设置构建和烧录示例所需的所有工具。重点是学习如何使用"复制示例"模板创建应用程序、构建它并将其烧录到 Nordic 芯片开发板!

  • 在 VS Code 中,点击 nRF Connect 扩展图标。在欢迎视图中,点击创建新应用程序。
  • 在搜索栏中输入 blinky 并选择第二个 Blinky 示例(路径 zephyr/samples/basic/blinky),如下所示。

Blinky 示例将使开发板上的 LED1 持续闪烁。 我们的第一个应用程序将基于 Blinky 示例。Blinky 示例源自 nRF Connect SDK 中的 Zephyr 模块,因此您将在示例路径中看到 zephyr 名称:zephyr\samples\basic\blinky。

5
添加 XIAO nRF54L15 开发板

首先,从 GitHub 链接克隆仓库git clone https://github.com/Seeed-Studio/platform-seeedboards.git 到您首选的本地文件夹。克隆完成后,导航到 platform-seeedboards/zephyr/ 目录。记住这个 zephyr 文件夹路径

要在 VS Code 中为 nRF Connect 配置您的开发板,您可以按照以下步骤操作:

  • 打开 VS Code 并转到设置。

  • 在搜索框中输入 nRF Connect。

  • 找到 Board Roots 设置项并点击 Edit in settings.json。

  • 将下载的 XIAO nRF54L15 板文件的 zephyr 路径添加到 boardRoots 数组中。

  • 在应用程序视图中,点击应用程序名称下方的 Add Build Configuration。
  • 我们可以在 Board target 中选择 XIAO nRF54L15 的型号,在 Base configuration files 中选择默认的 prj.config 文件,最后点击 Generate and Build 来构建文件。
6
下载烧录插件

附加插件:

在 Windows 上,我们将使用 Chocolatey 包管理器来安装 OpenOCD。

1.打开 PowerShell(以管理员身份运行):

  • 在 Windows 搜索栏中,输入"PowerShell"。
  • 右键点击"Windows PowerShell"并选择"以管理员身份运行"。

2.检查 PowerShell 执行策略:

  • 输入 Get-ExecutionPolicy 并按回车。
  • 输入 Get-ExecutionPolicy -List 并按回车。

3.安装 Chocolatey:

  • 粘贴并运行以下命令:
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))

此命令会绕过当前 PowerShell 会话的执行策略并安装 Chocolatey。安装完成后,关闭并重新打开 PowerShell 窗口(仍需以管理员身份运行)。

4.安装 OpenOCD:

  • 在新的 PowerShell 窗口中(以管理员身份),输入:
choco install openocd

5.验证 OpenOCD 安装:

  • 输入 Get-Command openocd 并按回车。

  • 如果安装成功,此命令将显示 openocd.exe 的路径。

7
West Flash 烧录程序
  • 打开 nRF 终端
  • 只需输入 west flash 命令,要烧录您的设备,只需输入 west flash 命令。红色高亮的路径表示您编译的 .elf 文件的位置。您可以使用相同的路径找到对应的 .hex 文件,该文件适用于使用 J-Link 调试器进行编程。
tip

如果出现 west flash 错误,说明与 VS Code 中的 CMake 插件存在冲突,您需要移除 CMake 插件。

8
点亮 LED

当我们成功在 Seeed Studio XIAO nRF54L15 Sense 中烧录程序后,您可以看到板子上的用户指示灯不停地闪烁绿光,如果您的板子也有相同的效果,说明您已经成功了!🎊

9
深入了解 nRF Connect SDK 内部机制

要真正掌握 nRF Connect SDK,您需要从内到外了解其构建模块。跳转到这些课程来提升您的知识:

电池供电板

XIAO nRF54L15 内置电源管理芯片,允许 XIAO nRF54L15 使用电池独立供电,或通过 XIAO nRF54L15 的 USB 端口为电池充电。

如果您想为 XIAO 连接电池,我们建议您购买合格的可充电 3.7V 锂电池。焊接电池时,请注意区分正负极。

XIAO nRF54L15 BLE Advertising Power Consumption

电池连接示意图

电池使用说明:

  1. 请使用符合规格的合格电池。
  2. 使用电池时,XIAO 可以通过数据线连接到您的计算机设备,请放心,XIAO 内置电路保护芯片,是安全的。
  3. XIAO nRF54L15 在电池供电时不会有任何 LED 亮起(除非您编写了特定程序),请不要通过 LED 的状态来判断 XIAO nRF54L15 是否工作,请通过您的程序合理判断。

同时,我们为电池充电设计了红色指示灯,通过指示灯显示来告知用户电池当前的充电状态。

caution

焊接时请注意不要短路正负极,以免烧坏电池和设备。

电池电压检测

XIAO nRF54L15 集成了电池电压检测功能,该功能以使用 TPS22916CYFPR 负载开关高效管理电池功率测量为核心。本指南将重点分析电池检测的软件实现**(特别是 main.c 代码)**,并指导您如何在 PlatformIO 环境中轻松部署和使用此功能,避免 Zephyr NCS SDK 的复杂性。

XIAO nRF54L15 BLE Advertising Power Consumption

电池检测示意图

TPS22916CYFPR 芯片的作用:

  • 它是一个智能电源开关,按需控制电池电压的通断。当需要测量电池电压时,它会打开,将电池连接到分压电路;当不需要测量时,它会关闭,断开连接。

  • 这个功能帮助我们做什么? 通过这种按需切换机制,芯片大大减少了不必要的电流消耗,有效延长电池寿命。结合后续的分压电路和 nRF54L15 的 ADC(模数转换器),XIAO nRF54L15 能够准确监控电池的剩余电量,为 IoT 设备等电池供电的低功耗应用提供重要的续航优化。

note

以下示例代码是为 PlatformIO 设计的,但它也与 nRF Connect SDK 兼容。

在 PlatformIO 中使用 XIAO nRF54L15 如果您想在 PlatformIO 中使用 XIAO nRF54L15,请参考此教程进行配置:XIAO nRF54L15 PlatformIO 配置

在 nRF Connect SDK 中使用 XIAO nRF54L15 要在 nRF Connect SDK 中使用此代码,您需要移植以下三个文件 main.cprj.confapp.overlay XIAO nRF54L15 PlatformIO 配置


核心代码

#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/regulator.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/kernel.h>


#if !DT_NODE_EXISTS(DT_PATH(zephyr_user)) || \
!DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels)
#error "No suitable devicetree overlay specified"
#endif

#define DT_SPEC_AND_COMMA(node_id, prop, idx) \
ADC_DT_SPEC_GET_BY_IDX(node_id, idx),

/* Data of ADC io-channels specified in devicetree. */
static const struct adc_dt_spec adc_channels[] = {
DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), io_channels,
DT_SPEC_AND_COMMA)};

static const struct device *const vbat_reg = DEVICE_DT_GET(DT_NODELABEL(vbat_pwr));

int main(void)
{
int err;
uint16_t buf;
int32_t val_mv;
struct adc_sequence sequence = {
.buffer = &buf,
/* buffer size in bytes, not number of samples */
.buffer_size = sizeof(buf),
};

regulator_enable(vbat_reg);
k_sleep(K_MSEC(100));

/* Configure channels individually prior to sampling. */
if (!adc_is_ready_dt(&adc_channels[7]))
{
printf("ADC controller device %s not ready\n", adc_channels[7].dev->name);
return 0;
}

err = adc_channel_setup_dt(&adc_channels[7]);
if (err < 0)
{
printf("Could not setup channel #7 (%d)\n", err);
return 0;
}

(void)adc_sequence_init_dt(&adc_channels[7], &sequence);

err = adc_read_dt(&adc_channels[7], &sequence);
if (err < 0)
{
printf("Could not read (%d)\n", err);
return 0;
}

/*
* If using differential mode, the 16 bit value
* in the ADC sample buffer should be a signed 2's
* complement value.
*/
if (adc_channels[7].channel_cfg.differential)
{
val_mv = (int32_t)((int16_t)buf);
}
else
{
val_mv = (int32_t)buf;
}
err = adc_raw_to_millivolts_dt(&adc_channels[7],
&val_mv);
/* conversion to mV may not be supported, skip if not */
if (err < 0)
{
printf(" value in mV not available\n");
}
else
{
printf("bat vol = %" PRId32 " mV\n", val_mv * 2);
}

regulator_disable(vbat_reg);
return 0;
}

所需硬件

tip

您需要下载最新版本的 J-Link 以获得 nRF54L15 型号板的支持。

所需软件

需要从网站下载 Segger 软件。

  • 步骤 1. 使用 Jlink 连接以下引脚:

pir

  • 步骤 2. 启动 J-Flash 并搜索 nRF54L15,创建新项目:

pir

  • 步骤 3. 点击 "Target" 然后选择 "Connect"。

pir

  • 步骤 4. 将 bin 或 hex 文件 拖拽到软件中。然后依次按 F4 和 F5。重新烧录完成。

pir

板载按键

XIAO nRF54L15(Sense) 配备了两个重要的物理按键,它们在设备操作和固件编程中发挥着关键作用:复位按键用户按键。了解它们的功能对于日常使用和固件更新至关重要。


复位按键

复位按键用于对设备执行硬复位操作。

  • 功能:
    • 强制重启: 按下此按键会立即中断所有当前设备操作并使其重启,类似于电源循环。
    • 解决程序卡死: 当设备运行的程序崩溃、进入无限循环或变得无响应时,按下复位按键是强制其恢复正常运行状态的最快方法。
    • 不影响固件: 复位操作不会擦除或更改已编程到设备中的固件。它只是重启当前运行的应用程序。
  • 使用场景:
    • 在开发/调试期间快速重新运行程序。
    • 当设备表现出意外行为或卡死时。

用户按键

用户按键是一个多功能的可编程输入,在您的应用程序中提供灵活的控制。

功能:

  • 可定制输入:与复位按键的固定功能不同,用户按键的操作完全由您编程的固件定义。

  • 事件触发:它可以被编程来触发特定事件、控制不同功能,或作为应用程序的通用输入。

使用场景:

  • 在自定义应用程序中激活特定功能或模式。
note

以下示例代码是为 PlatformIO 设计的,但它也与 nRF Connect SDK 兼容。

在 PlatformIO 中使用 XIAO nRF54L15 如果您想在 PlatformIO 中使用 XIAO nRF54L15,请参考此教程进行配置:XIAO nRF54L15 PlatformIO 配置

在 nRF Connect SDK 中使用 XIAO nRF54L15 要在 nRF Connect SDK 中使用此代码,您需要移植以下三个文件 main.cprj.confapp.overlay XIAO nRF54L15 PlatformIO 配置


每次按键时灯亮一次

XIAO nRF54L15 功耗代码示例 (PlatformIO)

以下示例代码是为 PlatformIO 设计的,但它也与 nRF Connect SDK 兼容。

在 PlatformIO 中使用 XIAO nRF54L15 如果您想在 PlatformIO 中使用 XIAO nRF54L15,请参考此教程进行配置:XIAO nRF54L15 PlatformIO 配置

在 nRF Connect SDK 中使用 XIAO nRF54L15 要在 nRF Connect SDK 中使用此代码,您需要移植以下三个文件 main.cprj.confapp.overlay

移植 main.c

移植 prj.conf/app.overlay,在进行项目配置时,您可能会看到以下文件:

  • prj.conf:此文件用于设置项目的 Kconfig 配置选项,例如启用特定外设或功能。

  • app.overlay:此文件用于修改设备树设置,例如更改引脚功能或调整硬件配置。

如果下面的代码示例包含这些单独的文件,您需要将它们的内容合并到您的 nRF Connect SDK 项目中。

替换位置

  • app.overlay 文件: 将其放在您的板子文件夹中。

  • prj.conf 文件: 将其放在您的项目根文件夹中。

  • main.c 文件: 将其放在您的 src 文件夹中。

蓝牙连接

本节详细介绍了设备作为蓝牙低功耗(BLE)外设主动广播时的功耗特性。该设备实现了自定义 BLE 服务,允许其他中心设备连接并与其交互。

以下图表展示了设备持续广播时的典型功耗曲线:

XIAO nRF54L15 BLE 广播功耗

设备在 BLE 广播期间的功耗

如图所示,设备表现出与每个广播事件相对应的周期性电流峰值,随后是较低电流消耗的时期。广播期间的平均功耗高于系统关闭模式,反映了广播所需的活跃无线电操作。


BLE 广播代码示例


以下是用于测试 BLE 广播期间功耗的代码:

#include <stdio.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>

// Custom 128-bit UUID for the ONOFF Service
#define BT_UUID_ONOFF_VAL BT_UUID_128_ENCODE(0x8e7f1a23, 0x4b2c, 0x11ee, 0xbe56, 0x0242ac120002)
#define BT_UUID_ONOFF BT_UUID_DECLARE_128(BT_UUID_ONOFF_VAL)

// Custom 128-bit UUID for the ONOFF Action Characteristic (Write)
#define BT_UUID_ONOFF_ACTION_VAL \
BT_UUID_128_ENCODE(0x8e7f1a24, 0x4b2c, 0x11ee, 0xbe56, 0x0242ac120002)
#define BT_UUID_ONOFF_ACTION BT_UUID_DECLARE_128(BT_UUID_ONOFF_ACTION_VAL)

// Custom 128-bit UUID for the ONOFF Read Characteristic (Read)
#define BT_UUID_ONOFF_READ_VAL \
BT_UUID_128_ENCODE(0x8e7f1a25, 0x4b2c, 0x11ee, 0xbe56, 0x0242ac120003)
#define BT_UUID_ONOFF_READ BT_UUID_DECLARE_128(BT_UUID_ONOFF_READ_VAL)

// Static flag to hold the on/off state, initialized to 0 (off)
static uint8_t onoff_flag = 0;

// Advertising data: flags and complete device name
static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), // General Discoverable, No BR/EDR
BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1), // Device Name
};

// Scan response data: include the 128-bit UUID of our custom service
static const struct bt_data sd[] = {
BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_ONOFF_VAL), // Service UUID
};

/**
* @brief GATT read callback for the ONOFF Read characteristic.
*
* This function is called when a connected central device attempts to read
* the ONOFF Read characteristic. It returns the current value of onoff_flag.
*
* @param conn Pointer to the connection object.
* @param attr Pointer to the GATT attribute being read.
* @param buf Buffer to store the read value.
* @param len Maximum length of the buffer.
* @param offset Offset from which to read the attribute value.
* @return Number of bytes read, or a negative error code.
*/
static ssize_t read_onoff_val(struct bt_conn *conn, const struct bt_gatt_attr *attr,
void *buf, uint16_t len, uint16_t offset)
{
// The user_data field of the attribute points to onoff_flag
const uint8_t *value = attr->user_data;
// Perform the GATT attribute read operation
return bt_gatt_attr_read(conn, attr, buf, len, offset, value, sizeof(*value));
}

/**
* @brief GATT write callback for the ONOFF Action characteristic.
*
* This function is called when a connected central device attempts to write
* to the ONOFF Action characteristic. It updates the onoff_flag based on
* the received value.
*
* @param conn Pointer to the connection object.
* @param attr Pointer to the GATT attribute being written.
* @param buf Buffer containing the value to be written.
* @param len Length of the value in the buffer.
* @param offset Offset at which to write the attribute value.
* @param flags Flags for the write operation.
* @return Number of bytes written, or a negative error code.
*/
static ssize_t write_onoff_val(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, uint16_t len, uint16_t offset, uint8_t flags)
{
uint8_t val;

// Ensure the length of the written data is 1 byte
if (len != 1U) {
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
}

// Ensure the write operation starts from offset 0
if (offset != 0) {
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
}

// Get the value from the buffer
val = *((uint8_t *)buf);

// Update onoff_flag based on the received value
if (val == 0x00U) {
printf("Write: 0\n");
onoff_flag = 0; // Set to off
} else if (val == 0x01U) {
printf("Write: 1\n");
onoff_flag = 1; // Set to on
} else {
// Return error if value is not 0 or 1
return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
}

return len; // Return number of bytes successfully written
}

// Define the custom GATT service and its characteristics
BT_GATT_SERVICE_DEFINE(lbs_svc,
BT_GATT_PRIMARY_SERVICE(BT_UUID_ONOFF), // Primary Service: ONOFF Service
BT_GATT_CHARACTERISTIC(BT_UUID_ONOFF_ACTION, BT_GATT_CHRC_WRITE, // Characteristic: ONOFF Action (Write)
BT_GATT_PERM_WRITE, NULL, write_onoff_val, NULL), // Permissions, callbacks
BT_GATT_CHARACTERISTIC(BT_UUID_ONOFF_READ, BT_GATT_CHRC_READ, // Characteristic: ONOFF Read (Read)
BT_GATT_PERM_READ, read_onoff_val, NULL, &onoff_flag), // Permissions, callbacks, user_data (onoff_flag)
);

/**
* @brief Callback function for successful Bluetooth connection.
*
* @param conn Pointer to the connection object.
* @param err Error code (0 if successful).
*/
static void connected(struct bt_conn *conn, uint8_t err)
{
if (err != 0U) {
printf("Connection failed (%02x, %s)\n", err, bt_hci_err_to_str(err));
return;
}

printf("Connected\n");
}

/**
* @brief Callback function for Bluetooth disconnection.
*
* @param conn Pointer to the connection object.
* @param reason Reason for disconnection.
*/
static void disconnected(struct bt_conn *conn, uint8_t reason)
{
printf("Disconnected (%02x, %s)\n", reason, bt_hci_err_to_str(reason));
}

// Define connection callbacks
BT_CONN_CB_DEFINE(conn_callbacks) = {
.connected = connected,
.disconnected = disconnected,
};

/**
* @brief Main function of the application.
*
* Initializes the Bluetooth stack, starts advertising, and enters the main loop.
* @return 0 on success, negative error code on failure.
*/
int main(void)
{
int err;

// Enable the Bluetooth stack
err = bt_enable(NULL);
if (err < 0) {
printf("Bluetooth enable failed (err %d)", err);
return err;
}

// Start BLE advertising
err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
if (err < 0) {
printf("Advertising failed to start (err %d)", err);
return err;
}

printf("Bluetooth enabled");
return 0;
}

超低功耗状态

为了实现设备的极低功耗,我们在系统关闭模式下进行了功耗测试。系统关闭模式是 Zephyr OS 提供的深度睡眠模式,其中大部分外设和 CPU 都被关闭,仅保留必要的唤醒源(如 GPIO 中断)以最小化功耗。

以下图表展示了设备进入系统关闭模式后的典型功耗曲线:

XIAO nRF54L15 系统关闭模式下的超低功耗

设备在系统关闭模式下的功耗

如图所示,进入系统关闭模式后,功耗显著降低,仅保持微安级别,这大大延长了电池寿命。当按下 sw0 按钮时,设备将从系统关闭模式唤醒并重新启动。


功耗代码示例


以下是用于测试上述系统关闭模式功耗的代码:

/*
* Copyright (c) 2019 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <inttypes.h>
#include <stdio.h>

#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/hwinfo.h>
#include <zephyr/drivers/comparator.h>
#include <zephyr/kernel.h>
#include <zephyr/pm/device.h>
#include <zephyr/sys/poweroff.h>
#include <zephyr/sys/util.h>

static const struct gpio_dt_spec sw0 = GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios);

void print_reset_cause(void)
{
uint32_t reset_cause;

hwinfo_get_reset_cause(&reset_cause);
if (reset_cause & RESET_DEBUG) {
printf("Reset by debugger.\n");
} else if (reset_cause & RESET_CLOCK) {
printf("Wakeup from System OFF by GRTC.\n");
} else {
printf("Other wake up cause 0x%08X.\n", reset_cause);
}
}

int main(void)
{
int rc;
const struct device *const cons = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));

if (!device_is_ready(cons)) {
printf("%s: device not ready.\n", cons->name);
return 0;
}

printf("\n%s system off demo\n", CONFIG_BOARD);
print_reset_cause();


/* configure sw0 as input, interrupt as level active to allow wake-up */
rc = gpio_pin_configure_dt(&sw0, GPIO_INPUT);
if (rc < 0) {
printf("Could not configure sw0 GPIO (%d)\n", rc);
return 0;
}

rc = gpio_pin_interrupt_configure_dt(&sw0, GPIO_INT_LEVEL_LOW);
if (rc < 0) {
printf("Could not configure sw0 GPIO interrupt (%d)\n", rc);
return 0;
}

printf("Entering system off; press sw0 to restart\n");


rc = pm_device_action_run(cons, PM_DEVICE_ACTION_SUSPEND);
if (rc < 0) {
printf("Could not suspend console (%d)\n", rc);
return 0;
}

hwinfo_clear_reset_cause();
sys_poweroff();

return 0;
}

资源

Seeed Studio XIAO nRF54L15

Seeed Studio XIAO nRF54L15 Sense

技术支持与产品讨论

感谢您选择我们的产品!我们在这里为您提供不同的支持,以确保您使用我们产品的体验尽可能顺畅。我们提供多种沟通渠道,以满足不同的偏好和需求。

Loading Comments...