PicoのPIO遊び

PIOを使うことで、MicroPythonでも厳密な波形を簡単に生成できる。やはりRaspberry Pi Picoは面白い。

例えばMicroPythonのGPIO制御で全速力でゼロイチを切り替えて矩形波を生成するプログラムを書いてみる。

import machine

led_onboard = machine.Pin(3, machine.Pin.OUT)

while True:
    led_onboard.value(0)
    led_onboard.value(1)

出力される波形はこんな感じ。

周波数は59 kHzしかでず、ジッタが2 μsほどある。用途によるが、たとえばGPIOピンを介したを使った通信・データ転送などには厳しいように思う。

PIOを利用した厳密なタイミング制御

これをPIOを使うと厳密なタイミング制御ができる。

import time
from rp2 import PIO, StateMachine, asm_pio
from machine import Pin

@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def rect_gen():
    wrap_target()
    set(pins, 1) [4]
    set(pins, 0) [4]
    wrap()

sm = rp2.StateMachine(0, rect_gen, freq=1_000_000, set_base=Pin(3))
sm.active(1)

while True:
    pass

1 MHzを10クロックのサイクルで繰り返している。

素晴らしい・・
出力周波数を上げてみよう。動作周波数をクロック周波数の125 MHzにして、ディレイを0にしてみる。

流石に矩形波という感じではなくなっている。寄生容量とプルダウン抵抗でLPFが形成されているせいか、使っているオシロのせいか分からんが波形が鈍っているが、確かに理論的な周波数がきっちり実現できていて素晴らしい。


なお、下のように出力ピンを複数化すると、1/2周期の矩形波を同時出力するのもお手のものである。

import time
from rp2 import PIO, StateMachine, asm_pio
from machine import Pin

@rp2.asm_pio(set_init=(rp2.PIO.OUT_LOW,)*2)
def rect_gen():
    wrap_target()
    set(pins, 0b00)
    set(pins, 0b01)
    set(pins, 0b10)
    set(pins, 0b11)
    wrap()

sm = rp2.StateMachine(0, rect_gen, freq=125_000_000, set_base=Pin(3))
sm.active(1)

while True:
    pass

遊びがいがある。