Feedback
Feedback

If you are having issues with the exercises, please create a ticket on DevZone: devzone.nordicsemi.com
Drag & Drop Files, Choose Files to Upload 您最多可以上传 2 个文件。
  • 简体中文
    Eng
    简体中文
  • 练习 1 – 通过按钮控制 LED(基于轮询)

    通过按钮控制 LED(基于轮询)

    在本练习中,我们将修改 blinky 示例,使得 LED1 仅在按下按钮 1 时点亮,如下图所示。B

    注意

    在 nRF54 DK 上,开发板的 LED 和按钮标有以 0 开头的 PCB 标签(PCB 丝印)(LED0-LED3 和 BUTTON0-BUTTON3)。在上一代开发套件中,索引从 1 开始(LED1-LED4)。因此,在 nRF54L15 DK 上,我们将使用 LED0 和 BUTTON0。

    为此,我们将使用 GPIO 通用 API 中讨论的轮询方法。这是通过不断轮询 CPU 以检查按钮是否被按下,然后相应地更新 LED 来实现的。在接下来的练习 2 中,我们将学习如何使用 GPIO 中断,这比轮询更省电。

    如果我们回顾 nRF52833 DK 的原理图,有四个按钮连接到与 LED 相同的 GPIO 外设 GPIO0(节点标签:gpio0)。这可以在 GPIO 引脚映射中看到,例如,请注意按钮 1 连接到 P0.11。P0 中的 0 象征着它是 &gpio0。

    nRF52833 DK 按钮位置
    nRF52833 DK 按钮引脚映射

    这就是为什么 LED 和按钮都需要相同的驱动程序。这从 DK 的设备树文件 nrf52833dk_nrf52833.dts 中也可以明显看出。

    	buttons {
    		compatible = "gpio-keys";
    		button0: button_0 { 
    			gpios = <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    			label = "Push button switch 0";
    		};
    		button1: button_1 {
    			gpios = <&gpio0 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    			label = "Push button switch 1";
    		};
    /* ... */
    		};
    	};
    
    /* ... */
    	/* These aliases are provided for compatibility with samples */
    	aliases {
    /* ... */
    		sw0 = &button0;
    		sw1 = &button1;
    		sw2 = &button2;
    		sw3 = &button3;
    		bootloader-led0 = &led0;
    	};
    };
    Devicetree

    nRF52833 DK 上的按钮 1 被赋予节点名称 button_0,它具有别名 (sw0) 和节点标签 (button0),并连接到 &gpio0、pin 11。请记住,设备树文件中的索引始终从 0 开始,这就是为什么开发板上的按钮 1 被称为 button0。

    gpios = <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    Devicetree

    注意

    如果按钮连接到与 LED 不同的 GPIO 端口(例如 gpio1),则需要一个新的设备指针。例如,nRF54L15 DK 的 LED 位于 gpio1 和 gpio2 上,而按钮连接到 gpio0 和 gpio1。

    练习步骤

    1. 克隆 nRF Connect SDK Fundamentals GitHub 仓库。请注意,该仓库包含练习代码库和解决方案。请务必选择与您选择的 nRF Connect SDK 版本相对应的分支:

    • main (默认分支):适用于 nRF Connect SDK v3.2.0 版本

    这里我们有两个选择。我们可以使用 VS Code 中的图形用户界面(在步骤 1.1 中描述)或命令行(在步骤 1.2 中描述)来克隆 GitHub 仓库。选择 1.1 或 1.2 即可。

    1.1 复制仓库链接并使用 VS Code 的命令面板(Command Palette)克隆仓库。

    转到“查看” -> “命令面板” -> 输入 Git Clone 并粘贴仓库链接。将仓库保存在靠近根目录的位置。

    1.2 或者,在靠近根目录的地方创建一个文件夹,并通过在 nRF Connect 终端中运行以下命令来克隆仓库(在 VS Code 中,通过查看 → 终端(或 Ctrl+J)打开终端,然后单击启动配置文件…下拉菜单(+ 旁边的箭头)并选择 nRF Connect)。

    git clone https://github.com/NordicDeveloperAcademy/ncs-fund.git
    Bash

    发出命令后,课程代码库将被克隆到当前工作目录中。

    注意

    确保仓库路径中没有空格或其他特殊字符。

    2. 在 VS Code 中打开本练习的练习代码库。

    2.1 在 nRF Connect 扩展的欢迎视图中,单击打开现有应用程序。

    选择本练习的基础代码(位于您所使用的版本的 l2/l2_e1 中),然后单击选择文件夹。

    2.2 从 VS Code 的资源管理器中打开 main.c,如下面的屏幕截图所示:

    3. 在硬件上初始化按钮。

    3.1 通过别名 sw0 获取按钮 1 的节点标识符。

    回想一下设备树章节,DK 设备树中的 /aliases 节点为节点 &button0 定义了别名 sw0。下面这行代码使用宏调用 DT_ALIAS() 通过别名访问该节点的节点标识符。

    在 main.c 中,搜索 STEP 3.1 并添加(复制并粘贴)以下行:

    #define SW0_NODE	DT_ALIAS(sw0) 
    C

    这样做是为了确保跨不同硬件的兼容性。

    3.2 通过 gpio_dt_spec 获取设备指针、引脚号和引脚配置标志。

    GPIO API 有一个名为 gpio_dt_spec 的结构体,它封装了所有这些信息,并且可以使用 GPIO_DT_SPEC_GET() 来检索。

    在 main.c 中,搜索 STEP 3.2 并添加(复制并粘贴)以下行:

    	static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET(SW0_NODE, gpios);
    C

    这行代码使用宏 GPIO_DT_SPEC_GET() 来填充 gpio_dt_spec 变量的成员:

    • 设备指针: const struct device *port
    • 引脚号: gpio_pin_t pin
    • 引脚标志: gpio_dt_flags_t dt_flags

    4. 在使用设备之前,通过调用 device_is_ready() 来验证设备是否已准备就绪,这一点非常重要。

    device_is_ready()

    在 main.c 中,搜索 STEP 4 并添加(复制并粘贴)以下行:

    if (!device_is_ready(button.port)) {
    	return -1;
    }
    C

    5. 将连接到按钮的引脚配置为输入引脚,并设置其硬件规格。

    在 main() 内部,搜索 STEP 5 并添加以下行:

    ret = gpio_pin_configure_dt(&button, GPIO_INPUT);
    if (ret < 0) {
    	return -1;
    }
    C

    6. 在本练习的主循环中,我们将无限期地轮询 CPU 以读取按钮的状态(按下 = 1,未按下 = 0),并根据按钮的状态更新 LED。

    6.1 读取按钮的状态并将其存储。

    使用 gpio_pin_get_dt() 读取 button.pin 的当前状态,并将其保存在变量 val 中。

    搜索 STEP 6.1 并在无限循环内添加以下代码:

    bool val = gpio_pin_get_dt(&button);
    C

    6.2 根据按钮状态更新 LED

    使用 gpio_pin_set_dt() 更新 LED,以反映上一步中保存在变量 val 中的按钮当前状态。

    搜索 STEP 6.2 并在无限循环内添加以下代码:

     gpio_pin_set_dt(&led,val);
    C

    7. 将休眠时间从 1000 ms 更改为 100 ms。100 ms 是让主线程休眠并仍能在按下按钮时及时响应的合适时间。

    8. 添加构建配置,就像我们在第 1 课练习 2 中所做的那样。

    9. 构建练习并将其烧录到开发板上,就像我们在上一课中所做的那样。观察当按下按钮 1 时,LED1 点亮。(请记住,在 nRF54L15 DK 上,那将是 button0 和 LED0)

    本练习的解决方案可以在 GitHub 仓库中找到,位于您所使用的版本的 l2/l2_e1_sol 中。

    Switch language?

    Progress is tracked separately for each language. Switching will continue from your progress in that language or start fresh if you haven't begun.

    Your current progress is saved, and you can switch back anytime.

    Register an account
    Already have an account? Log in
    (All fields are required unless specified optional)

    • 8 or more characters
    • Upper and lower case letters
    • At least one number or special character

    Forgot your password?
    Enter the email associated with your account, and we will send you a link to reset your password.