【瑞萨RA × Zephyr评测】LED、按键和UART 电子说
硬件: Renesas FPB-RA6E2 + 板载 LED 和按键
目标: 实现按键控制 LED 的开关状态,并通过 UART 输出按键事件日志,验证 GPIO 和串口通信功能。
包含 GPIO 输入输出功能与 UART 数据传输引脚。
| 功能 | 物理引脚 (Pin) | 信号定义 | 接线说明 |
|---|---|---|---|
| 按键输入 | P304 | Digital In (SW0) | 板载按键无需接线 |
| LED 输出 | P207 | Digital Out (LED0) | 板载 LED 无需接线 |
| UART 发送 | P411 | UART TX | 连接到调试器 |
| UART 接收 | P410 | UART RX | 连接到调试器 |
必须明确指定 GPIO 和 UART 的物理引脚绑定,并开启外设状态。
chosen {
zephyr,console = &uart0; /* in externalzephyrboardsrenesasfpb_ra6e2fpb_ra6e2.dts:22 */
zephyr,shell-uart = &uart0; /* in externalzephyrboardsrenesasfpb_ra6e2fpb_ra6e2.dts:23 */
};
/* GPIO 配置 */
leds {
compatible = "gpio-leds";
led1: led1 {
gpios = < &ioport2 7 GPIO_ACTIVE_HIGH >;
label = "LED1";
};
led2: led2 {
gpios = < &ioport2 6 GPIO_ACTIVE_HIGH >;
label = "LED2";
};
};
buttons {
compatible = "gpio-keys";
button0: s1 {
gpios = < &ioport3 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW) >;
label = "Push button switch 1";
zephyr,code = < INPUT_KEY_0 >;
};
};
/* UART 配置 */
&uart0 {
status = "okay";
pinctrl-0 = < &uart0_default >;
pinctrl-names = "default";
current-speed = < 115200 >; /* 波特率设置 */
};
};
};确保启用了 GPIO 和 UART 驱动支持。
CONFIG_GPIO=y
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y
/*
* Copyright (c) 2016 Open-RnD Sp. z o.o.
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*
* NOTE: If you are looking into an implementation of button events with
* debouncing, check out `input` subsystem and `samples/subsys/input/input_dump`
* example instead.
*/
#include < zephyr/kernel.h >
#include < zephyr/device.h >
#include < zephyr/drivers/gpio.h >
#include < zephyr/sys/util.h >
#include < zephyr/sys/printk.h >
#include < inttypes.h >
#define SLEEP_TIME_MS 1
/*
* Get button configuration from the devicetree sw0 alias. This is mandatory.
*/
#define SW0_NODE DT_ALIAS(sw0)
#if !DT_NODE_HAS_STATUS_OKAY(SW0_NODE)
#error "Unsupported board: sw0 devicetree alias is not defined"
#endif
static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios,
{0});
static struct gpio_callback button_cb_data;
/*
* The led0 devicetree alias is optional. If present, we'll use it
* to turn on the LED whenever the button is pressed.
*/
static struct gpio_dt_spec led = GPIO_DT_SPEC_GET_OR(DT_ALIAS(led0), gpios,
{0});
void button_pressed(const struct device *dev, struct gpio_callback *cb,
uint32_t pins)
{
printk("Button pressed at %" PRIu32 "n", k_cycle_get_32());
}
int main(void)
{
int ret;
if (!gpio_is_ready_dt(&button)) {
printk("Error: button device %s is not readyn",
button.port- >name);
return 0;
}
ret = gpio_pin_configure_dt(&button, GPIO_INPUT);
if (ret != 0) {
printk("Error %d: failed to configure %s pin %dn",
ret, button.port- >name, button.pin);
return 0;
}
ret = gpio_pin_interrupt_configure_dt(&button,
GPIO_INT_EDGE_TO_ACTIVE);
if (ret != 0) {
printk("Error %d: failed to configure interrupt on %s pin %dn",
ret, button.port- >name, button.pin);
return 0;
}
gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
gpio_add_callback(button.port, &button_cb_data);
printk("Set up button at %s pin %dn", button.port- >name, button.pin);
if (led.port && !gpio_is_ready_dt(&led)) {
printk("Error %d: LED device %s is not ready; ignoring itn",
ret, led.port- >name);
led.port = NULL;
}
if (led.port) {
ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT);
if (ret != 0) {
printk("Error %d: failed to configure LED device %s pin %dn",
ret, led.port- >name, led.pin);
led.port = NULL;
} else {
printk("Set up LED at %s pin %dn", led.port- >name, led.pin);
}
}
printk("Press the buttonn");
if (led.port) {
while (1) {
/* If we have an LED, match its state to the button's. */
int val = gpio_pin_get_dt(&button);
if (val >= 0) {
gpio_pin_set_dt(&led, val);
}
k_msleep(SLEEP_TIME_MS);
}
}
return 0;
}
程序采用中断驱动的方式,实现了按键事件捕获与 LED 状态切换,同时通过 UART 输出日志。
以下是代码中使用的关键 API:
gpio_pin_configure(gpio_dev, PIN_BTN, GPIO_INPUT | GPIO_PULL_UP);
gpio_pin_configure(gpio_dev, PIN_LED, GPIO_OUTPUT);
printk(str, args...);
gpio_pin_interrupt_configure(gpio_dev, PIN_BTN, GPIO_INT_EDGE_TO_ACTIVE);
gpio_init_callback(&btn_cb, button_pressed, BIT(PIN_BTN));
gpio_add_callback(gpio_dev, &btn_cb);
终端应显示如下数据流:
Button pressed at 91714454
Button pressed at 228051750
Button pressed at 342154106
Button pressed at 431864898
Button pressed at 514931258
...
本程序成功演示了 Renesas RA6E2 在 Zephyr RTOS 下的 GPIO 和 UART 外设控制。通过按键事件驱动 LED 状态切换,并实时记录日志到 UART,直观地展示了嵌入式系统中“输入-处理-输出”的基本工作流程。代码结构清晰,适配了最新的驱动 API,适用于初学者学习和开发者快速验证硬件功能。
全部0条评论
快来发表一下你的评论吧 !