跳到主要内容

GPIO 与中断教程

在 TuyaOpen 中配置 GPIO 引脚的数字输入、输出和中断驱动事件处理。

数字输出(LED 闪烁)

#include "tkl_gpio.h"
#include "tal_system.h"

#define LED_PIN TUYA_GPIO_NUM_18

void blink_led(void)
{
TUYA_GPIO_BASE_CFG_T cfg = {
.mode = TUYA_GPIO_PUSH_PULL,
.direct = TUYA_GPIO_OUTPUT,
.level = TUYA_GPIO_LEVEL_LOW,
};
tkl_gpio_init(LED_PIN, &cfg);

while (1) {
tkl_gpio_write(LED_PIN, TUYA_GPIO_LEVEL_HIGH);
tal_system_sleep(500);
tkl_gpio_write(LED_PIN, TUYA_GPIO_LEVEL_LOW);
tal_system_sleep(500);
}
}

中断驱动输入

static void button_isr(void *arg)
{
/* ISR 上下文 -- 保持简短 */
}

void setup_interrupt(void)
{
TUYA_GPIO_IRQ_T irq_cfg = {
.mode = TUYA_GPIO_IRQ_FALL,
.cb = button_isr,
.arg = NULL,
};
tkl_gpio_irq_init(BUTTON_PIN, &irq_cfg);
tkl_gpio_irq_enable(BUTTON_PIN);
}

中断模式

模式触发方式
TUYA_GPIO_IRQ_RISE上升沿
TUYA_GPIO_IRQ_FALL下降沿
TUYA_GPIO_IRQ_RISE_FALL双边沿
TUYA_GPIO_IRQ_LOW低电平
TUYA_GPIO_IRQ_HIGH高电平

软件消抖

机械按键会产生抖动。结合中断和定时器实现干净的检测:

static TIMER_ID s_debounce_timer;

static void debounce_cb(TIMER_ID id, void *arg)
{
TUYA_GPIO_LEVEL_E level;
tkl_gpio_read(BUTTON_PIN, &level);
if (level == TUYA_GPIO_LEVEL_LOW) {
TAL_PR_INFO("confirmed press");
}
}

static void button_isr(void *arg)
{
tkl_gpio_irq_disable(BUTTON_PIN);
tal_sw_timer_start(s_debounce_timer, 50, TAL_TIMER_ONCE);
}

:::tip TDL 按键框架 对于产品级按键处理(长按、连按、多按键支持),使用 TDL 按键框架 而非原始 GPIO 中断。 :::

GPIO 上下拉模式

模式常量用途
推挽输出TUYA_GPIO_PUSH_PULLLED、继电器
上拉输入TUYA_GPIO_PULLUP低电平有效按键
下拉输入TUYA_GPIO_PULLDOWN高电平有效传感器
开漏TUYA_GPIO_OPENDRAINI2C bit-bang
浮空TUYA_GPIO_FLOATING外部上拉电阻

平台说明

  • ESP32 经典款: GPIO 34-39 仅输入,输出模式将失败。
  • ESP32-S3: GPIO 22-25 为 NC,不要使用。
  • ESP32-C3: 仅 22 个 GPIO(0-21)。

参考资料