Skip to main content

XIAO nRF52840(sense) 与 Zephyr(RTOS)

什么是 RTOS​

当今嵌入式系统最重要的组件之一是 RTOS,也称为实时操作系统,它负责从任务调度到执行应用程序的所有工作。

RTOS 旨在提供可预测的执行模式。当处理必须满足系统的时间限制时,就会使用 RTOS。因此,与 GPOS(通用操作系统)相比,RTOS 通常重量轻、体积小,通常只提供在特定硬件上运行特定类型应用程序所需的功能。在某些情况下,开发人员可以修改现有的 RTOS,将其缩减为仅提供特定应用程序所需的功能,和/或定制其功能或性能特征。

什么是 Zephyr​

Zephyr 操作系统基于一个小占用空间的内核,专为在资源受限和嵌入式系统上使用而设计:从简单的嵌入式环境传感器和 LED 可穿戴设备到复杂的嵌入式控制器、智能手表和 IoT 无线应用程序。

特性​

Zephyr 提供大量且不断增长的功能,包括:

广泛的内核服务套件​

Zephyr 为开发提供了许多熟悉的服务:

  • 多线程服务,支持协作式、基于优先级的、非抢占式和抢占式线程,可选循环时间片。包括 POSIX pthreads 兼容 API 支持。
  • 中断服务,用于中断处理程序的编译时注册。
  • 内存分配服务,用于固定大小或可变大小内存块的动态分配和释放。
  • 线程间同步服务,包括二进制信号量、计数信号量和互斥信号量。
  • 线程间数据传递服务,包括基本消息队列、增强消息队列和字节流。
  • 电源管理服务,如总体的、应用程序或策略定义的系统电源管理和细粒度的、驱动程序定义的设备电源管理。

多种调度算法​

Zephyr 提供了一套全面的线程调度选择:

  • 协作式和抢占式调度
  • 最早截止时间优先 (EDF)
  • Meta IRQ 调度,实现"中断下半部"或"tasklet"行为
  • 时间片:在相同优先级的可抢占线程之间启用时间片
  • 多种队列策略:
    • 简单链表就绪队列
    • 红黑树就绪队列
    • 传统多队列就绪队列

蓝牙低功耗 5.0 支持​

蓝牙 5.0 兼容 (ESR10) 和蓝牙低功耗控制器支持 (LE 链路层)。包括蓝牙网格和蓝牙认证就绪的蓝牙控制器。

  • 通用访问配置文件 (GAP),支持所有可能的 LE 角色
  • 通用属性配置文件 (GATT)
  • 配对支持,包括蓝牙 4.2 的安全连接功能
  • 清晰的 HCI 驱动程序抽象
  • 原始 HCI 接口,可将 Zephyr 作为控制器而不是完整的主机堆栈运行
  • 已通过多个流行控制器验证
  • 高度可配置

网格支持:

  • 中继、朋友节点、低功耗节点 (LPN) 和 GATT 代理功能
  • 支持两种配置承载 (PB-ADV 和 PB-GATT)
  • 高度可配置,适用于至少具有 16k RAM 的设备

参考:Zephyr 项目

入门指南​

一旦设置好 Zephyr 工具链并下载了相关的 SDK,您就可以开始应用程序开发了。

对于 Xiao nrf52840,可以参考板卡描述文件获取更多设置信息。

要对 Xiao nrf52840 进行编程,可以按照以下步骤操作:

  1. 构建一个示例或您的应用程序
  2. 插入 Xiao nrf52840
  3. 双击 RST 按钮,将设备设置为 uf2 引导加载程序模式
  4. 运行命令 west flash -r uf2 来刷写设备

最简单的示例是在板卡上运行"Hello World"示例。切换到 Zephyr 安装目录后,运行以下命令。

west build -p always -b xiao_ble samples/hello_world

如果您使用的是 Xiao nRF52840 Sense 开发板,您可以通过使用 xiao_ble/nrf52840/sense 来替代 xiao_ble 为其板定义文件进行构建,如下所示(在此示例中没有区别):

west build -p always -b xiao_ble/nrf52840/sense samples/hello_world

完成此操作后进入 uf2 引导加载程序模式并输入:

west flash -r uf2

找到您设备的端口,在 Ubuntu 的情况下可以通过以下命令完成:ls /dev/tty* 并确认插入 USB 后出现的设备。

在我的示例中,我看到 /dev/ttyACM0:

使用 screen 您可以连接并监控串行响应:

screen /dev/ttyACM0 115200

你应该看到类似以下的响应:

*** Booting Zephyr OS build v3.6.0-5403-gd9e2b0c70763 ***
Hello World! xiao_ble/nrf52840

为了协助在 Xiao 及其扩展板上使用 Zephyr 的过程,我们构建了一个仓库,其中包含了此处使用的多个覆盖层和配置。本 wiki 文章中包含的命令假设该仓库位于相对于 zephyr 根目录的 ../applications/xiao-zephyr-examples 路径。可以通过更新下面的命令来提供替代路径。

git clone https://github.com/Cosmic-Bee/xiao-zephyr-examples

硬件准备​

Seeed Studio XIAO nrf52840 SenseSeeed Studio 扩展板

开发者知识​

XIAO 扩展板​

为了在 Seeed Studio XIAO nrf52840 上使用 Grove 模块,我们将使用 Seeed Studio XIAO 扩展底板 并将 XIAO nrf52840 连接到上面。

之后,板上的 Grove 连接器就可以用来连接 Grove 模块了

引脚定义​

当将 Grove 模块连接到 Seeed Studio XIAO 的 Grove 扩展板上的 Grove 连接器时,您需要按照下图使用相应的内部引脚编号。

主要功能​

  • 板载 LED
  • 板载 IMU(Sense)
  • 板载麦克风(Sense)
  • 蓝牙
  • TFLite

板载 LED​

在这个示例中,我们将使用闪烁示例来让板载 LED 闪烁。

cd ~/zephyrproject/zephyr
west build -p always -b xiao_ble samples/basic/blinky

双击RESET按钮,然后闪烁:

west flash -r uf2

您将看到板载红色 LED 开关切换,产生闪烁效果。

让我们深入了解这个示例,看看它为什么有效。

相关的示例代码引用了 led0:

#define LED0_NODE DT_ALIAS(led0)
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);

这在 Xiao nRF52840 设备树代码中通过别名定义:

 aliases {
led0 = &led0;
};

leds {
compatible = "gpio-leds";
led0: led_0 {
gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
label = "Red LED";
};
...
}

它对应板子上的第26号引脚。

对于带有Xiao分线板的引脚,你不需要直接使用&gpio0引脚映射,因为板文件提供了一个Xiao连接器来简化接口。

例如,如果我要引用D0,我可以将其引用为&gpio 2或&xiao_d 0。

/ {
xiao_d: connector {
compatible = "seeed,xiao-gpio";
#gpio-cells = <2>;
gpio-map-mask = <0xffffffff 0xffffffc0>;
gpio-map-pass-thru = <0 0x3f>;
gpio-map
= <0 0 &gpio0 2 0> /* D0 */
, <1 0 &gpio0 3 0> /* D1 */
, <2 0 &gpio0 28 0> /* D2 */
, <3 0 &gpio0 29 0> /* D3 */
, <4 0 &gpio0 4 0> /* D4 */
, <5 0 &gpio0 5 0> /* D5 */
, <6 0 &gpio1 11 0> /* D6 */
, <7 0 &gpio1 12 0> /* D7 */
, <8 0 &gpio1 13 0> /* D8 */
, <9 0 &gpio1 14 0> /* D9 */
, <10 0 &gpio1 15 0> /* D10 */
;
};
};

板载 IMU(传感)​

Xiao nrf52840 的主要特性之一是其内置的 IMU 传感器。利用这些数据,可以训练机器学习模型、检测手势、检测板子的运动等。

为了测试这个功能,我们将使用一个内置示例,该示例利用了 IMU,然后查看相关代码以了解其工作原理。

cd ~/zephyrproject/zephyr
west build -p -b xiao_ble/nrf52840/sense samples/sensor/lsm6dsl

双击 RESET 按钮,然后闪烁:

west flash -r uf2

接下来你需要连接以查看输出:

screen /dev/ttyACM0 115200

这应该显示类似以下内容:

3LSM6DSL sensor samples:

accel x:1.330409 ms/2 y:-1.705484 ms/2 z:9.957133 ms/2
gyro x:0.049632 dps y:-0.070860 dps z:-0.006184 dps
loop:46 trig_cnt:9677

3LSM6DSL sensor samples:

accel x:1.314257 ms/2 y:-1.734198 ms/2 z:9.902696 ms/2
gyro x:-0.220216 dps y:0.032833 dps z:-0.000458 dps
loop:47 trig_cnt:9892

3LSM6DSL sensor samples:

accel x:1.414158 ms/2 y:-1.476371 ms/2 z:9.835697 ms/2
gyro x:0.035430 dps y:-0.132252 dps z:-0.007788 dps
loop:48 trig_cnt:10107

为什么它能工作?我们可以通过 Zephyr 的 github 仓库查看示例代码。

 const struct device *const lsm6dsl_dev = DEVICE_DT_GET_ONE(st_lsm6dsl);

示例逻辑为目标板找到关联的 st_lsm6dsl 设备树对象。我们可以查看 Xiao nrf52840 sense 设备树来进一步了解其配置方式:

 lsm6ds3tr-c-en {
compatible = "regulator-fixed-sync", "regulator-fixed";
enable-gpios = <&gpio1 8 (NRF_GPIO_DRIVE_S0H1 | GPIO_ACTIVE_HIGH)>;
regulator-name = "LSM6DS3TR_C_EN";
regulator-boot-on;
startup-delay-us = <3000>;
};
&i2c0 {
compatible = "nordic,nrf-twim";
/* Cannot be used together with spi0. */
status = "okay";
pinctrl-0 = <&i2c0_default>;
pinctrl-1 = <&i2c0_sleep>;
pinctrl-names = "default", "sleep";
clock-frequency = <I2C_BITRATE_FAST>;

lsm6ds3tr_c: lsm6ds3tr-c@6a {
compatible = "st,lsm6dsl";
reg = <0x6a>;
irq-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};

一个 GPIO 被用来启用引脚电源。您可以从定义文件中看到它使用的是 GPIO1 8。我在下面突出显示了 Xiao nRF52840 原理图 的相关部分:

从这个原理图高亮部分您可以看到 GPIO1 8 是 IMU 的使能引脚。此外,GPIO0 11 是中断引脚。因此这在上述设备树片段中得到了体现。

板载麦克风 (Sense)​

Xiao nrf52840 的主要特性之一是其内置麦克风。像其 IMU 一样,它通过使用允许许多机器学习应用。

为了测试这个功能,我们将使用一个内置示例,该示例利用麦克风,然后研究相关代码以了解它为什么工作。

cd ~/zephyrproject/zephyr
west build -p -b xiao_ble/nrf52840/sense samples/drivers/audio/dmic

双击 RESET 按钮,然后闪烁:

west flash -r uf2

接下来你需要连接以查看输出:

screen /dev/ttyACM0 115200

这应该显示类似以下内容:

[00:00:00.297,088] <inf> dmic_sample: PCM output rate: 16000, channels: 1
[00:00:00.297,119] <inf> dmic_nrfx_pdm: PDM clock frequency: 1280000, actual PCM rate: 16000
[00:00:00.397,216] <inf> dmic_sample: 0 - got buffer 0x20008380 of 3200 bytes
[00:00:00.497,222] <inf> dmic_sample: 1 - got buffer 0x20006a80 of 3200 bytes
[00:00:00.597,229] <inf> dmic_sample: 2 - got buffer 0x20005180 of 3200 bytes
[00:00:00.697,235] <inf> dmic_sample: 3 - got buffer 0x20008380 of 3200 bytes
[00:00:00.797,241] <inf> dmic_sample: 4 - got buffer 0x20006a80 of 3200 bytes
[00:00:00.897,247] <inf> dmic_sample: 5 - got buffer 0x20005180 of 3200 bytes
[00:00:00.997,222] <inf> dmic_sample: 6 - got buffer 0x20008380 of 3200 bytes
[00:00:01.097,229] <inf> dmic_sample: 7 - got buffer 0x20006a80 of 3200 bytes
[00:00:01.097,259] <inf> dmic_sample: PCM output rate: 16000, channels: 2
[00:00:01.097,259] <inf> dmic_nrfx_pdm: PDM clock frequency: 1280000, actual PCM rate: 16000
[00:00:01.197,387] <inf> dmic_sample: 0 - got buffer 0x20008380 of 6400 bytes
[00:00:01.297,393] <inf> dmic_sample: 1 - got buffer 0x20005180 of 6400 bytes
[00:00:01.397,399] <inf> dmic_sample: 2 - got buffer 0x20006a80 of 6400 bytes
[00:00:01.497,375] <inf> dmic_sample: 3 - got buffer 0x20008380 of 6400 bytes
[00:00:01.597,381] <inf> dmic_sample: 4 - got buffer 0x20005180 of 6400 bytes
[00:00:01.697,387] <inf> dmic_sample: 5 - got buffer 0x20006a80 of 6400 bytes
[00:00:01.797,393] <inf> dmic_sample: 6 - got buffer 0x20008380 of 6400 bytes
[00:00:01.897,399] <inf> dmic_sample: 7 - got buffer 0x20005180 of 6400 bytes
[00:00:01.897,399] <inf> dmic_sample: Exiting

为什么它能工作?我们可以通过 github 仓库查看 Zephyr 的示例代码。

这个示例演示了以下内容:

这是一个非常简单的应用程序,旨在展示如何使用 :ref:Audio DMIC API,同时也是开发实现此 API 的驱动程序的辅助工具。它使用不同的配置(使用一个通道和两个通道)执行两次 PDM 传输,但不会以任何方式处理接收到的音频数据。

const struct device *const dmic_dev = DEVICE_DT_GET(DT_NODELABEL(dmic_dev));

示例逻辑为目标板找到关联的 dmic_dev 设备树对象。我们可以查看 Xiao nrf52840 sense 设备树来进一步了解其配置方式:

/ {
msm261d3526hicpm-c-en {
compatible = "regulator-fixed";
enable-gpios = <&gpio1 10 (NRF_GPIO_DRIVE_S0H1 | GPIO_ACTIVE_HIGH)>;
regulator-name = "MSM261D3526HICPM-C-EN";
};
}

&pdm0 {
pinctrl-0 = <&pdm0_default>;
pinctrl-1 = <&pdm0_sleep>;
pinctrl-names = "default", "sleep";
clock-source = "PCLK32M";
};

在示例项目叠加层中,此调节器随后被启用:

/ {
msm261d3526hicpm-c-en {
regulator-boot-on;
};
};

dmic_dev: &pdm0 {
status = "okay";
};

一个 GPIO 被用来启用引脚电源。我在下面突出显示了 Xiao nRF52840 原理图 的相关部分:

从这个原理图高亮部分可以看到 GPIO1 10 是麦克风的使能引脚。

蓝牙​

为了测试这个设置,我们可以使用 Zephyr 的现有示例:

west build -p always -b xiao_ble samples/bluetooth/observer

Flash your board:

west flash -r uf2

闪烁后等待片刻让 MCU 重置并连接到显示器:

screen /dev/ttyACM0 115200

你会看到一个可用于向开发板发送命令的控制台:

*** Booting Zephyr OS build v3.6.0-5403-gd9e2b0c70763 ***
Starting Observer Demo
Started scanning...
Exiting main thread.
Device found: EC:11:27:22:AF:D2 (public) (RSSI -74), type 0, AD data len 31
Device found: 0D:9A:BE:8D:10:FC (random) (RSSI -81), type 3, AD data len 31
Device found: D2:70:D8:F2:6F:C4 (random) (RSSI -68), type 0, AD data len 20
Device found: 72:7C:3C:87:E2:17 (random) (RSSI -77), type 0, AD data len 17
Device found: 65:65:23:B9:AD:EC (random) (RSSI -68), type 0, AD data len 17
Device found: 6D:39:26:C2:94:B5 (random) (RSSI -70), type 0, AD data len 18
CONFIG_BT=y
CONFIG_BT_OBSERVER=y

这里的配置文件为Zephyr构建启用了蓝牙相关功能。

TFLite - Hello World​

启用TFLite与Zephyr并更新:

west config manifest.project-filter -- +tflite-micro
west update

构建示例并烧录到您的开发板:

west build -p always -b xiao_ble samples/modules/tflite-micro/hello_world

Flash your board:

west flash -r uf2

闪烁后等待片刻让 MCU 重置并连接到显示器:

screen /dev/ttyACM0 115200

你将看到从控制台返回的结果:

*** Booting Zephyr OS build v3.6.0-5403-gd9e2b0c70763 ***
x_value: 1.0*2^-127, y_value: 1.0*2^-127

x_value: 1.2566366*2^-2, y_value: 1.4910772*2^-2

x_value: 1.2566366*2^-1, y_value: 1.1183078*2^-1

x_value: 1.8849551*2^-1, y_value: 1.677462*2^-1

x_value: 1.2566366*2^0, y_value: 1.9316229*2^-1

x_value: 1.5707957*2^0, y_value: 1.0420598*2^0

x_value: 1.8849551*2^0, y_value: 1.9146791*2^-1

x_value: 1.0995567*2^1, y_value: 1.6435742*2^-1

x_value: 1.2566366*2^1, y_value: 1.0674761*2^-1

x_value: 1.4137159*2^1, y_value: 1.8977352*2^-3

关于 TFLite 的其他信息超出了本指南的范围,但该示例可以作为设备功能和运行 TFLite 设置所需组件的指南。

其他组件​

Grove - 扩展板 - I2C 显示屏​

要测试此设置,我们可以使用 Zephyr 的现有示例:

west build -p always -b xiao_ble samples/drivers/display --  -DSHIELD=seeed_xiao_expansion_board
west flash -r uf2

您将看到一个显示多个黑色方块和角落中一个闪烁方块的显示屏,因为这个显示屏只支持两种颜色。

让我们深入了解这个例子,看看它为什么有效:

/ {
chosen {
zephyr,display = &ssd1306;
};
};

&xiao_i2c {
status = "okay";

ssd1306: ssd1306@3c {
compatible = "solomon,ssd1306fb";
reg = <0x3c>;
width = <128>;
height = <64>;
segment-offset = <0>;
page-offset = <0>;
display-offset = <0>;
multiplex-ratio = <63>;
segment-remap;
com-invdir;
prechargep = <0x22>;
};
};

该扩展板在 0x3C 寄存器处设置了一个 SSD1306 OLED 屏幕。它在 chosen 部分中被选择为 zephyr 显示器。

Grove - 扩展板 - 按钮​

为了测试这个设置,我们可以使用 Zephyr 的现有示例:

west build -p always -b xiao_ble samples/basic/button -- -DSHIELD=seeed_xiao_expansion_board

烧录您的开发板:

west flash -r uf2

闪烁后等待片刻让 MCU 重置并连接到显示器:

screen /dev/ttyACM0 115200

按下带有示例的按钮将触发板载LED点亮。

您将看到从控制台返回的结果:

*** Booting Zephyr OS build v3.6.0-5403-gd9e2b0c70763 ***
Set up button at gpio@50000000 pin 3
Set up LED at gpio@50000000 pin 26
Press the button
Button pressed at 839637
Button pressed at 857904
Button pressed at 883367
Button pressed at 1001258

让我们深入探讨这个例子,看看为什么它能够起作用:

/ {
aliases {
sw0 = &xiao_button0;
};

buttons {
compatible = "gpio-keys";
xiao_button0: button_0 {
gpios = <&xiao_d 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
label = "SW0";
zephyr,code = <INPUT_KEY_0>;
};
};
};

屏蔽/覆盖文件用于设置各种板载组件。使用此文件,按钮示例可以被利用,因为覆盖允许 Zephyr 配置按钮并使其可用于相关代码。

在这种情况下,Xiao nrf52840 上的 D1。它在此覆盖中被设置为充当按钮,并被别名为 sw0 名称,以允许它用于具有期望此功能的代码的示例。

Grove - 扩展板 - 蜂鸣器​

我们将使用闪烁 PWM 示例来激活我们的蜂鸣器,通过 PWM 信号控制其激活。为此,我们将使用一个自定义覆盖,该覆盖为 A3 引脚启用 PWM。

cd ~/zephyrproject/zephyr
west build -p always -b xiao_ble samples/basic/blinky_pwm -- -DDTC_OVERLAY_FILE="$(dirname $(pwd))/applications/xiao-zephyr-examples/xiao-nrf52480/xiao_expansion_buzzer.overlay"

刷写完成后,您应该开始听到一系列蜂鸣声,这些声音会随着示例程序的运行而发生变化。

让我们来看看这是如何工作的:

&pwm0 {
status = "disabled";
};

&sw_pwm {
status = "okay";
channel-gpios = <&gpio0 29 PWM_POLARITY_INVERTED>;
};

&pwm_led0 {
pwms = <&sw_pwm 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>;
};

覆盖层为引脚 29 配置 PWM 逻辑,该引脚对应 Xiao nrf52840 引脚图中的 A3 引脚。

Grove - 扩展板 - SD 卡​

我们将在这里使用文件系统示例以及 Xiao 扩展板护盾来尝试通过 SPI 与 SD 卡读卡器进行接口连接。扩展板护盾的 CS 引脚配置为关联的 &xiao_d 2 引脚,因此除了添加护盾之外,您无需为将此功能与板卡关联而做任何工作。为了进一步准备,我们使用了启用 SD 卡功能的自定义配置。

cd ~/zephyrproject/zephyr
west build -p always -b xiao_ble samples/subsys/fs/fs_sample -- -DEXTRA_CONF_FILE="$(dirname $(pwd))/applications/xiao-zephyr-examples/xiao_expansion_sd.conf" -DSHIELD=seeed_xiao_expansion_board

现在刷写并监控(首先按两次 RESET 进入 uf2 引导加载程序模式):

west flash -r uf2

你应该看到类似这样的响应:

*** Booting Zephyr OS build v3.6.0-5403-gd9e2b0c70763 ***
[00:00:00.483,367] <inf> sd: Maximum SD clock is under 25MHz, using clock of 24000000Hz
[00:00:00.483,856] <inf> main: Block count 15519744
Sector size 512
Memory Size(MB) 7578
Disk mounted.

Listing dir /SD: ...
[FILE] IMAGE1.JPG (size = 58422)
[FILE] IMAGE2.JPG (size = 97963)

在这种情况下,我的 SD 卡有两个文件。它们的名称和大小被输出到我的控制台。

让我们来看看这里涉及的相关元素:

CONFIG_SPI=y
CONFIG_DISK_DRIVER_SDMMC=y
CONFIG_GPIO=y

在相关配置中,我们启用了 SPI、SDMMC 磁盘驱动程序和 GPIO。如果没有这个配置,覆盖层将导致错误,因为示例无法找到 SD 卡。

Xiao 扩展板屏蔽层的相关部分如下所示:

&xiao_spi {
status = "okay";
cs-gpios = <&xiao_d 2 GPIO_ACTIVE_LOW>;

sdhc0: sdhc@0 {
compatible = "zephyr,sdhc-spi-slot";
reg = <0>;
status = "okay";
mmc {
compatible = "zephyr,sdmmc-disk";
status = "okay";
};
spi-max-frequency = <24000000>;
};
};

如前所述,使用 &xiao_d 2 引脚映射是为了允许选择 D2 引脚,无论使用哪种板子,只要它支持 &xiao_d 引脚设置即可。

Grove - 温湿度传感器 (SHT31)​

首先焊接引脚并将您的 Xiao nrf52840 连接到扩展板。然后使用 grove 连接线将 Grove SHT31 连接到扩展板上的其中一个 I2C 端口。

要测试此设置,我们可以使用 Zephyr 的现有示例:

west build -p always -b xiao_ble samples/sensor/sht3xd -- -DDTC_OVERLAY_FILE=$(dirname $(pwd))/applications/xiao-zephyr-examples/sht31.overlay

在您的板子进入 uf2 引导加载程序模式后对其进行刷写:

west flash -r uf2

闪烁后等待片刻让 MCU 重置并连接到显示器:

screen /dev/ttyACM0 115200

你将看到从控制台返回的结果:

*** Booting Zephyr OS build v3.6.0-5403-gd9e2b0c70763 ***
SHT3XD: 25.68 Cel ; 54.73 %RH
SHT3XD: 25.75 Cel ; 55.44 %RH
SHT3XD: 25.79 Cel ; 55.95 %RH
SHT3XD: 25.82 Cel ; 55.93 %RH
SHT3XD: 25.84 Cel ; 56.07 %RH
SHT3XD: 25.84 Cel ; 55.69 %RH

让我们深入探讨这个例子,看看为什么它能够起作用:

 &xiao_i2c {
sht3xd@44 {
compatible = "sensirion,sht3xd";
reg = <0x44>;
};
};

应用覆盖文件用于设置各种板载组件。使用此文件,SHT31 示例可以被利用,因为覆盖文件会告知示例逻辑如何为我们的板子配置传感器。

1.69英寸LCD显示模块,240×280分辨率,SPI接口​

在这个示例中,我们将使用SPI连接到一个1.69英寸、240x280分辨率的LCD。

首先使用以下图片作为指导将您的板子连接到LCD屏幕(在这种情况下我们使用的是Xiao nrf52840,但这里使用相同的引脚布局进行连接)。

1.69英寸LCD SPI显示屏XIAO nrf52840
VCC3V3
GNDGND
DIND10
CLKD8
CSD1
DCD3
RSTD0
BLD6

现在我们可以构建并烧录固件:

cd ~/zephyrproject/zephyr
west build -p always -b xiao_ble samples/drivers/display -- -DDTC_OVERLAY_FILE=$(dirname $(pwd))/applications/xiao-zephyr-examples/240x280_st7789v2.overlay -DEXTRA_CONF_FILE=$(dirname $(pwd))/applications/xiao-zephyr-examples/240x280_st7789v2.conf
west flash -r uf2

随着新固件的安装,设备现在显示与我们之前在扩展板上看到的相同演示屏幕,只是现在更新为通过 SPI 的彩色 LCD。

Xiao 圆形显示屏​

要测试此设置,我们可以使用 Zephyr 的现有示例:

west build -p always -b xiao_ble samples/drivers/display --  -DSHIELD=seeed_xiao_round_display

进入引导加载程序模式并刷写您的设备:

west flash -r uf2

您将看到一个显示多个彩色角落的显示屏,其中一个黑色角落在闪烁。

另一个示例演示了触摸屏的使用:

west build -p always -b xiao_ble samples/modules/lvgl/demos --  -DSHIELD=seeed_xiao_round_display -DCONFIG_LV_Z_DEMO_MUSIC=y

这里展示的音乐演示只是实际屏幕的一部分,但仍然演示了触摸屏的操作。如您所见,触摸播放按钮会开启音乐动画。

您可以从shield文件中看到,这是通过SPI接口与GC9A01圆形显示驱动程序以及通过i2c与CHSC6X触摸模块进行交互来实现的。

让我们深入了解一下这个示例,看看它是如何工作的:

/ {
chosen {
zephyr,display = &gc9a01_xiao_round_display;
};

lvgl_pointer {
compatible = "zephyr,lvgl-pointer-input";
input = <&chsc6x_xiao_round_display>;
};
};

/*
* xiao_serial uses pins D6 and D7 of the Xiao, which are used respectively to
* control the screen backlight and as touch controller interrupt.
*/
&xiao_serial {
status = "disabled";
};

&xiao_i2c {
clock-frequency = < I2C_BITRATE_FAST >;

chsc6x_xiao_round_display: chsc6x@2e {
status = "okay";
compatible = "chipsemi,chsc6x";
reg = <0x2e>;
irq-gpios = <&xiao_d 7 GPIO_ACTIVE_LOW>;
};
};

&xiao_spi {
status = "okay";
cs-gpios = <&xiao_d 1 GPIO_ACTIVE_LOW>, <&xiao_d 2 GPIO_ACTIVE_LOW>;

gc9a01_xiao_round_display: gc9a01@0 {
status = "okay";
compatible = "galaxycore,gc9x01x";
reg = <0>;
spi-max-frequency = <DT_FREQ_M(100)>;
cmd-data-gpios = <&xiao_d 3 GPIO_ACTIVE_HIGH>;
pixel-format = <PANEL_PIXEL_FORMAT_RGB_565>;
width = <240>;
height = <240>;
display-inversion;
};
};

这个扩展板的功能如下:

  • 选择 GC9A01 显示屏作为所选的 Zephyr 显示器
  • 设置 LVGL 指针逻辑使用 CHSC6X 模块
  • 禁用串口,因为引脚用于背光和触摸中断(如上所示通过:irq-gpios = <&xiao_d 7 GPIO_ACTIVE_LOW>;)
  • 配置圆形显示屏使用 D1、D2 和 D3 引脚进行 SPI 通信

示例逻辑 依赖于 LVGL 演示示例代码,可以进一步研究。

Xiao 圆形显示屏 - SD 卡​

我们将在这里使用文件系统示例以及 Xiao 扩展板扩展板来尝试通过 SPI 与 SD 卡读卡器进行接口通信。扩展板扩展板已为相关的 &xiao_d 2 引脚配置了 CS 引脚,因此除了添加扩展板之外,您无需为将此功能与开发板关联做任何工作。为了进一步准备,我们使用了启用 SD 卡功能的自定义配置。

cd ~/zephyrproject/zephyr
west build -p always -b xiao_ble samples/subsys/fs/fs_sample -- -DEXTRA_CONF_FILE="$(dirname $(pwd))/applications/xiao-zephyr-examples/xiao_expansion_sd.conf" -DSHIELD=seeed_xiao_round_display

现在刷写并监控(首先按两次 RESET 进入 uf2 引导加载程序模式):

west flash -r uf2

闪烁后等待片刻让 MCU 重置并连接到显示器:

screen /dev/ttyACM0 115200

您应该看到类似这样的响应:

*** Booting Zephyr OS build v3.6.0-5403-gd9e2b0c70763 ***
[00:00:00.491,485] <inf> sd: Maximum SD clock is under 25MHz, using clock of 24000000Hz
[00:00:00.491,973] <inf> main: Block count 15519744
Sector size 512
Memory Size(MB) 7578
Disk mounted.

Listing dir /SD: ...
[FILE] IMAGE1.JPG (size = 58422)
[FILE] IMAGE2.JPG (size = 97963)

如预期的那样,文件内容的显示方式与 Xiao 扩展板 SD 卡示例的输出类似。

圆形显示屏扩展板的相关部分如下所示:

&xiao_spi {
status = "okay";
cs-gpios = <&xiao_d 1 GPIO_ACTIVE_LOW>, <&xiao_d 2 GPIO_ACTIVE_LOW>;

sdhc_xiao_round_display: sdhc@1 {
compatible = "zephyr,sdhc-spi-slot";
reg = <1>;
status = "okay";
mmc {
compatible = "zephyr,sdmmc-disk";
status = "okay";
};
spi-max-frequency = <DT_FREQ_M(24)>;
};
};

D2 用于 SD CS 引脚。

✨ 贡献者项目​

技术支持与产品讨论​

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

Loading Comments...