
第一次拿到一块绿色的 Raspberry Pi Pico我盯着板子看了好一会儿没有常见的 USB 转串口芯片没有复位按键只有一个孤零零的 BOOTSEL 按钮。如果不懂烧录原理还真不知道怎么把代码弄进去。很多做硬件开发的新手就是卡在了这第一步。这篇入门课我会用一次完整的项目实践把 MicroPython 从环境搭建、基础语法、GPIO 控制到一个能跑起来的温湿度监测器全部走一遍。如果你是第一次接触单片机或者写过一点 Python 但没碰过硬件这篇内容就是为你准备的。跟着做完你不仅会点亮板载 LED还能独立完成一个带屏幕显示的硬件小项目。1. 为什么我建议新手第一块板子选 Pico语言选 MicroPython选开发板这件事很多人一开始就没选对。我自己最早是从 Arduino 入的门后来玩过一阵子 STM32再回到 Pico MicroPython 这条路线时最大的感受是不是每个人都需要从寄存器开始学嵌入式很多时候你得先把跑通一个项目的成就感建立起来才谈得上有动力去啃底层原理。1.1 几种常见入门路线的实际体验对比很多新手选板子是被关键词带跑的Arduino 最简单51 是经典STM32 找工作有用。但实际体验差别很大。入门路线编程语言上手难度典型卡点Arduino UnoC中等需要理解库函数和编译过程IDE 稍显老旧51 单片机C偏高寄存器配置繁琐一个定时器能折腾一下午STM32C / 寄存器偏高时钟树、外设初始化、调试器配置门槛劝退ESP32C / MicroPython中等上手容易但默认走物联网方向容易分心Raspberry Pi PicoMicroPython低几乎没有硬性门槛拖拽固件即可开始这里不是说 Arduino 或者 STM32 不好而是从第一次接触硬件开发的角度看Pico 提供了更低的上手门槛。你不需要在开始写代码之前理解一堆底层概念。MicroPython 解释器已经把这颗 RP2040 芯片的复杂寄存器操作封装成了Pin、PWM、I2C这类直观对象你要做的只是像写 Python 脚本一样调用它们。1.2 Pico 的硬件底子足够撑起入门到进阶Pico 的核心是 RP2040 芯片双核 ARM Cortex-M0主频最高 133MHz264KB SRAM2MB 板载 Flash。这些参数在单片机里不算惊艳但配合 MicroPython 解释器运行日常的传感器读取、电机控制、屏幕显示项目是绰绰有余的。引脚资源方面Pico 提供了 40 个引脚其中 26 个是多功能 GPIO。这意味着同一个引脚既可以用作数字输入输出也可以配置成 PWM、I2C、SPI、UART 等外设接口。板载还有 3 个外部 ADC 通道可以读取模拟电压另外 1 个通道连着片内温度传感器。对入门来说这些接口已经覆盖了大部分实验场景。我特别欣赏 Pico 的一点是它的官方文档把每一根引脚的第二功能标注得明明白白。比如你要用 I2C0文档会告诉你 SDA 可以映射到 GP0、GP4、GP8 或 GP12SCL 可以映射到 GP1、GP5、GP9 或 GP13。相比之下很多老牌开发板的引脚复用信息要翻几十页数据手册才能拼凑完整Pico 在这方面非常友好。1.3 MicroPython 带来的即时反馈体验MicroPython 是 Python 3 的精简实现官方移植版专门为 Pico 做了适配。它带来的最大好处是REPL 交互模式。和传统的编辑代码 → 编译 → 烧录 → 复位流程不同你在 REPL 里随便敲一行print(hello)回车就会立刻看到输出敲一行led.toggle()板载 LED 马上就会闪一下。这种即时反馈对新手学习是决定性的。我见过太多人因为编译错误和烧录失败在一个点灯程序上耗掉一整天最后怀疑自己不适合搞硬件。而 MicroPython 让你把注意力放在逻辑本身而不是工具链上。打个比方传统单片机开发像你在异国他乡生活得先学会当地语言才能点餐MicroPython 则像配了一位翻译你直接用母语告诉服务员你想吃什么翻译负责沟通。底层的事交给固件去做。2. 开工前先解决这三件事固件下载、烧录与开发环境既然选择 Pico MicroPython开箱后第一步不是急着写代码而是先让板子跑起来。这一节我会把固件获取、烧录和 IDE 配置讲透每一步的原理也会说清楚。2.1 在官方下载页拿到 UF2 固件Pico 使用 UF2 格式的固件文件。UF2 是微软和 Adafruit 推动的一种块格式专门设计成把磁盘拖个文件进去就能烧录。下载时要去 MicroPython 官网的下载页面找到 Raspberry Pi Pico 对应的.uf2文件。市面上还有一些第三方编译的 MicroPython 固件加入了各类扩展功能。入门阶段我建议直接用官方固件稳定、无坑。等后面你想玩 USB Host 这类特殊功能时再考虑社区实验固件。2.2 拖拽式烧录的具体姿势Pico 的烧录流程非常简单但关键动作是顺序不能错先用 USB 线把 Pico 连接到电脑但此时先不要急着插线。用手指按住板上唯一的BOOTSEL按钮不要松开。保持按住 BOOTSEL 的状态把 USB 线插入电脑。电脑会弹出一个名为RPI-RP2的可移动磁盘。把你下载好的.uf2固件文件直接拖拽到这个磁盘里。等待拷贝完成Pico 会自动重启RPI-RP2磁盘会消失。烧录完成后MicroPython 固件就写进了 Pico 的 Flash。注意这只是覆盖了 Flash 中的应用区BOOTSEL 引导程序是固化在芯片 ROM 里的不可能被冲掉。所以无论你怎么折腾固件都不会把板子变成砖。以后想换固件版本随时可以重新进入 BOOTSEL 模式来一遍。这里有个常见的疑问为什么按住 BOOTSEL 才会出现磁盘因为 RP2040 芯片上电时默认从 Flash 启动。如果 Flash 里的固件损坏或不存在芯片无法进入正常模式。按住 BOOTSEL 则强制芯片进入 USB 引导模式这时芯片会枚举成一个 USB 大容量存储设备把主控 Flash 模拟成可写磁盘。这是 Pico 一个很贴心的设计新手不需要额外的烧录器。2.3 配置 Thonny进入 REPL 交互固件就绪之后需要一个能跟板子对话的 IDE。Thonny 是我最推荐给新手的工具它本身是一个轻量 Python IDE内置了对 Pico 的完整支持。打开 Thonny依次配置菜单栏点击运行 →选择解释器。在解释器下拉框中选择MicroPython (Raspberry Pi Pico)。端口选择通常会自动识别。如果识别不到检查 USB 线是否插好、固件是否烧录成功。点击确定后下方 Shell 窗口会出现提示符这就是 MicroPython 的 REPL。配置完成后在 Shell 里输入print(hello pico)立即会输出hello pico。这一瞬间Pico 和电脑之间的对话通道就算打通了。2.4 第一个脚本点亮板载 LEDREPL 验证通过后就可以动手点灯了。Pico 板载一颗绿色的 LED它连接在 GPIO25 上。在 Thonny 中输入以下代码并运行from machine import Pin import time led Pin(LED, Pin.OUT) while True: led.toggle() time.sleep(0.5)程序运行后板载 LED 会以 0.5 秒的间隔交替闪烁。如果你用的板子是 Pico W带 Wi-Fi 的版本用Pin(LED)这个写法也完全兼容但如果抄老教程里的Pin(25)在 Pico W 上可能没反应。这里建议统一用Pin(LED)这也是新版官方固件推荐的写法。Thonny 的运行逻辑默认是运行时临时推送也就是代码只在内存里跑断电就没了。如果想让程序上电自动运行需要把代码保存到 Pico 的main.py文件中。操作方法是在 Thonny 中按CtrlShiftS选择保存到 Raspberry Pi Pico文件名填main.py。之后 Pico 一通电就会自动执行这个文件。这个机制和 Arduino 的setup()/loop()不同更接近脚本语言的运行方式也延续了 Python 的__main__思维。3. MicroPython 玩转硬件的三大基础GPIO、PWM 与中断灯能闪了只是热身。接下来我会把硬件开发中最核心的三种操作讲清楚数字输入输出、PWM 模拟输出、外部中断。这三个能力几乎覆盖了 80% 的入门项目需求。3.1 GPIO 输出从闪烁开始理解数字引脚GPIO 是 General Purpose Input/Output 的缩写也就是通用输入输出引脚。你把它配置成输出模式就能控制高电平3.3V或低电平0V配置成输入模式就能读取外部是高电平还是低电平。上面那个闪烁程序Pin(LED, Pin.OUT)做的就是两件事指定引脚对象、设置输出模式。led.toggle()则是把当前电平反转一次配合sleep实现闪烁。很多新手容易把time.sleep写成阻塞式循环导致按键检测不到。这是因为while True里的sleep会让 CPU 一直空转在睡眠期间无法执行其他代码。解决这个问题的思路有两个一是用中断二是用非阻塞的ticks_ms()时间差判断。后面我都会讲到。3.2 PWM用数字引脚产生模拟效果数字引脚只能输出 0 或 3.3V 两种状态但很多场景需要一半的电压或者渐变的光。这时候就要用 PWM脉冲宽度调制。原理听上去复杂实际很简单让引脚以极快的速度在高电平和低电平之间切换通过改变高电平持续的时间比例占空比等效出介于 0 和满电压之间的输出效果。人眼看到的就是变暗的灯。看一个呼吸灯例子from machine import Pin, PWM import time led PWM(Pin(LED)) led.freq(1000) while True: for duty in range(0, 65535, 1000): led.duty_u16(duty) time.sleep_ms(2) for duty in range(65535, 0, -1000): led.duty_u16(duty) time.sleep_ms(2)关键点有两个freq(1000)设定 PWM 频率为 1000Hz也就是每秒切换 1000 个周期。频率太低会看到明显闪烁太高则可能导致电压建立不足。duty_u16(0~65535)设置占空比0 表示全程低电平65535 表示全程高电平。这个 16 位的范围听起来别扭但它是 MicroPython 跨平台统一的标准直接照用就行。PWM 的用途不只限于调光它还能驱动舵机、控制电机转速、模拟声音输出。理解了占空比你等于解锁了模拟世界的大门。3.3 外部中断让程序在等待中保持响应轮询的问题在于如果主循环正在执行sleep或耗时任务按键事件就会错过。中断机制解决了这个问题当引脚电平发生变化时芯片会暂停当前工作跳转执行你注册的回调函数。用按键控制一个计数器的例子from machine import Pin import time counter 0 last_time 0 btn Pin(15, Pin.IN, Pin.PULL_UP) def btn_handler(pin): global counter, last_time now time.ticks_ms() if time.ticks_diff(now, last_time) 50: return last_time now counter 1 print(按键次数:, counter) btn.irq(triggerPin.IRQ_FALLING, handlerbtn_handler)这里有几个值得注意的细节。Pin.PULL_UP启用了内部上拉电阻。按键一端接 GP15另一端接 GND。不按键时GP15 被上拉到高电平按下时引脚被拉到低电平。Pin.IRQ_FALLING就是在检测电平从高变低的瞬间。回调函数里的去抖逻辑非常关键。机械按键在按下和释放的瞬间金属触点会反复弹跳几十毫秒如果不去抖一次按键可能触发多次中断。传统做法是加 RC 滤波电路在软件里最简单可靠的就是用ticks_ms()记录时间两次触发间隔小于 50ms 就忽略。这里我还要提醒一个新手容易犯的错误直接在回调函数里写耗时的操作比如sleep或大循环。中断回调应该尽量轻量复杂的逻辑放到主循环里处理。我习惯的做法是回调里只设置一个标志位主循环检测到标志位后再做真正的工作。3.4 ADC 模拟输入为传感器项目做准备除了数字信号很多传感器输出的是连续变化的电压值比如电位器、光敏电阻、土壤湿度传感器。Pico 的 GP26、GP27、GP28 分别对应 ADC0、ADC1、ADC2可读取 0~3.3V 的模拟电压。读取一个模拟值的核心代码很简单from machine import ADC, Pin pot ADC(Pin(26)) value pot.read_u16() voltage value / 65535 * 3.3 print(原始值:, value, 电压:, voltage, V)read_u16()将模拟电压映射到 0~65535 的整数范围除以 65535 再乘 3.3就得到实际电压。注意 ADC 输入电压绝对不能超过 3.3V否则可能损坏引脚。如果你要用外部传感器输出 5V 信号必须加电阻分压或电平转换电路。4. 从零做一个温湿度监测器DHT11 OLED 显示屏实践前面讲的知识点单个练终究是散的。这一节我会做一个综合项目把 DHT11 温湿度传感器采集到的数据实时显示在 OLED 小屏幕上。这个小项目虽然入门但涵盖了数字输入、I2C 通信、库引用和用户界面是一个非常完整的硬件开发缩影。4.1 项目选材与接线硬件清单如下Raspberry Pi Pico 一块DHT11 温湿度传感器模块一个0.96 寸 SSD1306 OLED 显示屏I2C 接口一个面包板、杜邦线若干选 DHT11 不是因为性能好而是因为便宜、四线接口简单、库支持完善。它的精度一般温度 ±2°C湿度 ±5%做验证和学习完全够用。如果以后要做严肃的数据采集可以换 DHT22 或 SHT3x但接线逻辑是一样的。接线方案我也给出来模块引脚连接到 PicoDHT11VCC3V3DHT11DATAGP16DHT11GNDGNDOLEDVCC3V3OLEDSDAGP8OLEDSCLGP9OLEDGNDGND注意如果你用的是裸的 DHT11 元件而不是模块DATA 与 VCC 之间需要外接一个 4.7kΩ 上拉电阻。很多模块已经集成了上拉电阻接法就简单多了。OLED 的 I2C 地址默认是 0x3C部分屏幕模块可以通过背面电阻调整如果代码里扫描不到设备优先检查地址。I2C 引脚为什么选 GP8/GP9因为这对引脚在 MicroPython 中默认映射为 I2C0 的 SDA/SCL也是最常见的接线。当然也可以换成其他支持 I2C0 的引脚比如 GP4/GP5只要初始化代码里同步改就好了。4.2 把 ssd1306 驱动装进 Pico 文件系统DHT11 的驱动已经内置在官方 MicroPython 固件里直接import dht就能用。但 SSD1306 显示屏的驱动不是固件自带的需要手动往 Pico 文件系统里放一个ssd1306.py文件。获取方式很简单在 MicroPython 官方驱动仓库里找到drivers/display/ssd1306.py下载到本地。然后在 Thonny 中点击菜单视图→文件打开文件面板把本地的ssd1306.py文件拖拽到 Pico 的根目录即可。这一步容易被新手忽略。很多教程直接写import ssd1306但你没装驱动文件运行就会报ModuleNotFoundError。把这个文件理解成 Python 的第三方库只是安装方式变成了手动拖拽。4.3 完整代码与关键点注释下面是完整程序我会把每一段的作用都标注清楚from machine import Pin, I2C import dht import ssd1306 import time # 1. 初始化温湿度传感器 d dht.DHT11(Pin(16)) # 2. 初始化 OLED通过 I2C0 通信 i2c I2C(0, sclPin(9), sdaPin(8), freq100000) oled ssd1306.SSD1306_I2C(128, 64, i2c) # 3. 主循环 while True: try: # 触发一次温湿度测量 d.measure() temp d.temperature() hum d.humidity() # 在 OLED 上显示 oled.fill(0) # 清屏 oled.text(Temp: {} C.format(temp), 0, 0) oled.text(Hum: {} %.format(hum), 0, 16) oled.show() # 同时在终端打印方便调试 print(temp, hum) except OSError as e: # DHT11 偶尔会发出未就绪错误打印但不崩溃 print(读取失败:, e) # 传感器读取间隔至少 1 秒最好 2 秒以上 time.sleep(2)这段代码有几个容易踩坑的地方我一个个说。d.measure()的作用是让 DHT11 启动一次测量。DHT11 的通信协议非常依赖时序测量完成之后temperature()和humidity()拿到的才是有效值。如果没有调用measure()直接读大概率读到 0 或者奇怪的数值。DHT11 两次测量之间的间隔必须大于 1 秒。我实际测试下来1 秒还是偶尔报错所以代码里统一用 2 秒。这个传感器本身很低速你要做更快的实时监控只能换传感器型号。oled.fill(0)是清屏操作oled.text()是在指定坐标绘制文字最后一定要调用oled.show()才真正刷新屏幕。SSD1306 这个库采用了 framebuffer 的机制所有绘图操作都是先画到内存里show()才一次性发送给屏幕。如果你写了text()但没写show()屏幕不会有任何变化。4.4 运行后遇到的问题与调试方式第一次运行时最可能遇到两个问题。第一个是 OLED 没反应。优先检查接线确认 SDA 接对因为 SDA 和 SCL 接反是经典错误。然后可以用一条命令扫描 I2C 总线上的设备地址from machine import Pin, I2C i2c I2C(0, sclPin(9), sdaPin(8), freq100000) print(i2c.scan())如果返回[60]说明 OLED 在 0x3C 地址上正常工作。如果返回空列表[]就是接线或者供电问题。这个方法适合所有 I2C 外设的故障排查请记住它。第二个问题是 DHT11 报错OSError: [Errno 110] ETIMEDOUT。这个很常见通常是因为读取间隔太短、接线松动、或者模块供电用的是 5V 而数据线直连 Pico 导致电平不匹配。建议模块供电统一用 3V3保持传感器数据线与 Pico GPIO 同电平域出问题的概率会小很多。项目跑通后你可以很清晰地看到这个 20 行不到的代码同时用到了数字输入DHT11 数据线、I2C 通信OLED、异常处理和定时调度。这已经是一个结构完整的硬件项目模型。5. 实测中让我反复翻车的五个坑在我带过的入门者以及自己早期的探索里有些坑出现频率极高。它们不是复杂的原理问题但每一个都能卡住新手大半天。我整理成一张表后面再逐个展开。问题现象可能原因解决办法电脑不识别 Pico没有盘符USB 线只能充电没有数据线芯换一条确认支持数据传输的 USB 线传感器读数异常或反复超时5V 与 3.3V 电平不匹配统一用 3V3 供电必要时加电平转换DHT11 报 ETIMEDOUT读取间隔太短或上拉电阻缺失间隔改 2 秒加 4.7kΩ 上拉引脚明明接到了外设没反应引脚被其他功能占用或功能复用冲突查阅引脚复用表换一组引脚重试照抄 Arduino 代码完全跑不通引脚编号规则和库 API 不同按 MicroPython 规则重新编写5.1 USB 线只能充电不能传数据的问题这大概是所有新手遇到的第一个隐性杀手。有些 USB 线内部只有电源线没有数据线插上之后电脑一点反应都没有。Pico 本身设计没问题问题出在这根线上。遇到识别不了的情况先别急着怀疑板子坏了拿一根确定能传数据的手机充电线换上去试试。我手边常备两根质量可靠的 USB 线专门用来调试开发板。5.2 5V 与 3.3V 电平的边界问题Pico 的所有 GPIO 都是 3.3V 电平。很多传感器模块为了方便默认支持 5V 供电输出高电平也是 5V。如果你把 5V 输出直接接到 Pico 的 GPIO 上轻则读数异常重则烧毁引脚。我遇到过最典型的情况是超声波模块 HC-SR04 的 Echo 脚输出 5V 高电平直接接 Pico 的 GP16读到的距离数据非常不稳定。后来加了一个分压电路才解决。任何 5V 逻辑信号进入 3.3V 系统都必须做电平转换。简单的电阻分压比如 1kΩ 串联 2kΩ 下拉就能满足大多数场景。5.3 DHT11 读取时序导致的报错DHT11 的时序协议是非常严格的单总线通信。MicroPython 的dht库底层处理了时序但在硬件层面如果你用了过长的杜邦线、或者模块供电不稳定measure()就很容易超时。实际经验是DHT11 用 3V3 供电比用 5V 更稳定数据线尽量短读取间隔至少 2 秒。而且代码里一定要包一层try/except。我见过太多程序因为一次传感器未就绪的异常直接在 while 循环里崩溃退出。5.4 引脚复用和默认功能的冲突Pico 的优势是引脚多功能但这也带来了冲突问题。比如 GP0/GP1 默认可以被用作 I2C0但同时它们也是 UART0 的 TX/RX 引脚。如果你在初始化 UART 之后再初始化 I2C0 选择了同一组引脚两个外设会抢资源结果非常诡异。解决办法是养成习惯每次接线之前查阅官方的引脚图确认同一组引脚没有被两个外设占用。如果一个项目里同时要用多路 I2C、UART 和 SPI务必规划好每一组引脚的专属功能。5.5 从 Arduino 习惯转过来的引脚编号误导如果你之前玩过 Arduino转到 Pico 第一反应可能是找板上印的 D13 这类标识。但 RP2040 的引脚命名全是 GP0GP1 这种风格且 MicroPython 里用的是Pin(0)这种整数值而不是 Arduino 里的D0。更迷惑的是有的教程写Pin(25)点灯但 Pico W 的 GPIO25 被无线模块占用代码跑起来没反应。我后来在代码里统一用Pin(LED)这种别名写法才彻底避免了不同板卡之间的差异。遇到板子行为异常先确认你手上的型号和教程里的型号是否一致这是硬件开发中非常基础但极其重要的一步。6. 下一个方向USB Host、其他支持 MicroPython 的板卡与更复杂的玩法到这里你已经完成了 Pico MicroPython 的入门闭环。接下去能往哪走我给你三个延展方向作为参考。6.1 RP2040 的 USB Host 潜力RP2040 芯片自带的 USB 控制器不仅支持设备模式也支持 Host 模式也就是可以像电脑一样外接其他 USB 设备。官方 MicroPython 固件目前主要面向 Device 场景但社区里已经有一些支持 USB Host 的 MicroPython 固件可以让 Pico 读取 U 盘里的文件、接收 USB 键盘或鼠标的事件。这个方向很适合做进阶项目。想一想用 Pico 做一个自动复制 U 盘文件的小盒子或者把它改造成一个 USB 键盘鼠标记录器这些都是可以拿得出手的作品。不过这类固件通常处于实验阶段需要一定的动手能力建议版本管理和固件备份做好再玩。6.2 支持 MicroPython 的板卡选择思路学会 Pico 之后你会发现 MicroPython 其实是一个跨芯片的生态。目前主流的支持 MicroPython 的单片机包括ESP32 系列自带 Wi-Fi 和蓝牙适合做物联网项目开发成本低社区资源丰富。ESP32-S3在 ESP32 基础上增加了 USB OTG 和更好的 AI 加速能力适合做带屏幕的交互设备。STM32F4 系列性能和生态都很强适合做更严肃的产品原型。RP2040 系列其他板卡比如 Pico W 自带了 Wi-Fi引脚布局和 Pico 基本一致迁移成本几乎为零。我的建议是不要急着换平台。先把手上的 Pico 玩熟等下一个项目明确需要无线或更高性能时再带着你已经掌握的思维框架去选新板子。硬件平台只是载体GPIO、I2C、PWM、中断这些底层逻辑是相通的。6.3 入门完成后可以继续深入的方向从项目实践的角度你可以按这几个方向进阶给 Pico 加上 Wi-Fi升级到 Pico W用 MicroPython 连接网络后把温湿度数据上传到本地服务器或云平台。做一个智能控制面板把之前的 OLED 扩展成多页面菜单用按键和旋钮控制 LED 亮度或画面切换。引入实时时钟和 SD 卡存储给监测器增加时间戳和离线记录功能让数据可以回放分析。学习用 C SDK 开发 PicoMicroPython 适合快速实现但对实时性和性能要求更高的场景RP2040 的 C 语言 SDK 能给你更精细的控制力。每次做新项目我都会提醒自己一句话不要为未来的需求预先做复杂的架构。先跑通最小可行版本再逐步加功能。这个思路在硬件开发里尤为重要因为接线的改动比代码的改动更麻烦一次只改一个变量才不会把自己绕进坑里。如果你把上面这套 DHT11 OLED 的代码完整跑通并且理解了 GPIO、中断、I2C 各起了什么作用那恭喜你Pico 的大门已经正式为你打开了。下一课我打算接着写 Pico W 的无线功能把一个能联网上报数据的版本做出来到时候见。