树莓派 RP2040 学习笔记1

你需要的RP2040 MicroPython固件官方下载地址和详细刷入步骤我都整理好了,新手也能轻松操作:

一、官方下载地址

  1. 核心官网(树莓派基金会)

    最权威的固件下载页:https://www.raspberrypi.com/documentation/microcontrollers/micropython.html#drag-and-drop-micropython

    这个页面不仅能下载固件,还包含完整的MicroPython使用文档。

  2. 固件直链(懒人版)

    直接下载最新稳定版Pico/Pico W固件(根据你的板子选择):

二、完整刷入固件步骤(补充细节,避免踩坑)

  1. 进入BOOTSEL模式

    • 按住RP2040开发板上的 BOOTSEL 按键(唯一的按键)不松手;
    • 将USB线(建议用数据线,而非充电线)插入开发板的USB口,另一端连接电脑;
    • 电脑识别到后(会弹出一个名为 RPI-RP2 的U盘),再松开 BOOTSEL 键。
  2. 刷入固件

    • 打开 RPI-RP2 这个U盘(Windows/ macOS/ Linux都能识别);
    • 将下载好的 .uf2 格式固件文件直接拖入这个U盘;
    • 拖入后,U盘会自动断开,开发板重启,MicroPython固件就刷入完成了。

三、验证是否刷入成功

  1. 打开Thonny IDE(新手首选);
  2. 点击Thonny右上角的「解释器」选择框,选择「MicroPython (Raspberry Pi Pico)」;
  3. 点击「确定」,如果能看到串口连接成功的提示,且左下角显示「Python 3.xx.xx (MicroPython)」,说明固件刷入成功。

总结

  1. 核心官网 :树莓派官方文档页 https://www.raspberrypi.com/documentation/microcontrollers/micropython.html 是最权威的入口,包含固件下载和所有使用说明;
  2. 刷入关键 :必须按住 BOOTSEL 键插USB进入U盘模式,固件格式为 .uf2,拖入即完成刷入;
  3. 版本匹配 :Pico和Pico W的固件不通用,需根据板子型号下载对应版本。
    Thonny IDE 的官方下载地址是:**https://thonny.org/**。

各系统下载与安装方式

  • Windows

    1. 打开官网,点击 Download for Windows ,自动下载 .exe 安装包。
    2. 双击安装,默认选项即可,推荐选择"为我安装"。
    3. 也可下载 Portable 便携版,解压即用。
  • macOS

    1. 点击 Download for macOS ,下载 .dmg 镜像。
    2. 打开后将 Thonny 拖入「应用程序」文件夹。
  • Linux(Ubuntu/Debian)

    bash 复制代码
    sudo apt update
    sudo apt install thonny

    或用 Flatpak/Snap 安装。

  • 已有 Python 环境

    bash 复制代码
    pip install thonny

安装完成后,打开 Thonny,在右上角选择解释器为 MicroPython (Raspberry Pi Pico),即可连接 RP2040 开发板。

需要我帮你整理一份 Thonny 连接 RP2040 的完整配置步骤 吗?

RP2040(比如树莓派Pico)点亮LED是最基础也是最经典的入门实验,我会用MicroPython(最适合新手的方式)来一步步教你实现,整个过程简单易懂。

一、准备工作

  1. 硬件清单
    • RP2040开发板(如Raspberry Pi Pico/Pico W)
    • LED灯(任意颜色)
    • 220Ω限流电阻(必须,防止烧坏LED)
    • 杜邦线若干
    • 面包板(可选,方便接线)
  2. 软件准备
    • 给RP2040刷入MicroPython固件(官网可下载,按住BOOTSEL键插USB即可刷入)
    • 编辑器(如Thonny IDE,新手首选,自带串口连接功能)

二、接线步骤(核心)

LED有正负极之分(长脚是正极/阳极,短脚是负极/阴极),接线逻辑如下:

  1. 将LED的正极通过220Ω电阻连接到RP2040的任意GPIO引脚(比如GPIO15,物理引脚20);
  2. 将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秒

四、运行代码

  1. 在Thonny中点击「运行」按钮(▶️),代码会直接运行,此时LED会按预期常亮/闪烁;
  2. 如果想让开发板上电自动运行,将代码保存到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毫秒)。

总结

  1. 核心步骤:硬件接线(GPIO→电阻→LED正极,LED负极→GND)→ 初始化GPIO为输出模式 → 控制引脚高低电平点亮/熄灭LED;
  2. 关键注意:必须串联220Ω限流电阻,否则高电平会直接烧坏LED;GPIO引脚可任选(除少数特殊引脚外),代码中对应修改数字即可;
  3. 核心函数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上的工作逻辑

  1. RP2040的硬件基础
    RP2040是双核ARM Cortex-M0+微控制器,本身不认识Python代码,但刷入的MicroPython固件包含:
    • Python解释器(把Python代码翻译成机器码);
    • 硬件抽象层(HAL):封装了操控GPIO、定时器等硬件的底层函数;
    • 运行时环境:管理内存、中断、外设资源。
  2. 代码的加载与执行流程
    当你在Thonny中点击运行,代码会通过USB串口传输到RP2040的RAM中 → MicroPython解释器逐行解析执行 → 最终调用硬件驱动操控GPIO引脚电平变化 → 驱动LED闪烁。

二、代码逐行解释执行(从语法到硬件调用)

python 复制代码
# 1. 导入硬件控制模块
from machine import Pin
  • machine是MicroPython内置的"硬件控制核心模块",专门用于操控微控制器的外设(GPIO、ADC、I2C等);
  • Pinmachine模块下的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秒 → 重复循环 → 视觉上的"闪烁"。


总结

  1. 环境核心:MicroPython是"桥梁",将Python代码翻译成RP2040能执行的硬件指令,普通Python无此硬件操控能力;
  2. 代码核心Pin(25, Pin.OUT)初始化输出引脚,toggle()翻转电平控制电流,sleep()控制闪烁频率;
  3. 硬件核心: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() 更适合持续输出,避免换行/缓冲区延迟问题。

总结

  1. 核心逻辑:通过模拟 DHT11 单总线通信时序,读取 40 位原始数据,校验后解析出温湿度。
  2. 关键优化 :初始化引脚时启用 Pin.PULL_UP 内部上拉,解决 DHT11 总线电平飘移导致的读取失败问题。
  3. 时序要求 :DHT11 对微秒级延时敏感,必须用 time.sleep_us()/time.ticks_us() 保证精准度,否则数据会出错。

如果运行时仍出现"读取失败",优先检查:① 引脚接线是否正确(DATA 接 GPIO15,VCC 接 3.3V,GND 接地);② 传感器是否正常(DHT11 需接 3.3V/5V,不能反接);③ 延时参数是否被修改(时序错会导致数据解析失败)。

相关推荐
_下雨天.1 小时前
Linux系统安全学习
linux·学习·系统安全
ouliten1 小时前
[CUTLASS笔记2]host端工具类
c++·笔记·cuda·cutlass
我命由我123451 小时前
Git 创建新分支并推送到远程仓库
java·服务器·git·后端·学习·java-ee·学习方法
Cathy Bryant1 小时前
线性代数直觉(六):向量通过矩阵
人工智能·笔记·线性代数·机器学习·矩阵
结网的兔子2 小时前
前端学习笔记(实战准备篇)——用vite构建一个项目【吐血整理】
前端·学习·elementui·npm·node.js·vue
Larry_Yanan2 小时前
QML学习笔记(六十四)动画相关:State状态、Transition过渡和Gradient渐变
开发语言·c++·笔记·qt·学习
ADHD多动联盟2 小时前
注意力缺陷是什么?主要有哪些应对策略和干预方法?
学习·学习方法·玩游戏
hsg772 小时前
简述:openclaw应用二三事
人工智能·学习