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

RP2040自定义板MicroPython中嵌套UART引脚中断实现问题求助

在RP2040 MicroPython上实现无阻塞UART中断的正确方法

针对你的场景,核心问题在于中断回调的上下文限制和核心资源抢占,以下是两种可行的解决思路:

方案一:优化核心任务分配(无需额外引脚中断)

放弃用第二个引脚中转中断的方案,直接利用_thread模块将UART命令处理放到Core1,同时在Core1的循环中加入短暂休眠,避免抢占定时器资源:

from machine import UART, Pin
import _thread
import utime

# 初始化UART
uart = UART(1, baudrate=9600, tx=Pin(4), rx=Pin(5))
rx_pin = Pin(5, Pin.IN)

# 全局标志位与锁
rx_trig = False
lock = _thread.allocate_lock()

# RXD引脚中断回调(仅设置标志)
def on_uart_rx(pin):
    global rx_trig
    with lock:
        rx_trig = True

# Core1的命令处理循环
def core1_task():
    global rx_trig
    while True:
        with lock:
            if rx_trig:
                # 读取UART数据并处理命令
                if uart.any():
                    data = uart.read()
                    # 替换为你的命令处理逻辑
                    print(f"Received command: {data}")
                rx_trig = False
        # 主动让出CPU时间,避免阻塞Core0的定时器
        utime.sleep_ms(1)

# 注册RXD上升沿中断
rx_pin.irq(trigger=Pin.IRQ_RISING, handler=on_uart_rx)

# 启动Core1任务
_thread.start_new_thread(core1_task, ())

# Core0的主逻辑(含定时器任务)
while True:
    # 替换为你的定时器相关代码
    utime.sleep(1)
    print("Core0 timer tick")

方案二:用PIO实现硬件级UART接收中断(更可靠)

RP2040的PIO可独立处理UART接收,不受CPU核心调度影响,适合低延迟场景:

from machine import Pin
import rp2
import utime

# PIO程序:接收UART字节后触发中断
@rp2.asm_pio()
def uart_rx():
    # 配置UART波特率适配(基于125MHz时钟,9600波特)
    set(x, 130)
    set(y, 12)
    label("bit_loop")
    wait(0, pin, 0)  # 等待起始位
    wait(1, pin, 0)  # 跳过起始位
    in_(pins, 1)     # 读取数据位
    jmp(x_dec, "bit_loop")  # 循环读取8位
    irq(block, 0)    # 触发中断

# 初始化PIO状态机
sm = rp2.StateMachine(0, uart_rx, freq=125000000, in_base=Pin(5))

# PIO中断回调
def on_pio_rx(sm):
    data = sm.get() >> 24  # 提取接收到的字节
    # 替换为你的命令处理逻辑
    print(f"PIO received: {chr(data)}")

# 注册PIO中断
sm.irq(on_pio_rx)

# 启动状态机
sm.active(1)

# Core0主逻辑(含定时器)
while True:
    utime.sleep(1)
    print("Core0 timer tick")

关键注意事项

  • 中断回调函数必须极简,不能包含耗时操作(如串口打印、复杂计算),否则会阻塞其他中断或定时器。
  • 若坚持用引脚中转方案,需确保cmdPin的中断优先级高于RXD,且回调仅做设置标志的操作,而非直接触发电平变化。
  • RP2040的MicroPython定时器默认运行在Core0,Core1的任务必须通过utime.sleep_ms()主动让出CPU时间,避免抢占资源。

内容的提问来源于stack exchange,提问作者Aaditya Dengle

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 23:15:24