风筝
发表于: 2025-11-14 12:12:57 | 显示全部楼层

你知道如何使用MicroPython实现外部中断和定时器中断吗?有一种方法可以确保某些代码在外部事件(例如按钮按下)或时间变化时执行。在本篇帖子中,我们将探讨外部中断和定时器中断的工作原理,并且实现通过按下按键来控制LED闪烁。

我们将使用Raspberry Pi Pico 2开发板,你也可以使用Pi Pico或者ESP32。代码可以在任何支持MicroPython的硬件上运行。我们将在面包板上搭建原型。

Raspberry-Pi-Pico-2.jpg


中断是一种确保某些代码在需要时执行的方法。大多数微控制器中有两种主要的中断类型:外部(硬件)中断和定时器中断。在本文中,你将学习这两种中断。

当发生中断时,主函数代码的执行会短暂停止,并运行一段特殊的代码。这段特殊代码短暂执行完毕后,主函数代码会恢复执行。在本示例中,我们将使用一个外部按键来触发中断。按下按键后,LED灯会开始闪烁。再次按下按键,LED灯停止闪烁。


所需的硬件

本文中需要一个轻触开关(6×6毫米)、两个1k欧姆的电阻和一个LED灯。当然,还需要一个Raspberry Pi Pico 2、Pi Pico或者ESP32开发板。完整的电路图如下所示。

pi-pico-2-button-led.png

Pi Pico 2开发板内置了上拉和下拉电阻,但我这次决定使用外置的下拉电阻。由于这里使用的是下拉电阻,我可以使用10k欧姆甚至47k欧姆的电阻。但我决定使用一个1k欧姆的电阻来匹配LED的电阻,以减少元件种类。

引脚14和15是通用 I/O (GPIO),所以我随机选择它们分别用作按键和LED灯。实际上,Pi Pico 2的几乎任何引脚都可以用于此任务。以下是实际搭建好的电路图

1741909962320.jpg


Python代码

在microPython中,外部中断的代码非常简单。只需要下面这行代码以及一个包含所需代码的函数即可。

  1. button.irq(trigger=Pin.IRQ_RISING, handler=myFunction)
复制代码

我们通过调用“.irq()”来触发该函数,并将检测边沿(上升沿、下降沿)和目标函数的名称作为参数传递。在我们的例子中,该函数名为“myFunction”,非常直观。


另一方面,定时器中断只需要两行代码,并且需要指定一个函数,也很简单:

  1. tim= Timer(-1)
  2. tim.init(mode=Timer.PERIODIC, period=200, callback=led_interrupt)
复制代码

执行“Timer(-1)”会创建一个虚拟定时器,将定时器的控制权交给软件而不是硬件。

如上所述,我们将运行一个示例,该示例读取按键(使用硬件中断)并控制LED灯闪烁。按下一次按键开始闪烁,再按下一次停止闪烁。完整的代码如下:

  1. from machine import Pin, Timer
  2. import time
  3. #import gc
  4. #gc.collect()


  5. button = Pin(14,Pin.IN,Pin.PULL_UP) #Pi Pico 2
  6. #button = Pin(26,Pin.IN,Pin.PULL_UP) #Xiao RP2350
  7. led= machine.Pin(15, machine.Pin.OUT) #Pi Pico 2
  8. ledonboard= machine.Pin(25, machine.Pin.OUT) #Pi Pico 2
  9. #led= machine.Pin(27, machine.Pin.OUT) #Xiao RP2350

  10. shouldblink= 0
  11. ledblink= 0
  12. buttontime= time.ticks_ms()
  13. flowcontroltime= time.ticks_ms()

  14. def myFunction(button):
  15.     global shouldblink
  16.     global buttontime
  17.    
  18.     if time.ticks_diff(time.ticks_ms(), buttontime) > 500: # this IF will be true every 5        00 ms
  19.         buttontime= time.ticks_ms() #update with the "current" time
  20.         
  21.         print("Interrupt has occured")
  22.         
  23.         if shouldblink == 0: # alternate between blinking and not blinking, for every button press
  24.             shouldblink = 1
  25.         else:
  26.             shouldblink = 0
  27.             
  28. def led_interrupt(timer):
  29.    
  30.     global ledblink
  31.     global shouldblink
  32.    
  33.     if shouldblink == 1:
  34.         led.value(not led.value())
  35.     else:
  36.         led.value(0)
  37.         
  38. if __name__ == "__main__":
  39.    
  40.     tim= Timer(-1)
  41.     tim.init(mode=Timer.PERIODIC, period=200, callback=led_interrupt)
  42.     button.irq(trigger=Pin.IRQ_RISING, handler=myFunction)
  43.    
  44.     while True: # Put anything here, it will not interfere or be interfered by the interrupts code
  45.    
  46.         ledonboard.value(1)
  47.         time.sleep_ms(200)
  48.         ledonboard.value(0)
  49.         time.sleep_ms(200)
复制代码

运行结果

复制代码并将其粘贴到Thonny IDE中的一个新文件中,然后将该文件保存为“main.py”。现在点击界面顶部的绿色箭头(“Run current script (F5)”)。按下面包板上的按按键,观察LED指示灯;它会开始闪烁。再次按下按键,LED指示灯将停止闪烁。

以上就是本文的全部内容,如有任何疑问,请随时在本帖下面回复。

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



手机版|

GMT+8, 2025-12-1 07:19 , Processed in 0.145615 second(s), 5 queries , Gzip On, Redis On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表