中断就像它的声音一样,是一个 “中断 “程序正常流程的事件。在一般的情况下,我们处理的是外部硬件中断,这意味着在程序继续运行之前,需要处理一个信号或状态变化。
中断的基本实现方法
为了实现中断,我们需要将一个引脚定义为 “中断输入”, 定义该点上的状态变化被认为是一个中断。
1 2 3 4
| import machie
int = machine.Pin(1, machine.Pin.IN, machine.Pin.PULL_DOWN)
|
同时,还需要创建了一个 “中断处理程序 “函数,我们希望在检测到中断时运行该函数。
1 2 3
| def interrupt_handler(pin): print("%d号引脚触发中断!" % pin)
|
然后将 “中断处理程序 “与 “中断输入 “配对。
1
| int.irq(trigger=machine.Pin.IRQ_RISING, handler=interrupt_handler)
|
现在,每当中断输入条件发生时,Pico 将停止它正在做的任何事情,并执行 “中断处理程序”。然后它将恢复到原来的位置。
完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import machie import utime
high = machine.Pin(0, machine.Pin.OUT) high.value(1) int_pin = machine.Pin(1, machine.Pin.IN, machine.Pin.PULL_DOWN)
def interrupt_handler(pin): print("%s触发中断!" % str(pin))
int_pin.irq(trigger=machine.Pin.IRQ_RISING, handler=interrupt_handler) while True: print("Running!") utime.sleep(1)
|
运行这个脚本
在0
号引脚和1
号引脚间连接一个开关,当按下这个开关时,即打印
1
| Pin(1, mode=IN, pull=PULL_DOWN)触发中断!
|
细心的朋友应该发现了,按钮按一次,中断会触发多次,我们可以通过判断中断与上一次中断的时间来决定是否执行中断函数,这部分非常简单,大家自己改改就行了。
优雅的实现中断
上面基本方法虽然简单,但略显发杂,代码比较乱,下面让我们使用Python装饰器封装一个中断实现。
如果你对装饰器不了解,你仍然可以使用该方法,但如果想自己DIY的话,可以看看我的这篇文章
创建interrupt.py
,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import machine import utime
class Interrupt: def __init__(self, pin, pull=machine.Pin.PULL_DOWN, trigger=machine.Pin.IRQ_RISING, time=1000, before=None, final=None): self.pin = machine.Pin(pin, machine.Pin.IN, pull) self.trigger = trigger self.time = time self.last_time = utime.ticks_ms() self.before = before self.final = final
def __call__(self, func): def wrapped_func(*args, **kwargs): if self.before is not None: self.before() this_time = utime.ticks_ms() res = None if this_time - self.last_time > self.time: self.pin.irq(handler=None) res = func(*args, **kwargs) self.pin.irq(handler=wrapped_func) self.last_time = this_time if self.final is not None: self.final() return res self.pin.irq(trigger=self.trigger, handler=wrapped_func) return wrapped_func
|
相信了解Python装饰器的朋友应该能看懂这个类的工作原理
下面我再写一个中断的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import machine import utime
from interrupt import Interrupt
high = machine.Pin(0, machine.Pin.OUT) high.value(1)
@Interrupt(1, time=300) def handler(pin): print("Interrupt Detected!") print("%s触发中断!" % str(pin))
while True: print("Running!") utime.sleep(1)
|
是不是清爽很多?
@Interrupt()
可以有6个参数,分别为: