2. GPIO输出控制LED

任务目标

本案例使用 Zephyr 的 GPIO 驱动接口,在开发板上控制一个 LED 以 1 秒周期闪烁(亮 500ms、灭 500ms)。通过该案例掌握 Zephyr 中 GPIO 的设备树绑定、引脚配置及输出电平控制方法。

硬件准备

  • 一块支持 Zephyr 的开发板(如 nRF52840DK、STM32F4 系列、ESP32 等)
  • 板载 LED 或外接 LED(串联 220Ω 限流电阻)连接至任意 GPIO 引脚

设备树配置

Zephyr 使用设备树描述硬件。开发板默认设备树中通常已定义 led0 节点(板载 LED)。若使用外接 LED,需在 app.overlay 中自定义节点:

/ {
    leds {
        compatible = "gpio-leds";
        ext_led: ext_led {
            gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
            label = "External LED";
        };
    };
};

本例使用开发板默认的 led0 别名,无需额外 overlay。若目标板无 led0,请按上述方式添加并修改代码中的节点名。

完整代码

创建 src/main.c:

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>

/* 开发板默认 LED 节点,若未定义则使用自定义节点 */
#define LED0_NODE DT_ALIAS(led0)

static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);

int main(void)
{
    int ret;

    if (!gpio_is_ready_dt(&led)) {
        return -1;
    }

    ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
    if (ret < 0) {
        return ret;
    }

    while (1) {
        /* 点亮 LED(GPIO_ACTIVE_HIGH 时输出高电平) */
        gpio_pin_set_dt(&led, 1);
        k_msleep(500);

        /* 熄灭 LED */
        gpio_pin_set_dt(&led, 0);
        k_msleep(500);
    }
    return 0;
}

构建与运行

  1. 在项目根目录的 prj.conf 中无需额外配置(GPIO 驱动默认启用)。
  2. 使用 west 构建并烧录(以 nRF52840DK 为例):
west build -b nrf52840dk_nrf52840 .
west flash

其他开发板请将 -b 参数替换为对应的 board 名称。

验证方法

  • 现象观察:烧录后,LED 应以 1Hz 频率闪烁(亮 500ms、灭 500ms)。
  • 逻辑分析仪/万用表:测量 GPIO 引脚电平,应观察到周期为 1s、占空比 50% 的方波。
  • 判定通过:LED 持续闪烁且周期误差在合理范围内(±10%),即表示 GPIO 输出控制功能正常。

常见问题

  • LED 不亮:检查 GPIO_ACTIVE_HIGH/LOW 是否与硬件接法匹配;确认设备树中 gpios 的引脚号和控制器正确。
  • 编译报错 led0 未定义:当前 board 未提供 led0 别名,需按上文添加 overlay 并改用 DT_NODELABEL(ext_led)。