阿扎穆 2026-01-28 15:33 采纳率: 0%
浏览 4

米思齐上升沿和下降沿esp32

用esp32s3实现5号管脚输入高电平保持,15号输出1s高电平,5号从高变低,16号输出1s高电平
相当于,上升沿触发15输出1s下降沿触发16输出1s

  • 写回答

2条回答 默认 最新

  • 檀越@新空间 2026-01-28 15:34
    关注

    下午好🌅🌅🌅
    本答案参考通义千问

    在ESP32-S3中,你可以使用中断(Interrupt)来检测某个引脚的上升沿下降沿,并根据这些事件触发相应的操作。你提到的需求是:

    • 5号引脚 从低变高(上升沿),15号引脚输出1秒高电平
    • 5号引脚 从高变低(下降沿),16号引脚输出1秒高电平

    ✅ 实现目标:

    • 使用ESP32-S3的GPIO中断功能;
    • 利用定时器或延时函数实现1秒的高电平输出;
    • 在上升沿和下降沿分别触发不同的输出行为。

    🧠 解决方案

    1. 配置5号引脚为输入,并设置中断触发方式为上升沿下降沿

    pinMode(5, INPUT_PULLUP); // 设置5号引脚为输入并启用内部上拉
    attachInterrupt(digitalPinToInterrupt(5), handleEdge, CHANGE); // 监听所有变化(上升/下降)
    

    2. 定义两个变量用于记录当前状态

    volatile bool isHigh = false; // 记录5号引脚是否为高电平
    

    3. 定义中断处理函数 handleEdge,判断是上升沿还是下降沿

    void handleEdge() {
        bool currentLevel = digitalRead(5);
        if (currentLevel && !isHigh) { // 上升沿
            isHigh = true;
            digitalWrite(15, HIGH); // 触发15号输出1秒高电平
            delay(1000); // 延时1秒
            digitalWrite(15, LOW); // 恢复低电平
        } else if (!currentLevel && isHigh) { // 下降沿
            isHigh = false;
            digitalWrite(16, HIGH); // 触发16号输出1秒高电平
            delay(1000); // 延时1秒
            digitalWrite(16, LOW); // 恢复低电平
        }
    }
    

    ⚠️ 注意:在中断服务程序中使用 delay() 是不推荐的,因为会阻塞其他中断。建议使用定时器或异步方式。


    🛠️ 改进方案(推荐)

    为了避免在中断中使用 delay(),我们可以使用 硬件定时器软件定时器 来控制1秒的高电平输出。

    ✅ 推荐方法:使用 TimerOne

    步骤一:安装 TimerOne 库

    在 Arduino IDE 中,通过“库管理器”搜索并安装 TimerOne 库。

    步骤二:修改代码如下:

    #include <TimerOne.h>
    
    #define PIN_5 5
    #define PIN_15 15
    #define PIN_16 16
    
    volatile bool isHigh = false;
    
    void setup() {
        pinMode(PIN_5, INPUT_PULLUP);
        pinMode(PIN_15, OUTPUT);
        pinMode(PIN_16, OUTPUT);
    
        attachInterrupt(digitalPinToInterrupt(PIN_5), handleEdge, CHANGE);
    
        Timer1.initialize(1000000); // 1秒
        Timer1.attachInterrupt(timerCallback);
    }
    
    void loop() {
        // 主循环中不需要做任何事
    }
    
    void handleEdge() {
        bool currentLevel = digitalRead(PIN_5);
        if (currentLevel && !isHigh) { // 上升沿
            isHigh = true;
            digitalWrite(PIN_15, HIGH);
            Timer1.start();
        } else if (!currentLevel && isHigh) { // 下降沿
            isHigh = false;
            digitalWrite(PIN_16, HIGH);
            Timer1.start();
        }
    }
    
    void timerCallback() {
        digitalWrite(PIN_15, LOW);
        digitalWrite(PIN_16, LOW);
        Timer1.stop();
    }
    

    🔍 说明

    • TimerOne 是一个非常方便的库,可以用来创建精确的定时任务;
    • 使用 Timer1.start()Timer1.stop() 来控制1秒的高电平;
    • timerCallback() 是定时器到达设定时间后执行的函数,用来关闭输出。

    ✅ 总结

    重点部分总结:

    • 上升沿触发 15号引脚输出1秒高电平;
    • 下降沿触发 16号引脚输出1秒高电平;
    • 使用 中断 + 定时器 的组合方式,避免阻塞主程序;
    • 推荐使用 TimerOne 库实现更稳定的定时功能。

    如果你需要进一步优化或者有其他功能需求(如同时检测多个引脚、多任务处理等),也可以继续提问!

    评论

报告相同问题?

问题事件

  • 创建了问题 1月28日