post / 2024.02.15

MicroPython函式庫

MicroPython函式庫

本文整理 MicroPython 的 machine 模組在 Raspberry Pi Pico(RP2040)上的常用介面。內容已對照 MicroPython 官方文件 核對。

machine:與硬體相關的功能

腳位編號有以下兩種:

  • GPIO 編號(GP0–GP29):程式碼裡最常用,Pin(25) 就是 GP25。
  • 實體腳位號:開發板上的 40 個針腳位置,與 GPIO 編號不是一回事,接線時要注意區分。

Pin 類別

建構子 machine.Pin(id, mode=-1, pull=-1, value=None)

參數說明
id腳位編號。Pico 上可用 0–29(GP0–GP29)
modeNone / Pin.IN(0) / Pin.OUT(1) / Pin.OPEN_DRAIN(2)
pull內部上下拉電阻,僅在輸入模式有效:None / Pin.PULL_UP(1) / Pin.PULL_DOWN(2)
value僅輸出/開汲極模式有效,初始電位:0 低電位,1 高電位

注意是 Pin.PULL_DOWN,不是 Pin.DOWN。

Pin.init(mode=-1, pull=-1, value=None)

重新初始化腳位。只修改傳入的參數,其餘狀態保持不變。

Pin.value([x])

  • 不傳參數:回傳目前腳位電位(0 或 1)。
  • 傳參數:寫入腳位電位,參數會被轉成布林值(True 置 1,False 置 0)。

Pin.on() / Pin.off()、Pin.high() / Pin.low()

  • on()、high():輸出高電位(置 1)。
  • off()、low():輸出低電位(置 0)。

這四個方法僅對輸出/開汲極模式有意義。low() / high() 屬於非核心 API,在 Pico(rp2)上可用。

Pin.toggle()

翻轉輸出電位,0 變 1、1 變 0。toggle() 在 rp2、esp32 等埠可用;如果某個埠不支援,用 Pin.value(not Pin.value()) 代替。

from machine import Pin
import time

led = Pin(25, Pin.OUT)   # Pico 板載 LED 在 GP25
while True:
    led.toggle()
    time.sleep(1)        # 每 1 秒翻轉一次

Pin.irq(handler=None, trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING)

設定外部中斷。電位變化時自動呼叫回呼函式。

  • handler:中斷回呼函式,必須接收一個 Pin 參數。
  • trigger:觸發條件,可用 | 組合:
常數含義
Pin.IRQ_FALLING下降緣
Pin.IRQ_RISING上升緣
Pin.IRQ_LOW_LEVEL低電位
Pin.IRQ_HIGH_LEVEL高電位
def on_press(pin):
    print("按鍵被按下")

button = Pin(15, Pin.IN, Pin.PULL_UP)
button.irq(handler=on_press, trigger=Pin.IRQ_FALLING)

PWM 類別

PWM(脈衝寬度調變)透過快速開關來模擬中間的電壓值,常用於調光、調速、伺服馬達控制。

machine.PWM(pin, freq=..., duty_u16=...)

在指定腳位上建立 PWM 輸出,pin 是 Pin 物件。

常用方法

方法作用
PWM.freq([value])讀取/設定頻率,單位 Hz,範圍約 8 Hz – 62.5 MHz(CPU 125 MHz 時)
PWM.duty_u16([value])讀取/設定工作週期,取值 0–65535,代表 value / 65535 的比例
PWM.duty_ns([value])讀取/設定一個週期內的高電位時長,單位 ns
PWM.deinit()關閉 PWM 輸出

注意 duty_u16 的上限是 65535,不是 65536。寫 65536 會溢位。

RP2040 有 8 組獨立的 PWM 切片,每組 2 個通道,共 16 路。同一組的兩個通道必須共用頻率,但可以有不同工作週期。

例:呼吸燈

from machine import Pin, PWM
import time

led = PWM(Pin(25))
led.freq(1000)      # 1 kHz

duty = 0            # 工作週期百分比
step = 1

while True:
    duty += step
    if duty >= 100:
        duty = 100
        step = -1
    elif duty <= 0:
        duty = 0
        step = 1

    # 百分比換算成 0-65535,注意別越界
    led.duty_u16(int(duty / 100 * 65535))

    if duty % 5 == 0:
        print(duty)  # 方便繪圖觀察

    time.sleep(0.01)  # 約 2 秒一個來回

例:按鍵點燈(含軟體防彈跳)

from machine import Pin
import time

button = Pin(15, Pin.IN, Pin.PULL_UP)   # 按下時讀到 0
led_board = Pin(25, Pin.OUT)            # 板載 LED
led_ext = Pin(16, Pin.OUT)              # 外接 LED

while True:
    led_ext.off()
    if button.value() == 0:             # 可能按下
        time.sleep(0.01)                # 等 10 ms 再確認,濾掉彈跳
        if button.value() == 0:         # 確認按下
            led_board.toggle()
            led_ext.on()
            print("The button is pressed.")
            while button.value() == 0:  # 等待放開
                time.sleep(0.01)

機械按鍵在按下和放開的瞬間會產生毫秒級的電位彈跳,被 CPU 讀成多次按鍵。軟體防彈跳的做法是:偵測到按下後延時 10 ms 再確認一次。

ADC 類別

ADC(類比數位轉換)把類比電壓轉成數位量。

machine.ADC(id)

id 可以是 Pin 物件,也可以是通道號:

  • Pico 上通道 0–3 對應 GP26–GP29(GP29 板載接 VSYS);
  • 通道 4 是晶片內建溫度感測器,可用 ADC.CORE_TEMP 表示。

ADC.read_u16()

讀取轉換結果,回傳 0–65535 的整數,對應電壓範圍 0–3.3 V。

from machine import ADC, Pin

adc = ADC(Pin(26))          # 也可以寫成 ADC(0)
value = adc.read_u16()      # 0 - 65535
voltage = value / 65535 * 3.3   # 換算成電壓
print(voltage, "V")

注意量程是 0–65535。RP2040 的 ADC 硬體本身是 12 位元(0–4095),MicroPython 將它線性拉伸到 16 位元,所以末尾幾位沒有實際精度。

小結

場景關鍵點
數位輸入輸出Pin(id, mode, pull),輸入用 value() 讀,輸出用 value() / on() / off() / toggle()
中斷Pin.irq(handler, trigger),回呼必須帶一個 Pin 參數
調光/調速PWM(pin) + freq() + duty_u16(),工作週期上限 65535
讀類比量ADC(Pin(26)) + read_u16(),回傳 0–65535
按鍵彈跳偵測到變化後延時 10 ms 再確認

本文作者: 孤筝

本文標題: MicroPython函式庫

本文發佈時間: 2024-02-15

本文更新時間: 2026-10-05

本文版權: CC BY-NC-SA 4.0

何時一樽酒,重與細論文。

搜尋