硬件: Renesas FPB-RA6E2 + 板載 LED 和按鍵
目標(biāo): 實現(xiàn)按鍵控制 LED 的開關(guān)狀態(tài),并通過 UART 輸出按鍵事件日志,驗證 GPIO 和串口通信功能。
1. 硬件連接與引腳定義
包含 GPIO 輸入輸出功能與 UART 數(shù)據(jù)傳輸引腳。
| 功能 | 物理引腳 (Pin) | 信號定義 | 接線說明 |
|---|---|---|---|
| 按鍵輸入 | P304 | Digital In (SW0) | 板載按鍵無需接線 |
| LED 輸出 | P207 | Digital Out (LED0) | 板載 LED 無需接線 |
| UART 發(fā)送 | P411 | UART TX | 連接到調(diào)試器 |
| UART 接收 | P410 | UART RX | 連接到調(diào)試器 |
2. 軟件環(huán)境配置
2.1 Device Tree Overlay (app.overlay)
必須明確指定 GPIO 和 UART 的物理引腳綁定,并開啟外設(shè)狀態(tài)。
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 >; /* 波特率設(shè)置 */
};
};
};2.2 Kconfig 配置 (prj.conf)
確保啟用了 GPIO 和 UART 驅(qū)動支持。
CONFIG_GPIO=y
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y
3. 代碼邏輯分析
3.1 主程序代碼(main.c)
/*
* 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;
}
3.2 核心流程
程序采用中斷驅(qū)動的方式,實現(xiàn)了按鍵事件捕獲與 LED 狀態(tài)切換,同時通過 UART 輸出日志。
- 初始化階段
- 配置 GPIO 引腳:P002 設(shè)置為輸入模式,啟用內(nèi)部上拉電阻;P003 設(shè)置為輸出模式。
- 配置 UART:波特率 115200,8N1 格式。
- 注冊按鍵中斷回調(diào)函數(shù)。
- 運行時邏輯
- 按鍵按下時觸發(fā)中斷,切換 LED 狀態(tài)(開/關(guān))。
- 在中斷回調(diào)中,記錄按鍵事件并通過 UART 輸出日志。
- 主循環(huán)保持空閑,等待中斷觸發(fā)。
3.1 關(guān)鍵 API 使用
以下是代碼中使用的關(guān)鍵 API:
- GPIO 初始化與控制
gpio_pin_configure(gpio_dev, PIN_BTN, GPIO_INPUT | GPIO_PULL_UP); gpio_pin_configure(gpio_dev, PIN_LED, GPIO_OUTPUT); - UART 數(shù)據(jù)發(fā)送
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);
4. 實驗現(xiàn)象與數(shù)據(jù)分析
4.1 串口日志 (UART Output)
終端應(yīng)顯示如下數(shù)據(jù)流:
Button pressed at 91714454
Button pressed at 228051750
Button pressed at 342154106
Button pressed at 431864898
Button pressed at 514931258
...
4.2 板載 LED 行為
- 初始狀態(tài):LED 關(guān)閉。
- 每次按鍵按下,LED 狀態(tài)翻轉(zhuǎn)(開/關(guān))。
- 視覺效果:LED 應(yīng)與按鍵動作同步,無明顯延遲。
5. 測評總結(jié)
本程序成功演示了 Renesas RA6E2 在 Zephyr RTOS 下的 GPIO 和 UART 外設(shè)控制。通過按鍵事件驅(qū)動 LED 狀態(tài)切換,并實時記錄日志到 UART,直觀地展示了嵌入式系統(tǒng)中“輸入-處理-輸出”的基本工作流程。代碼結(jié)構(gòu)清晰,適配了最新的驅(qū)動 API,適用于初學(xué)者學(xué)習(xí)和開發(fā)者快速驗證硬件功能。
-
單片機
+關(guān)注
關(guān)注
6076文章
45500瀏覽量
670698 -
瑞薩
+關(guān)注
關(guān)注
37文章
22482瀏覽量
90904 -
Zephyr
+關(guān)注
關(guān)注
0文章
59瀏覽量
6588
發(fā)布評論請先 登錄
如何搭建瑞薩RA VS code開發(fā)環(huán)境
當(dāng)RA MCU遇見Zephyr系列(3)——在Vs code中配置Zephyr集成開發(fā)環(huán)境
【瑞薩RA × Zephyr評測】LED、按鍵和UART
評論