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

何时一樽酒,重与细论文。

搜索