You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RPi Pico使用blink_1Hz程序IRQ做时钟计数器异常求助

问题解决:RPi Pico PIO状态机IRQ仅触发一次的问题

问题场景

使用RPi Pico搭建时钟,参考官方blink_1hz.py程序,想用其1秒IRQ中断作为时钟计数器。原程序每秒能正确打印系统时间,但将IRQ中的lambda函数替换为自定义计数函数secs()后,程序仅打印一次而非预期的十次,全局变量t也未递增。

错误核心点

原代码中设置IRQ处理程序的语句存在问题:

sm.irq(handler = secs()) # 仅打印一次secs

问题原因

  1. 函数调用错误:写secs()时是立即执行该函数,把函数返回值(None,因为secs无return语句)传给了handler参数,而非传入函数本身作为中断回调
  2. 参数缺失:PIO状态机的IRQ处理函数需要接收一个参数(触发IRQ的状态机对象),原secs函数无参数,后续触发时会直接报错

修正后的完整代码

# Example using PIO to blink an LED and raise an IRQ at 1Hz.
import time
from machine import Pin
import rp2

@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def blink_1hz():
    # Cycles: 1 + 1 + 6 + 32 * (30 + 1) = 1000
    irq(rel(0))
    set(pins, 1)
    set(x, 31) [5]
    label("delay_high")
    nop() [29]
    jmp(x_dec, "delay_high")

    # Cycles: 1 + 7 + 32 * (30 + 1) = 1000
    set(pins, 0)
    set(x, 31) [6]
    label("delay_low")
    nop() [29]
    jmp(x_dec, "delay_low")

def secs(p):  # 添加参数接收触发IRQ的状态机对象
    global t
    t = t+1
    print("secs",t)

t = 0

# 创建状态机,输出引脚25
sm = rp2.StateMachine(0, blink_1hz, freq=2000, set_base=Pin(25))

# 修正:传入函数引用而非调用函数
sm.irq(handler=secs)

# 启动状态机
sm.active(1)
time.sleep(10)
# 停止状态机
sm.active(0)
print("main",t)

关键修正说明

  • 将sm.irq(handler = secs())改为sm.irq(handler=secs):传递函数本身作为中断回调,而非立即执行函数
  • 给secs函数添加参数p:匹配PIO状态机IRQ触发时的参数传递要求,确保回调能正常执行

内容的提问来源于stack exchange,提问作者Guus van der wal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 07:50:18