你需要的RP2040 MicroPython固件官方下载地址和详细刷入步骤我都整理好了,新手也能轻松操作:
一、官方下载地址
-
核心官网(树莓派基金会) :
这个页面不仅能下载固件,还包含完整的MicroPython使用文档。
-
固件直链(懒人版) :
直接下载最新稳定版Pico/Pico W固件(根据你的板子选择):
- Raspberry Pi Pico(无WiFi):https://micropython.org/download/rp2-pico/rp2-pico-latest.uf2
- Raspberry Pi Pico W(带WiFi):https://micropython.org/download/rp2-pico-w/rp2-pico-w-latest.uf2
二、完整刷入固件步骤(补充细节,避免踩坑)
-
进入BOOTSEL模式:
- 按住RP2040开发板上的
BOOTSEL按键(唯一的按键)不松手; - 将USB线(建议用数据线,而非充电线)插入开发板的USB口,另一端连接电脑;
- 电脑识别到后(会弹出一个名为
RPI-RP2的U盘),再松开BOOTSEL键。
- 按住RP2040开发板上的
-
刷入固件:
- 打开
RPI-RP2这个U盘(Windows/ macOS/ Linux都能识别); - 将下载好的
.uf2格式固件文件直接拖入这个U盘; - 拖入后,U盘会自动断开,开发板重启,MicroPython固件就刷入完成了。
- 打开
三、验证是否刷入成功
- 打开Thonny IDE(新手首选);
- 点击Thonny右上角的「解释器」选择框,选择「MicroPython (Raspberry Pi Pico)」;
- 点击「确定」,如果能看到串口连接成功的提示,且左下角显示「Python 3.xx.xx (MicroPython)」,说明固件刷入成功。
总结
- 核心官网 :树莓派官方文档页
https://www.raspberrypi.com/documentation/microcontrollers/micropython.html是最权威的入口,包含固件下载和所有使用说明; - 刷入关键 :必须按住
BOOTSEL键插USB进入U盘模式,固件格式为.uf2,拖入即完成刷入; - 版本匹配 :Pico和Pico W的固件不通用,需根据板子型号下载对应版本。
Thonny IDE 的官方下载地址是:**https://thonny.org/**。
各系统下载与安装方式
-
Windows
- 打开官网,点击 Download for Windows ,自动下载
.exe安装包。 - 双击安装,默认选项即可,推荐选择"为我安装"。
- 也可下载 Portable 便携版,解压即用。
- 打开官网,点击 Download for Windows ,自动下载
-
macOS
- 点击 Download for macOS ,下载
.dmg镜像。 - 打开后将 Thonny 拖入「应用程序」文件夹。
- 点击 Download for macOS ,下载
-
Linux(Ubuntu/Debian)
bashsudo apt update sudo apt install thonny或用 Flatpak/Snap 安装。
-
已有 Python 环境
bashpip install thonny
安装完成后,打开 Thonny,在右上角选择解释器为 MicroPython (Raspberry Pi Pico),即可连接 RP2040 开发板。
需要我帮你整理一份 Thonny 连接 RP2040 的完整配置步骤 吗?
RP2040(比如树莓派Pico)点亮LED是最基础也是最经典的入门实验,我会用MicroPython(最适合新手的方式)来一步步教你实现,整个过程简单易懂。
一、准备工作
- 硬件清单 :
- RP2040开发板(如Raspberry Pi Pico/Pico W)
- LED灯(任意颜色)
- 220Ω限流电阻(必须,防止烧坏LED)
- 杜邦线若干
- 面包板(可选,方便接线)
- 软件准备 :
- 给RP2040刷入MicroPython固件(官网可下载,按住BOOTSEL键插USB即可刷入)
- 编辑器(如Thonny IDE,新手首选,自带串口连接功能)
二、接线步骤(核心)
LED有正负极之分(长脚是正极/阳极,短脚是负极/阴极),接线逻辑如下:
- 将LED的正极通过220Ω电阻连接到RP2040的任意GPIO引脚(比如GPIO15,物理引脚20);
- 将LED的负极直接连接到RP2040的GND引脚(比如物理引脚23)。
简单记:
RP2040 GPIO15 → 220Ω电阻 → LED正极 → LED负极 → RP2040 GND
三、编写代码点亮LED
这里提供两种常见方式:常亮LED 和 闪烁LED(新手建议先试常亮)。
方式1:LED常亮
打开Thonny IDE,连接RP2040后,输入以下代码:
python
# 导入RP2040的MicroPython引脚控制模块
from machine import Pin
# 初始化GPIO15为输出模式,命名为led_pin
# Pin.OUT表示输出模式,Pin.IN是输入模式
led_pin = Pin(15, Pin.OUT)
# 设置引脚为高电平(3.3V),点亮LED
led_pin.value(1) # 也可以简写为 led_pin.on()
方式2:LED闪烁(更有趣)
python
from machine import Pin
import time # 导入时间模块,用于延时
# 初始化引脚
led_pin = Pin(15, Pin.OUT)
# 无限循环闪烁
while True:
led_pin.on() # 点亮LED
time.sleep(1) # 延时1秒
led_pin.off() # 熄灭LED
time.sleep(1) # 延时1秒
四、运行代码
- 在Thonny中点击「运行」按钮(▶️),代码会直接运行,此时LED会按预期常亮/闪烁;
- 如果想让开发板上电自动运行,将代码保存到RP2040中,文件名改为
main.py即可。
五、关键代码解释
from machine import Pin:导入RP2040的硬件引脚控制模块,是操作GPIO的核心;Pin(15, Pin.OUT):指定使用GPIO15引脚,设置为输出模式(输出高低电平控制LED);led_pin.on()/led_pin.value(1):将引脚置为高电平(3.3V),电流流过LED使其点亮;led_pin.off()/led_pin.value(0):将引脚置为低电平(0V),无电流,LED熄灭;time.sleep(1):暂停1秒,单位是秒(比如0.5就是500毫秒)。
总结
- 核心步骤:硬件接线(GPIO→电阻→LED正极,LED负极→GND)→ 初始化GPIO为输出模式 → 控制引脚高低电平点亮/熄灭LED;
- 关键注意:必须串联220Ω限流电阻,否则高电平会直接烧坏LED;GPIO引脚可任选(除少数特殊引脚外),代码中对应修改数字即可;
- 核心函数 :
Pin()初始化引脚、on()/off()控制电平、time.sleep()实现延时。
如果接线正确、代码无误,你就能看到RP2040成功控制LED点亮/闪烁了。


绝大多数 RP2040/Pico 板子自带一颗 LED,一般在 GPIO25(普通 Pico)或 GPIOWL(Pico W)。
c
from machine import Pin
import time
led = Pin(25, Pin.OUT)
while True:
led.toggle()
time.sleep(0.5)
我会从软件运行环境→代码解释执行→硬件底层交互三个核心层面,一步步拆解这段代码能让LED闪烁的完整逻辑,新手也能理解"代码如何操控硬件"的本质:
先明确核心前提
这段代码运行在 RP2040的MicroPython环境 中,而非普通电脑的Python环境。MicroPython是专门为微控制器定制的Python解释器,核心能力是"把Python代码翻译成硬件能执行的底层指令"。
一、运行环境层面:MicroPython在RP2040上的工作逻辑
- RP2040的硬件基础 :
RP2040是双核ARM Cortex-M0+微控制器,本身不认识Python代码,但刷入的MicroPython固件包含:- Python解释器(把Python代码翻译成机器码);
- 硬件抽象层(HAL):封装了操控GPIO、定时器等硬件的底层函数;
- 运行时环境:管理内存、中断、外设资源。
- 代码的加载与执行流程 :
当你在Thonny中点击运行,代码会通过USB串口传输到RP2040的RAM中 → MicroPython解释器逐行解析执行 → 最终调用硬件驱动操控GPIO引脚电平变化 → 驱动LED闪烁。
二、代码逐行解释执行(从语法到硬件调用)
python
# 1. 导入硬件控制模块
from machine import Pin
machine是MicroPython内置的"硬件控制核心模块",专门用于操控微控制器的外设(GPIO、ADC、I2C等);Pin是machine模块下的GPIO引脚类,封装了初始化引脚、设置电平、读取电平的所有方法;- 这行代码的本质:把操控GPIO的底层函数"暴露"给Python代码,让你能用简单的Python语法调用硬件功能。
python
# 2. 导入时间模块
import time
time模块是MicroPython适配的时间控制模块,time.sleep()会调用RP2040的定时器/延时函数;- 区别于电脑Python的
time:这里的sleep是"硬件级延时",不会占用CPU全部资源(底层通过定时器中断实现)。
python
# 3. 初始化GPIO25为输出模式
led = Pin(25, Pin.OUT)
这是核心硬件初始化步骤,拆解为3层逻辑:
-
语法层面:创建
Pin类的实例led,传入两个参数:25:指定操控的是RP2040的GPIO25引脚(板载LED的正极连接到此引脚);Pin.OUT:将该引脚设置为输出模式(GPIO有输入/输出两种核心模式,输出模式可主动输出高低电平)。
-
解释器层面:MicroPython把
Pin(25, Pin.OUT)翻译成底层函数调用:c// 底层C语言等价逻辑(MicroPython内部实现) gpio_init(25); // 初始化GPIO25的寄存器 gpio_set_dir(25, GPIO_OUT); // 设置引脚方向为输出 -
硬件层面:RP2040的GPIO寄存器被配置:
GPIO_CTRL_REG[25](引脚控制寄存器):设置为输出模式;GPIO_OUT_REG(输出电平寄存器):初始电平为低(0V),此时板载LED不亮。
python
# 4. 无限循环实现闪烁
while True:
led.toggle()
time.sleep(0.5)
(1)while True: 无限循环
- Python语法层面:创建一个永不终止的循环(除非手动停止代码);
- 硬件层面:MicroPython解释器会持续执行循环内的代码,直到收到"停止"指令(如Thonny的停止按钮)。
(2)led.toggle() 翻转引脚电平
- 语法层面:调用
Pin实例的toggle()方法("翻转"电平); - 解释器层面:翻译为底层函数
gpio_toggle(25); - 硬件层面:
- 每次调用
toggle(),RP2040的GPIO_OUT_REG[25]寄存器值会翻转:- 初始电平:0(低电平,0V)→ 翻转后变为1(高电平,3.3V)→ LED点亮;
- 下一次调用:1→0 → LED熄灭;
- 板载LED的电路逻辑:GPIO25 → LED正极 → LED负极 → GND(地,0V),当GPIO25输出高电平时,形成3.3V→LED→GND的电流回路,LED发光;低电平时无电流,LED熄灭。
- 每次调用
(3)time.sleep(0.5) 延时0.5秒
- 语法层面:暂停代码执行0.5秒;
- 解释器层面:调用底层
sleep_ms(500)函数(毫秒级延时); - 硬件层面:
- RP2040的定时器模块(SysTick)会设置一个500ms的计时中断;
- 计时期间,CPU可进入低功耗模式(不占用资源),直到中断触发,代码继续执行;
- 延时的作用:让LED保持"亮/灭"状态0.5秒,形成肉眼可见的闪烁(无延时的话翻转太快,肉眼看不到闪烁)。
三、底层硬件电路层面:电如何让LED闪烁
1. 板载LED的电路结构(RP2040 Pico为例)
RP2040芯片 → GPIO25引脚 → 限流电阻(约1kΩ) → LED正极 → LED负极 → GND(地)
- 限流电阻:出厂自带,无需外接,作用是限制电流(RP2040 GPIO输出电流最大约12mA,电阻可将电流控制在3mA左右,保护LED和GPIO);
- LED的特性:单向导电,只有当正极电压高于负极(GPIO25高电平,GND低电平)时,电流才会流过LED的PN结,电子跃迁释放光子 → 发光。
2. 电平变化与LED状态的对应关系
| GPIO25寄存器值 | 引脚电平 | 电流状态 | LED状态 |
|---|---|---|---|
| 1 | 高电平(3.3V) | 有电流(3mA左右) | 亮 |
| 0 | 低电平(0V) | 无电流 | 灭 |
3. 完整的硬件执行链路
代码循环 → toggle() → GPIO25寄存器值翻转 → 引脚电平变化 → 电流回路通/断 → LED亮/灭 → 延时0.5秒 → 重复循环 → 视觉上的"闪烁"。
总结
- 环境核心:MicroPython是"桥梁",将Python代码翻译成RP2040能执行的硬件指令,普通Python无此硬件操控能力;
- 代码核心 :
Pin(25, Pin.OUT)初始化输出引脚,toggle()翻转电平控制电流,sleep()控制闪烁频率; - 硬件核心:LED的单向导电特性+GPIO电平变化,形成通/断的电流回路,最终实现闪烁。
简单来说:代码操控的是"GPIO引脚的电压高低",电压高低决定"LED有没有电流流过",电流流过就发光,没电流就熄灭,配合延时就成了闪烁。
c
from machine import Pin
import time
import sys
class DHT11:
def __init__(self, pin):
# 关键修改:启用内部上拉电阻(Pin.PULL_UP)
self.pin = Pin(pin, Pin.OUT, Pin.PULL_UP) # 新增 Pin.PULL_UP
self.temperature = 0
self.humidity = 0
# 以下读取逻辑完全不变(无需修改)
def read(self):
self.pin.value(0)
time.sleep_ms(20)
self.pin.value(1)
time.sleep_us(40)
self.pin.init(Pin.IN, Pin.PULL_UP) # 输入模式也保持上拉
time.sleep_us(80)
if not self.pin.value():
time.sleep_us(80)
data = []
for _ in range(40):
while not self.pin.value():
pass
start = time.ticks_us()
while self.pin.value():
pass
end = time.ticks_us()
data.append(1 if (end - start) > 50 else 0)
if len(data) == 40:
bytes_data = []
for i in range(0, 40, 8):
byte = 0
for j in range(8):
byte = (byte << 1) | data[i+j]
bytes_data.append(byte)
if sum(bytes_data[:4]) & 0xFF == bytes_data[4]:
self.humidity = bytes_data[0]
self.temperature = bytes_data[2]
return True
return False
# 初始化DHT11(DATA接GPIO15,内部上拉已启用)
dht11 = DHT11(15)
# 主循环不变
print("DHT11数据读取中(使用内部上拉)...")
while True:
if dht11.read():
data_str = f"温度:{dht11.temperature}℃,湿度:{dht11.humidity}%\n"
sys.stdout.write(data_str)
else:
sys.stdout.write("读取失败,检查接线!\n")
time.sleep(1)
我会逐行拆解这份基于 RP2040(MicroPython)的 DHT11 驱动代码,从类定义、引脚初始化、通信协议、数据解析到主循环,每个细节都讲清楚,帮你彻底理解 DHT11 的工作逻辑。
整体功能总结
这段代码实现了 DHT11 温湿度传感器 在 RP2040 上的驱动,核心是模拟 DHT11 的单总线通信协议,读取温湿度数据并校验,最终循环输出结果;关键优化是启用了 GPIO 内部上拉电阻,解决了接线不稳定导致的读取失败问题。
逐行代码解读
1. 导入核心模块
python
from machine import Pin
import time
import sys
from machine import Pin:导入 RP2040 硬件引脚控制模块(MicroPython 标准库),用于配置 GPIO 输入/输出、上拉/下拉等。import time:导入时间模块,用于精准的毫秒/微秒级延时(DHT11 通信对时序要求极高)。import sys:导入系统模块,这里主要用sys.stdout.write()替代print(),输出更稳定(避免缓冲区问题)。
2. 定义 DHT11 类(核心驱动)
python
class DHT11:
def __init__(self, pin):
# 关键修改:启用内部上拉电阻(Pin.PULL_UP)
self.pin = Pin(pin, Pin.OUT, Pin.PULL_UP) # 新增 Pin.PULL_UP
self.temperature = 0
self.humidity = 0
class DHT11::定义 DHT11 传感器的驱动类,封装所有操作逻辑。def __init__(self, pin)::类的初始化方法,pin是传入的 GPIO 引脚号(比如 15)。self.pin = Pin(pin, Pin.OUT, Pin.PULL_UP):Pin.OUT:初始将引脚设为输出模式(DHT11 通信由主机主动发起,先拉低引脚触发传感器)。Pin.PULL_UP:启用 GPIO 内部上拉电阻(核心优化)------ DHT11 单总线无通信时需要高电平,外部不上拉的话引脚电平会飘,导致读取失败;内部上拉可省掉外部上拉电阻,同时保证电平稳定。
self.temperature = 0/self.humidity = 0:初始化温度、湿度属性,默认值为 0。
3. 核心方法:read()(读取传感器数据)
python
def read(self):
# 步骤1:主机发送起始信号(拉低引脚 20ms)
self.pin.value(0) # 引脚拉低,告诉 DHT11 "准备接收数据"
time.sleep_ms(20) # 拉低至少 18ms(DHT11 协议要求)
self.pin.value(1) # 释放引脚(拉回高电平)
time.sleep_us(40) # 保持高电平 40μs,等待传感器响应
# 步骤2:切换引脚为输入模式,接收传感器的响应信号
self.pin.init(Pin.IN, Pin.PULL_UP) # 改为输入模式,仍保持上拉
time.sleep_us(80) # 等待传感器拉低引脚(响应信号)
# 步骤3:检查传感器是否响应
if not self.pin.value(): # 如果引脚被拉低(传感器响应了)
time.sleep_us(80) # 传感器拉低 80μs 后会拉回高电平,等待这个过程
data = [] # 存储 40 位原始二进制数据
# 步骤4:读取 40 位数据(DHT11 输出 40 位:湿度整数+湿度小数+温度整数+温度小数+校验位)
for _ in range(40):
# 等待引脚从低电平变为高电平(数据位起始)
while not self.pin.value():
pass
# 记录高电平起始时间
start = time.ticks_us()
# 等待引脚从高电平变回低电平(数据位结束)
while self.pin.value():
pass
# 记录高电平结束时间
end = time.ticks_us()
# 判断数据位:高电平持续 >50μs 是 1,否则是 0(DHT11 协议定义)
data.append(1 if (end - start) > 50 else 0)
# 步骤5:校验并解析数据
if len(data) == 40: # 确保读取到完整的 40 位
bytes_data = [] # 把 40 位拆成 5 个字节(8位/字节)
for i in range(0, 40, 8):
byte = 0
for j in range(8):
# 逐位拼接成字节(高位在前)
byte = (byte << 1) | data[i+j]
bytes_data.append(byte)
# 校验位验证:前4字节的和(取低8位)等于第5字节
if sum(bytes_data[:4]) & 0xFF == bytes_data[4]:
# 解析数据:bytes_data[0] = 湿度整数,bytes_data[2] = 温度整数
# DHT11 小数位固定为 0,所以只取整数部分
self.humidity = bytes_data[0]
self.temperature = bytes_data[2]
return True # 读取成功,返回 True
# 任何步骤失败(无响应、数据不全、校验失败),返回 False
return False
关键细节说明:
- DHT11 通信时序:主机拉低 20ms → 释放 40μs → 传感器拉低 80μs → 拉高 80μs → 输出 40 位数据。
- 数据格式:40 位 = 湿度整数(8位) + 湿度小数(8位) + 温度整数(8位) + 温度小数(8位) + 校验位(8位)。
- 校验逻辑:
sum(前4字节) & 0xFF == 校验位,确保数据没传错。
4. 初始化传感器并主循环
python
# 初始化DHT11(DATA接GPIO15,内部上拉已启用)
dht11 = DHT11(15)
# 主循环不变
print("DHT11数据读取中(使用内部上拉)...")
while True:
if dht11.read():
# 读取成功,格式化输出温湿度
data_str = f"温度:{dht11.temperature}℃,湿度:{dht11.humidity}%\n"
sys.stdout.write(data_str)
else:
# 读取失败,提示检查接线
sys.stdout.write("读取失败,检查接线!\n")
time.sleep(1) # 每秒读取一次(DHT11 最快 1Hz 采样)
dht11 = DHT11(15):指定 DHT11 的 DATA 引脚接 RP2040 的 GPIO15。while True:无限循环,每秒读取一次数据;成功则输出温湿度,失败则提示接线问题。sys.stdout.write():比print()更适合持续输出,避免换行/缓冲区延迟问题。
总结
- 核心逻辑:通过模拟 DHT11 单总线通信时序,读取 40 位原始数据,校验后解析出温湿度。
- 关键优化 :初始化引脚时启用
Pin.PULL_UP内部上拉,解决 DHT11 总线电平飘移导致的读取失败问题。 - 时序要求 :DHT11 对微秒级延时敏感,必须用
time.sleep_us()/time.ticks_us()保证精准度,否则数据会出错。
如果运行时仍出现"读取失败",优先检查:① 引脚接线是否正确(DATA 接 GPIO15,VCC 接 3.3V,GND 接地);② 传感器是否正常(DHT11 需接 3.3V/5V,不能反接);③ 延时参数是否被修改(时序错会导致数据解析失败)。