基于esp32,控制IO1高低电平 和读取IO0按键的c程序

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"

// 引脚定义
#define OUTPUT_IO     GPIO_NUM_1    // 输出控制引脚
#define BUTTON_IO     GPIO_NUM_0    // 按键输入引脚

// 按键检测参数
#define DEBOUNCE_TIME_MS  50       // 消抖时间(毫秒)
#define SHORT_PRESS_MS    500       // 短按时间阈值
#define LONG_PRESS_MS     2000      // 长按时间阈值

// 全局变量
volatile uint32_t button_press_time = 0;
volatile bool button_active = false;
volatile bool button_long_press = false;

// 初始化GPIO
void init_gpio() {
    // 配置输出引脚
    gpio_config_t io_conf = {
        .pin_bit_mask = (1ULL << OUTPUT_IO),
        .mode = GPIO_MODE_OUTPUT,
        .pull_up_en = GPIO_PULLUP_DISABLE,
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .intr_type = GPIO_INTR_DISABLE
    };
    gpio_config(&io_conf);
    
    // 配置输入引脚(按键)
    io_conf.pin_bit_mask = (1ULL << BUTTON_IO);
    io_conf.mode = GPIO_MODE_INPUT;
    io_conf.pull_up_en = GPIO_PULLUP_ENABLE;  // 使用内部上拉
    io_conf.intr_type = GPIO_INTR_NEGEDGE;    // 下降沿触发中断
    gpio_config(&io_conf);
    
    // 安装GPIO中断服务
    gpio_install_isr_service(0);
    // 添加中断处理函数
    gpio_isr_handler_add(BUTTON_IO, button_isr_handler, NULL);
}

// 按键中断服务程序
void IRAM_ATTR button_isr_handler(void* arg) {
    uint32_t current_time = xTaskGetTickCount() * portTICK_PERIOD_MS;
    
    if (!gpio_get_level(BUTTON_IO)) {
        // 按键按下(下降沿)
        button_press_time = current_time;
        button_active = true;
        button_long_press = false;
    } else if (button_active) {
        // 按键释放(上升沿)且之前是按下状态
        uint32_t press_duration = current_time - button_press_time;
        
        if (press_duration >= DEBOUNCE_TIME_MS) {
            if (press_duration >= LONG_PRESS_MS) {
                button_long_press = true;
                printf("长按 detected\n");
            } else if (press_duration >= DEBOUNCE_TIME_MS) {
                printf("短按 detected\n");
            }
        }
        button_active = false;
    }
}

// 主任务
void app_main() {
    // 初始化GPIO
    init_gpio();
    
    // 初始状态: IO1输出低电平
    gpio_set_level(OUTPUT_IO, 0);
    
    while (1) {
        // 示例: 每5秒切换一次IO1状态
        printf("Setting IO1 HIGH\n");
        gpio_set_level(OUTPUT_IO, 1);
        vTaskDelay(5000 / portTICK_PERIOD_MS);
        
        printf("Setting IO1 LOW\n");
        gpio_set_level(OUTPUT_IO, 0);
        vTaskDelay(5000 / portTICK_PERIOD_MS);
        
        // 这里可以根据按键状态做其他操作
        // 例如:
        // if (button_long_press) {
        //     // 处理长按事件
        //     button_long_press = false;
        // }
    }
}

程序说明
1. 引脚定义:
◦ OUTPUT_IO (GPIO1): 用于输出高低电平
◦ BUTTON_IO (GPIO0): 用于连接按键(注意: GPIO0在ESP32上通常有特殊用途,如启动模式选择)
2. 按键检测功能:
◦ 使用中断方式检测按键
◦ 实现了消抖处理(50ms)
◦ 区分短按(500ms以内)和长按(2000ms以上)
◦ 按键释放时判断是短按还是长按
3. 输出控制:
◦ 示例中每5秒切换一次IO1的电平状态
◦ 实际应用中可以根据按键状态来控制输出
注意事项
1. GPIO0在ESP32开发板上通常连接有自动下载电路,用作按键输入可能会有问题。如果遇到问题,可以尝试改用其他GPIO(如GPIO2、GPIO4等)。
2. 按键需要连接在GPIO0和地之间,内部已启用上拉电阻。
3. 中断处理函数标记为IRAM_ATTR确保它被放置在IRAM中。
4. 实际应用中,可以根据需要调整短按和长按的时间阈值。
5. 如果需要更复杂的按键处理(如双击、多击等),可以考虑使用状态机或专门的按键库。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值