树莓派Pico中断服务程序(ISR)陷入无限循环问题排查
树莓派Pico水位控制ISR无限循环问题排查与解决
核心问题分析
你的问题大概率由两个关键因素导致:
- 金属探针的接触弹跳(抖动):裸金属探针接触/离开水时,尤其是水位波动(比如暴雨),会产生多次快速电平跳变,反复触发中断,看起来像无限循环。
- 中断处理逻辑的竞态与不规范操作:ISR内的标志位修改、中断禁用范围不当,可能导致中断反复触发或逻辑冲突。
具体解决方法
一、硬件层面:解决探针抖动
给探针输入引脚添加RC滤波电路:在引脚与GND之间并联100nF电容,同时串联1kΩ电阻,平滑电平跳变,从源头减少误触发。如果条件允许,直接换用带防抖模块的水位传感器更省心。
二、软件层面:优化中断处理
1. 给ISR添加软件防抖
注意:ISR内不能用time.sleep()这类阻塞式延时,要用非阻塞的时间差判断实现防抖,示例代码如下:
from machine import Pin import utime # 全局标志位与水泵引脚 flag_l = 0 flag_h = 0 pump = Pin(2, Pin.OUT, value=0) # 防抖装饰器,过滤10ms内的重复触发 def debounce(func): last_trigger = 0 def wrapper(pin): nonlocal last_trigger now = utime.ticks_ms() if utime.ticks_diff(now, last_trigger) > 10: func(pin) last_trigger = now return wrapper @debounce def lf_interrupt(pin): global flag_l, flag_h # 临时禁用当前中断,避免处理中重复触发 pin.irq(handler=None) # 确认电平状态(下降沿=水离开低位探针) if pin.value() == 0 and flag_h == 1: pump.value(0) flag_l = 0 flag_h = 0 # 恢复中断 pin.irq(handler=lf_interrupt, trigger=Pin.IRQ_FALLING) @debounce def hr_interrupt(pin): global flag_l, flag_h pin.irq(handler=None) # 确认电平状态(上升沿=水接触高位探针) if pin.value() == 1: flag_h = 1 flag_l = 0 pump.value(1) pin.irq(handler=hr_interrupt, trigger=Pin.IRQ_RISING) # 初始化引脚 lf_pin = Pin(18, Pin.IN, Pin.PULL_DOWN) hr_pin = Pin(21, Pin.IN, Pin.PULL_DOWN) lf_pin.irq(handler=lf_interrupt, trigger=Pin.IRQ_FALLING) hr_pin.irq(handler=hr_interrupt, trigger=Pin.IRQ_RISING) # 主循环(仅做兜底检查,逻辑主要靠中断) while True: utime.sleep(0.5)
2. 避免中断竞态:处理时屏蔽相关中断
如果高低位中断可能同时触发,处理其中一个时可以临时屏蔽另一个,防止标志位被同时修改:
@debounce def hr_interrupt(pin): global flag_l, flag_h # 临时屏蔽两个中断 pin.irq(handler=None) lf_pin.irq(handler=None) if pin.value() == 1: flag_h = 1 flag_l = 0 pump.value(1) # 恢复所有中断 pin.irq(handler=hr_interrupt, trigger=Pin.IRQ_RISING) lf_pin.irq(handler=lf_interrupt, trigger=Pin.IRQ_FALLING)
3. 简化ISR逻辑:复杂操作移到主循环
ISR要尽量简短,只做标志位更新和必要的硬件控制,把水泵启停的判断逻辑移到主循环,减少ISR的执行时间:
# 修改后的主循环 while True: if flag_h == 1 and flag_l == 0: pump.value(1) elif flag_h == 0: pump.value(0) utime.sleep(0.1)
三、调试技巧
- 在ISR内添加打印时,带上时间戳(
utime.ticks_ms()),看是否是短时间内多次触发同一中断,确认抖动问题。 - 用万用表或逻辑分析仪观察探针引脚的电平变化,直观看到抖动的次数和持续时间,调整防抖的时间阈值。
内容的提问来源于stack exchange,提问作者Robavh
相关产品推荐
相关产品推荐

