2. GPIO输出控制LED闪烁
任务目标
在Zephyr RTOS环境下,通过设备树声明LED引脚,利用GPIO API实现LED周期性闪烁(亮100ms、灭100ms),以此掌握设备树节点配置与gpio_pin_configure/gpio_pin_toggle等核心API的调用方法。
硬件与工程配置
以nRF52840DK开发板为例(其他开发板需按实际原理图调整设备树)。板载LED0对应P0.13引脚,低电平点亮。工程文件结构如下:
app/
├── CMakeLists.txt
├── prj.conf
└── src/
└── main.c
CMakeLists.txt(最小工程定义):
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(blinky)
target_sources(app PRIVATE src/main.c)
prj.conf:本案例无需额外配置项,文件可为空或仅包含注释。
设备树LED节点
Zephyr默认设备树已包含led0节点(位于zephyr/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840-common.dtsi),其定义如下:
leds {
compatible = "gpio-leds";
led0: led_0 {
gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
label = "Green LED 0";
};
};
若使用自定义开发板,需在板级设备树中补充上述节点,并确保gpio0节点状态为okay。
关键完整代码
src/main.c:
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/devicetree.h>
/* 从设备树获取LED0节点及其GPIO配置 */
#define LED0_NODE DT_ALIAS(led0)
#if !DT_NODE_HAS_STATUS(LED0_NODE, okay)
#error "Device tree node 'led0' not found or not okay"
#endif
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
#define SLEEP_TIME_MS 100
int main(void)
{
int ret;
/* 校验GPIO控制器是否就绪 */
if (!gpio_is_ready_dt(&led)) {
return -1;
}
/* 配置LED引脚为输出模式,初始电平由设备树极性决定(此处为低电平点亮,初始为灭) */
ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_INACTIVE);
if (ret < 0) {
return ret;
}
while (1) {
/* 翻转引脚电平 */
ret = gpio_pin_toggle_dt(&led);
if (ret < 0) {
return ret;
}
k_msleep(SLEEP_TIME_MS);
}
return 0;
}
构建与运行
# 在app目录下执行
west build -b nrf52840dk_nrf52840 .
west flash
验证方法
烧录后观察开发板LED0:应呈现周期为200ms的闪烁(亮100ms、灭100ms)。若LED状态相反(常亮或常灭),检查GPIO_ACTIVE_LOW极性是否与硬件原理图匹配;若LED不亮,使用west build -t menuconfig确认CONFIG_GPIO已启用(默认开启),并检查设备树中led0别名是否存在。
常见问题
- 编译报错“led0 not found”:确认板级设备树包含
led0节点,且chosen节点中定义了zephyr,console等必要别名(部分板卡需手动添加aliases { led0 = &led0; };)。 - 引脚无输出:检查GPIO控制器在设备树中是否使能(
status = "okay"),并确认引脚号与原理图一致。