【pico入门级教程】8-PIO(可编程输入输出接口)

【MicroPython】PIO有关函数详解

MicroPython引入了一个新的@rp2.Asm_pio装饰器和rp2.PIO类.

  • PIO程序的定义和状态机的配置分为2个逻辑部分:
    1. 程序定义,包括使用了多少引脚,如果它们是in/out引脚。这在@rp2.asm_pio中定义。
    2. 程序,设置状态机的频率和绑定到哪个引脚。当设置一个状态机来运行特定的程序时,就会设置这些参数。

所有的程序配置(例如autopull)都是在@asm_pio装饰器中完成的。 只设置频率和基础引脚需要在StateMachine构造函数中设置。

@asm_pio装饰器

@asm_pio(
    out_init=None,
    set_init=None,
    sideset_init=None,
    in_shiftdir=0,
    out_shiftdir=0,
    autopush=False,
    autopull=False,
    push_thresh=32,
    pull_thresh=32,
    fifo_join=0
)
  • out_init :输出引脚初始化
  • set_init :设置引脚初始化
  • sideset_init :侧置引脚初始化
  • in_shiftdir : 数据输入方向
  • out_shiftdir:数据输出方向
  • autopush :自动推送,若开启,当ISR达到阈值,自动将ISR传输到RX-FIFO。
  • autopull :自动拉取,若开启,当OSR达到阈值,自动将TX-FIFO传输到OSR。
  • push_thresh :推送阈值
  • pull_thresh :拉取阈值
  • fifo_join :fifo组合,指定一个FIFO,将另一个FIFO关闭并加入改FIFO,获取更深位数的FIFO.

rp2.StateMachine函数详解

  • rp2.StateMachine.init(sm_id ,program, freq=-1, *, in_base=None, out_base=None, set_base=None, jmp_pin=None, sideset_base=None, in_shiftdir=None, out_shiftdir=None, push_thresh=None, pull_thresh=None)
    • sm_id:使用状态机ID
    • program:PIO运行程序
    • freq:状态机运行频率,默认为系统时钟频率,
      • 时钟分频器的分配因子计算公式为“系统时钟频率/频率”,所以 可能存在轻微的舍入误差。
      • 最小可能的时钟分频器是系统时钟的 65536 分之一:所以在默认系统时钟频率 125MHz下,最小值为1908。
      • 要以较慢的频率运行状态机,需要使用“machine.freq()”降低系统时钟速度。
    • in_base:用于in()指令的第一个引脚
    • out_base:用于out()指令的第一个引脚
    • set_base:用于set()指令的第一个引脚
    • jmp_pin:用于jmp(pin, …)指令的第一个引脚
    • sideset_base:是用于侧置的第一个引脚。
    • in_shiftdir:ISR将移动的方向,可为PIO.SHIFT_LEFT或者PIO.SHIFT_RIGHT
    • out_shiftdir: OSR 将移动的方向,可为PIO.SHIFT_LEFT或者PIO.SHIFT_RIGHT
    • push_thresh:推送阈值
    • pull_thresh:拉取阈值
  • StateMachine.active([value])
    • 获取或设置状态机当前是否正在运行。
    • 当value不为空时,设置状态机,反之获取运行状态。
  • StateMachine.restart()
    • 重新启动状态机并跳转到程序的开头。
  • StateMachine.exec(instr)
    • 执行单个 PIO 指令。使用 asm_pio_encode 编码 来自给定字符串 instr 的指令。
  • StateMachine.get(buf=None, shift=0)
    • 从状态机的RX-FIFO中提取一个字。
    • 如果FIFO为空,它会阻塞直到数据到达(即状态机推一个字)。
    • shift为在返回之前右移位数
    • 返回值是“word >> shift”
  • StateMachine.put(value, shift=0)
    • 将一个字推送到状态机的 TX FIFO。
    • 如果 FIFO已满,它将阻塞直到有空间(即状态机拉一个字)。
    • shift为在返回之前右移位数
    • 返回值是“word >> shift”
  • StateMachine.rx_fifo()
    • 返回状态机的 RX FIFO 中的字数。值为0表示 FIFO 为空。
    • 用于在调用之前检查数据是否正在等待读取StateMachine.get()
  • StateMachine.tx_fifo()
    • 返回状态机的 RX FIFO 中的字数。值为0表示 FIFO 为空。
    • 用于在调用之前检查数据是否正在等待读取StateMachine.put()
  • StateMachine.irq(handler=None, trigger=0|1, hard=False)
    • 返回给定 StateMachine 的 IRQ 对象。

PIO_ASM

  1. JMP (condition) target
    1. target :跳转地址,允许数值0-31,因为PIO只有32条指令空间。
    2. condition :
      1. !X OR !Y:
      2. X– OR Y–
      3. X!=Y :
      4. PIN :
      5. !(OSRE):
    • JMP指令作用是将达到某些条件的情况下将程序跳转到指定地址.
    • 当条件达成时,程序就会根据target跳转指定地址
    • 当然也可以不填写条件,则会无条件跳转指定地址。
  2. WAIT Polarity Source Index
    1. Polarity: 等待 0 OR 1
    2. Source:
      1. GPIO:绝对GPIO
      2. PIN:引脚映射后的引脚
      3. IRQ:中断标志
    3. Index:
      1. GPIO_num:对应GPIO源,GPIO数值
      2. pin_num:对应pin源,pin数值
      3. IRQ_num:对应IRQ源,指定等待的引脚或者位,这里IRQ_NUM也是支持使用(_rel)
    • WAIT指令作用为在条件达成前等待
  3. IN Source,Bitcount
    1. Source :
      1. PINS
      2. X
      3. Y
      4. NULL
      5. ISR
      6. OSR
    2. Bitcount :读取位数
    • IN指令作用将数据存入ISR寄存器
  4. OUT destination,Bitcount
    1. destination :
      1. PINS
      2. X
      3. Y
      4. NULL
      5. PINDIRS
      6. PC
      7. ISR
      8. OSR
    2. Bitcount :读取位数
    • OUT和IN功能相反,指令作用将OSR寄存器输出到目标
  5. PUSH (IfFull) (Block/noBloc k)
    1. IfFull,若为1则只有ISR到达阈值,才能推送.
    2. Block,若为1且RX FIFO达到阈值,就会进行将数据推送到ISR中,否则会等待RXFIO达到阈值,若为0则RXFIFO达不到阈值,则不会进行推送。
    • PUSH指令的作用为将ISR中内容推送到RX FIFO和清空ISR
  6. PULL (IfEmpty) (Block/noBloc k)
    1. IfEmpty:若为1则只有OSR才会接收TXFIFO的数据。
    2. Block:1则TXFIFO为空则等待TXFIFO.
    • PUSH指令的作用将从TXFIFO数据读出到OSR寄存器。
  7. MOV destinationmov,(Operation ),source
    1. destination:
      1. PINS:输出映射
      2. X:
      3. Y:
      4. EXEC:解码寄存器
      5. PC:PC寄存器(JUM)
      6. ISR
      7. EXEC:
    2. source:
      1. PINS:
      2. X
      3. Y
      4. NULL:空,用于清零
      5. STATUS:表示不同状态,如fifo满或者空。
      6. ISR:
      7. OSR:
    3. Operation:
      1. 00:不改变
      2. 01:位取反
      3. 10:位翻转,高低位互换。
    • MOV 指令其作用为将数据从源移动目标寄存器。
  8. IRQ (option) irq_num (_rel)
    1. irq_num:0-7 中断标志位
    2. option
      1. set(默认):设置
      2. nowait(默认):不等待清除
      3. wait:等待清除后,运行
      4. clear:清除
    3. _rel:若存在则将irq_num和状态机编码sm_num相加并进行模四运行并将高位置1,若状态机2设置中断标识3,中断值则为0X11
    • irq_flag=(sm_id+irq_num) %4 + 0x10
    • IRQ指令作用为设置或者清空中断标识
  9. SET destination,data
    1. destination:目标地址
      1. PINS :SET映射引脚
      2. PINDIRS :引脚方向,将第一个映射GPIO1为输出,0为输入
      3. X : 暂存寄存器,暂存数据
      4. Y : 暂存寄存器,暂存数据
    2. data :数据, 0-31
    • set指令会将数据写入目标地址.通常用于控制设置映射引脚。

例程地址

此文章仅针对RP2040 MicroPython固件,以源码为准,本文根据编写时官方源码编写,用于为初学者提供便利,仅供于参考,如有能力者建议自行查询MicroPython源码