树莓派 GPIO 入门到实践

硬件环境: Raspberry Pi 4 Model B Rev 1.5 · Debian 12 Bookworm · 内核 6.12.25
测试日期: 2026 年 4 月
作者: zeruns (https://blog.zeruns.com/)
本文由AI编写的,仅供参考(Hermes Agent + DeepSeek V4 Flash)


目录

  1. GPIO 基础概念
  2. 环境准备与工具
  3. GPIO 输入输出(Shell 方式)
  4. GPIO 输入输出(Python 方式)
  5. I2C 通信
  6. SPI 通信
  7. 综合实例
  8. 注意事项与排错

1. GPIO 基础概念

1.1 什么是 GPIO

GPIO(General Purpose Input/Output,通用输入输出)是微处理器上的一组可编程引脚。通过软件控制,你可以将每个引脚设置为:

  • 输出模式:输出高电平(3.3V)或低电平(0V),用于控制 LED、继电器、蜂鸣器等
  • 输入模式:读取外部电平状态(高/低),用于读取按钮、传感器信号
  • 复用功能:I2C、SPI、UART、PWM 等专用通信协议

1.2 树莓派 4B 引脚排列

树莓派 4B 采用 40 Pin 扩展排针,引脚编号有三种方式:

编号方式 说明 典型库
物理引脚(Board) 从 1 到 40,左上为 1 RPi.GPIO setmode(GPIO.BOARD)
BCM 编号(Broadcom) 芯片 GPIO 编号,如 GPIO17 RPi.GPIO setmode(GPIO.BCM)、libgpiod
wiringPi 编号 wiringPi 自定义编号(已废弃) wiringPi 库

40 Pin 引脚功能表

                    ┌─────────────────────────────┐
                    │  🥝 树莓派 4B 40Pin 引脚图   │
  3.3V  (01) ──●  ●── (02)  5V                    │
 GPIO2  (03) ──●  ●── (04)  5V                    │
 GPIO3  (05) ──●  ●── (06)  GND                   │
 GPIO4  (07) ──●  ●── (08)  GPIO14 (UART TX)      │
   GND  (09) ──●  ●── (10)  GPIO15 (UART RX)      │
GPIO17  (11) ──●  ●── (12)  GPIO18 (PWM0)         │
GPIO27  (13) ──●  ●── (14)  GND                   │
GPIO22  (15) ──●  ●── (16)  GPIO23                │
  3.3V  (17) ──●  ●── (18)  GPIO24                │
GPIO10 (19) ──●  ●── (20)  GND  (SPI_MOSI)        │
 GPIO9 (21) ──●  ●── (22)  GPIO25 (SPI_MISO)      │
GPIO11 (23) ──●  ●── (24)  GPIO8  (SPI_SCLK)      │
   GND (25) ──●  ●── (26)  GPIO7  (SPI_CE0)       │
 GPIO0 (27) ──●  ●── (28)  GPIO1  (ID_SDA / I2C)  │
 GPIO5 (29) ──●  ●── (30)  GND                    │
 GPIO6 (31) ──●  ●── (32)  GPIO12 (PWM0)          │
GPIO13 (33) ──●  ●── (34)  GND                    │
GPIO19 (35) ──●  ●── (36)  GPIO16                 │
GPIO26 (37) ──●  ●── (38)  GPIO20                 │
   GND (39) ──●  ●── (40)  GPIO21                 │
                    └─────────────────────────────┘

树莓派 4B 主要引脚功能表

物理引脚 BCM 编号 功能 物理引脚 BCM 编号 功能
1 3.3V 2 5V
3 GPIO2 I2C1 SDA 4 5V
5 GPIO3 I2C1 SCL 6 GND
7 GPIO4 8 GPIO14 UART TX
9 GND 10 GPIO15 UART RX
11 GPIO17 12 GPIO18 PCM_CLK / PWM0
13 GPIO27 14 GND
15 GPIO22 16 GPIO23
17 3.3V 18 GPIO24
19 GPIO10 SPI0 MOSI 20 GND
21 GPIO9 SPI0 MISO 22 GPIO25
23 GPIO11 SPI0 SCLK 24 GPIO8 SPI0 CE0
25 GND 26 GPIO7 SPI0 CE1
27 GPIO0 ID_SDA (EEPROM) 28 GPIO1 ID_SCL (EEPROM)
29 GPIO5 30 GND
31 GPIO6 32 GPIO12 PWM0
33 GPIO13 PWM1 34 GND
35 GPIO19 PCM_FS / PWM1 36 GPIO16
37 GPIO26 38 GPIO20 PCM_DIN
39 GND 40 GPIO21 PCM_DOUT

1.3 重要说明

  • 逻辑电平: 树莓派 GPIO 是 3.3V 逻辑,不能直接接 5V 信号
  • 电流限制: 每个 GPIO 最大输出约 16mA,所有引脚合计不超过 50mA
  • 默认状态: 大部分 GPIO 默认是输入模式,部分有内部上拉/下拉
  • 3.3V 引脚(01/17): 最大输出电流约 500mA
  • 5V 引脚(02/04): 直接从 USB-C 供电取电,电流取决于电源适配器

2. 环境准备与工具

2.1 已安装的工具清单

本教程基于 Debian 12 Bookworm 系统进行测试,以下工具已预装:

工具/库 版本 用途
libgpiod / gpioset / gpioget 1.6.3 Shell 方式控制 GPIO
python3-libgpiod 1.6.3 Python libgpiod 绑定
RPi.GPIO 0.7.2 经典 Python GPIO 库
smbus2 已安装 Python I2C 通信
spidev 已安装 Python SPI 通信
pigpiod 1.79 GPIO 守护进程(PWM/远程控制)
i2c-tools 4.3 I2C 设备扫描工具

2.2 安装所需工具

如果某些工具未安装,可以按以下命令安装:

# 基础 GPIO 工具
sudo apt install gpiod libgpiod-dev python3-libgpiod

# I2C 工具
sudo apt install i2c-tools

# Python 库
pip install RPi.GPIO smbus2 spidev gpiozero

# pigpio 守护进程(硬件 PWM,推荐)
sudo apt install pigpio pigpiod
sudo systemctl enable pigpiod --now

2.3 开启 I2C / SPI 接口

使用 raspi-config 开启:

sudo raspi-config

菜单路径:
Interface OptionsI2CEnableYes
Interface OptionsSPIEnableYes

或者在终端直接编辑 /boot/firmware/config.txt(Debian 12):

# 手动添加
sudo tee -a /boot/firmware/config.txt <<EOF
dtparam=i2c_arm=on
dtparam=spi=on
EOF

# 重启生效
sudo reboot

验证开启成功:

# 检查 I2C
ls /dev/i2c*
# 输出: /dev/i2c-20  /dev/i2c-21

# 检查 SPI(开启后)
ls /dev/spi*
# 输出: /dev/spidev0.0  /dev/spidev0.1

2.4 查看所有 gpiochip

$ gpioinfo
gpiochip0 - 58 lines:
        line   0:     "ID_SDA"       unused   input  active-high
        line   1:     "ID_SCL"       unused   input  active-high
        line   2:      "GPIO2"       unused   input  active-high
        ...

树莓派 4B 的 BCM2711 芯片提供一个 gpiochip0,共 58 个 GPIO,但只有 GPIO0-GPIO27 通过 40Pin 排针引出。


3. GPIO 输入输出(Shell 方式)

3.1 libgpiod 工具包

推荐使用 libgpiod 的工具,它不依赖 wiringPi,是当今主流方案。

主要命令:

命令 功能 示例
gpioinfo 查看所有 GPIO 状态 gpioinfo
gpioset 设置 GPIO 输出电平 gpioset 0 17=1
gpioget 读取 GPIO 输入电平 gpioget 0 17
gpiomon 监听 GPIO 事件 gpiomon 0 17

格式说明: gpioset <chip> <pin>=<value>
chip 通常为 0(gpiochip0),pin 为 BCM 编号

3.2 输出:点亮 LED

将 LED 正极(长脚)通过 330Ω 电阻 连接到 GPIO17(物理引脚 11),负极(短脚)连接到 GND(物理引脚 9)。

# 设置 GPIO17 输出高电平 → LED 点亮
gpioset 0 17=1

# 设置 GPIO17 输出低电平 → LED 熄灭
gpioset 0 17=0

3.3 输入:读取按键状态

将按键一端接 GPIO18(物理引脚 12),另一端接 GND(物理引脚 14)。

# 读取 GPIO18 电平(需外部上拉或启用内部上拉)
gpioget 0 18
# 输出: 1 (未按下,高电平)
# 输出: 0 (按下,低电平)

3.4 查看所有引脚状态

# 查看全部引脚
gpioinfo

# 查看特定引脚(BCM 编号 17)
gpioinfo | grep "GPIO17"
# 输出: line  17:      "GPIO17"       "myapp"   output  active-high

3.5 gpioset 设置上拉/下拉

libgpiod 1.6 支持在请求时设置偏置:

# 设置 GPIO17 为输出,初始高电平,带上拉
gpioset --bias=enable 0 17=1

4. GPIO 输入输出(Python 方式)

4.1 使用 RPi.GPIO(经典库)

RPi.GPIO 是最常用的 Python GPIO 库,简单直观。

4.1.1 输出:LED 闪烁

import RPi.GPIO as GPIO
import time

# 使用 BCM 编号方式
GPIO.setmode(GPIO.BCM)

# 设置 GPIO17 为输出
GPIO.setup(17, GPIO.OUT)

# LED 闪烁 5 次
for _ in range(5):
    GPIO.output(17, GPIO.HIGH)  # 点亮
    time.sleep(0.5)
    GPIO.output(17, GPIO.LOW)   # 熄灭
    time.sleep(0.5)

# 清理资源
GPIO.cleanup()

4.1.2 输入:读取按键

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

# GPIO18 为输入,启用内部上拉电阻
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)

try:
    while True:
        if GPIO.input(18) == GPIO.LOW:
            print("按钮按下")
        else:
            print("按钮松开")
        time.sleep(0.1)
except KeyboardInterrupt:
    GPIO.cleanup()

GPIO.PUD_UP = 内部上拉(默认高电平,按下变低)
GPIO.PUD_DOWN = 内部下拉(默认低电平,按下变高)

4.1.3 PWM 输出:呼吸灯

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)  # GPIO18 支持硬件 PWM

pwm = GPIO.PWM(18, 1000)  # 频率 1kHz
pwm.start(0)  # 初始占空比 0%

try:
    while True:
        # 渐亮
        for duty in range(0, 101, 5):
            pwm.ChangeDutyCycle(duty)
            time.sleep(0.05)
        # 渐暗
        for duty in range(100, -1, -5):
            pwm.ChangeDutyCycle(duty)
            time.sleep(0.05)
except KeyboardInterrupt:
    pwm.stop()
    GPIO.cleanup()

4.1.4 事件检测:中断方式读取按键

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)

def button_callback(channel):
    print(f"按钮按下!(引脚 {channel})")

# 下降沿触发中断
GPIO.add_event_detect(18, GPIO.FALLING,
                      callback=button_callback,
                      bouncetime=200)

try:
    print("等待按钮按下...")
    time.sleep(60)
except KeyboardInterrupt:
    GPIO.cleanup()

4.2 使用 gpiozero(高级封装)

gpiozero 提供了更高级的面向对象封装,适合快速开发:

# 安装
pip install gpiozero
from gpiozero import LED, Button, Buzzer
from signal import pause

# LED:自动闪烁
led = LED(17)
led.blink()

# 按钮:按下时点亮 LED
btn = Button(18, pull_up=True)

# 方法 1:直接赋值
btn.when_pressed = led.on
btn.when_released = led.off

# 方法 2:自定义回调
btn.when_pressed = lambda: print("按下!")

# 保持运行
pause()

gpiozero 内置的组件:

组件 类名 说明
LED LED(pin) 控制 LED 开关/闪烁/呼吸
按钮 Button(pin, pull_up=True) 读取按键、长按检测
蜂鸣器 Buzzer(pin) 有源蜂鸣器控制
距离传感器 DistanceSensor(echo, trigger) HC-SR04 超声波
舵机 Servo(pin) 舵机角度控制
电机 Motor(forward, backward) 直流电机控制

4.3 使用 libgpiod Python 绑定(底层操作)

import gpiod
import time

# 打开 gpiochip0
chip = gpiod.Chip('gpiochip0')

# 获取 GPIO17 并请求为输出
line = chip.get_line(17)
line.request(consumer='myapp', type=gpiod.LINE_REQ_DIR_OUT)

# 输出高电平
line.set_value(1)
time.sleep(1)

# 输出低电平
line.set_value(0)

# 释放
line.release()

输入模式:

import gpiod

chip = gpiod.Chip('gpiochip0')
line = chip.get_line(18)

# 请求为输入,内部上拉
line.request(consumer='myapp',
             type=gpiod.LINE_REQ_DIR_IN,
             flags=gpiod.LINE_REQ_FLAG_BIAS_PULL_UP)

value = line.get_value()  # 0 或 1
print(f"GPIO18 = {value}")

line.release()

5. I2C 通信

5.1 I2C 基本原理

I2C(Inter-Integrated Circuit)是一种串行通信总线,使用两条线:

信号 引脚 功能
SCL GPIO3 (物理引脚 5) 时钟线
SDA GPIO2 (物理引脚 3) 数据线

特点:

  • 主从架构:树莓派是主机(Master),传感器等是从机(Slave)
  • 7位地址:每个从机有唯一地址(如 0x44)
  • 多设备共享:一条 I2C 总线上可挂接多个设备
  • 速率:标准 100kHz,快速 400kHz

5.2 查看 I2C 总线

# 查看 I2C 总线列表
$ i2cdetect -l
i2c-20  i2c        bcm2711_i2c1                   I2C adapter
i2c-21  i2c        bcm2711_i2c0                   I2C adapter
  • i2c-20:对应物理引脚 3(SDA)/5(SCL) — 主 I2C 总线
  • i2c-21:对应 ID_EEPROM(引脚 27/28),一般不接外部设备

5.3 扫描 I2C 设备

# 扫描 i2c-20 上的设备
$ i2cdetect -y 20
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- 44 -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

地址 0x44 处有一个设备 — 这就是 SHT30 温湿度传感器(I2C 地址 0x44)。

如果没看到任何设备(全是 --),说明总线上没有挂载设备。

5.4 使用 smbus2 读写 I2C

smbus2 是最常用的 Python I2C 库。

5.4.1 读取 SHT30 温湿度传感器

import smbus2
import time

# SHT30 I2C 地址
SHT30_ADDR = 0x44

# 打开 I2C 总线 20
bus = smbus2.SMBus(20)

# 发送测量命令:高精度模式
bus.write_i2c_block_data(SHT30_ADDR, 0x2C, [0x06])

time.sleep(0.015)  # 等待测量完成(15ms)

# 读取 6 字节数据
data = bus.read_i2c_block_data(SHT30_ADDR, 0x00, 6)

# 计算温度和湿度
temp_raw = ((data[0] << 8) | data[1])
temp = -45 + 175 * temp_raw / 65535.0

hum_raw = ((data[3] << 8) | data[4])
hum = 100 * hum_raw / 65535.0

print(f"温度: {temp:.2f}°C")
print(f"湿度: {hum:.2f}%")

5.4.2 封装为函数

import smbus2
import time

class SHT30:
    def __init__(self, bus_id=20, addr=0x44):
        self.bus = smbus2.SMBus(bus_id)
        self.addr = addr

    def read(self):
        """读取温湿度,返回 (温度°C, 湿度%)"""
        self.bus.write_i2c_block_data(self.addr, 0x2C, [0x06])
        time.sleep(0.015)
        data = self.bus.read_i2c_block_data(self.addr, 0x00, 6)

        temp_raw = (data[0] << 8) | data[1]
        temp = -45 + 175 * temp_raw / 65535.0

        hum_raw = (data[3] << 8) | data[4]
        hum = 100 * hum_raw / 65535.0

        return round(temp, 2), round(hum, 2)

# 使用
sensor = SHT30()
t, h = sensor.read()
print(f"{t}°C, {h}%RH")

5.4.3 通用 I2C 读写操作

import smbus2

bus = smbus2.SMBus(20)
addr = 0x44  # 设备 I2C 地址

# 写单个字节到寄存器
bus.write_byte_data(addr, 0x2C, 0x06)

# 读单字节
value = bus.read_byte_data(addr, 0x00)

# 读多字节
data = bus.read_i2c_block_data(addr, 0x00, 6)

# 写多字节
bus.write_i2c_block_data(addr, 0x2C, [0x06])

# 写一个字节(无寄存器地址)
bus.write_byte(addr, 0x06)

# 读一个字节(无寄存器地址)
value = bus.read_byte(addr)

bus.close()

5.5 使用 i2cget / i2cset 命令行

# 读取 SHT30 状态寄存器(1字节)
$ i2cget -y 20 0x44 0x00
0x65

# 读取 6 字节原始数据
$ i2cget -y 20 0x44 0x00 b 6

6. SPI 通信

6.1 SPI 基本原理

SPI(Serial Peripheral Interface)是一种全双工同步串行总线,使用四条线:

信号 树莓派引脚 功能
MOSI GPIO10 (物理引脚 19) 主机输出,从机输入
MISO GPIO9 (物理引脚 21) 主机输入,从机输出
SCLK GPIO11 (物理引脚 23) 时钟信号
CE0 GPIO8 (物理引脚 24) 片选 0
CE1 GPIO7 (物理引脚 26) 片选 1

特点:

  • 全双工:发送和接收同时进行
  • 主从:树莓派是主机,可挂接多个从机(每个从机一个片选)
  • 速率高:可达几十 MHz
  • 无设备地址:通过片选线选择从机

6.2 开启 SPI 并验证

# 开启 SPI(已开启后)
$ ls /dev/spi*
/dev/spidev0.0  /dev/spidev0.1
  • /dev/spidev0.0:SPI0 总线,CE0
  • /dev/spidev0.1:SPI0 总线,CE1

6.3 使用 spidev 读写 SPI

pip install spidev

6.3.1 读取 MCP3008 ADC(8通道 ADC)

import spidev

# 打开 SPI
spi = spidev.SpiDev()
spi.open(0, 0)  # 总线0,片选0

# 配置
spi.max_speed_hz = 1350000  # 1.35MHz
spi.mode = 0  # SPI 模式

def read_adc(channel):
    """读取 MCP3008 指定通道 (0-7)"""
    # 发送 3 字节:起始位 + 单端模式 + 通道号
    r = spi.xfer2([1, (8 + channel) << 4, 0])
    value = ((r[1] & 3) << 8) + r[2]
    return value

# 读取通道 0
adc_value = read_adc(0)
voltage = adc_value * 3.3 / 1023
print(f"ADC值: {adc_value}, 电压: {voltage:.3f}V")

spi.close()

6.3.2 通用 SPI 数据收发

import spidev

spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 500000
spi.mode = 0

# 发送并接收(全双工,发送0xFF同时读取)
data_out = [0xFF, 0x00, 0x55]
data_in = spi.xfer2(data_out)  # 发送3个字节,接收3个字节
print(f"发送: {[hex(x) for x in data_out]}")
print(f"接收: {[hex(x) for x in data_in]}")

# 只发送(忽略接收结果)
spi.writebytes([0x01, 0x02, 0x03])

spi.close()

7. 综合实例

7.1 实例1:LED 呼吸灯 + 按钮控制

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

LED_PIN = 17      # BCM 17
BTN_PIN = 18      # BCM 18

GPIO.setup(LED_PIN, GPIO.OUT)
GPIO.setup(BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)

pwm = GPIO.PWM(LED_PIN, 500)
pwm.start(0)

running = True  # LED 状态

try:
    while True:
        if GPIO.input(BTN_PIN) == GPIO.LOW:
            running = not running
            time.sleep(0.3)  # 去抖动

        if running:
            # 呼吸灯
            for duty in range(0, 101, 2):
                pwm.ChangeDutyCycle(duty)
                time.sleep(0.01)
            for duty in range(100, -1, -2):
                pwm.ChangeDutyCycle(duty)
                time.sleep(0.01)
        else:
            pwm.ChangeDutyCycle(0)

except KeyboardInterrupt:
    pwm.stop()
    GPIO.cleanup()

7.2 实例2:SHT30 温湿度读取 + 自动记录

import smbus2
import time
import csv
from datetime import datetime

class SHT30:
    def __init__(self, bus_id=20, addr=0x44):
        self.bus = smbus2.SMBus(bus_id)
        self.addr = addr

    def read(self):
        self.bus.write_i2c_block_data(self.addr, 0x2C, [0x06])
        time.sleep(0.015)
        data = self.bus.read_i2c_block_data(self.addr, 0x00, 6)
        t = -45 + 175 * ((data[0] << 8) | data[1]) / 65535.0
        h = 100 * ((data[3] << 8) | data[4]) / 65535.0
        return round(t, 2), round(h, 2)

sensor = SHT30()

# 测试读取
t, h = sensor.read()
print(f"[{datetime.now()}] 温度: {t}°C, 湿度: {h}%")

# 持续记录到 CSV(每分钟一次)
with open('sensor_log.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(['时间', '温度(C)', '湿度(%)'])
    for i in range(10):  # 记录10次
        t, h = sensor.read()
        now = datetime.now().strftime('%H:%M:%S')
        writer.writerow([now, t, h])
        print(f"[{now}] {t}°C, {h}%")
        time.sleep(60)

7.3 实例3:gpiozero 一键完成

from gpiozero import LED, Button
from signal import pause
import time

led = LED(17)
btn = Button(18, pull_up=True)

# 按下时点亮,松开熄灭
btn.when_pressed = led.on
btn.when_released = led.off

# 双击切换闪烁模式
press_count = 0

def double_click():
    global press_count
    press_count += 1
    time.sleep(0.3)
    if press_count == 2:
        led.blink()
        print("双击!LED 闪烁模式")
        press_count = 0

btn.when_pressed = double_click

pause()

8. 注意事项与排错

8.1 电平转换 (3.3V vs 5V)

:warning: 树莓派 GPIO 是 3.3V 逻辑,严禁直接连接 5V 设备!

场景 做法
5V 传感器输出 → 树莓派输入 使用 电平转换模块(如 TXS0108E)或 电阻分压
树莓派输出 → 5V 设备输入 部分 5V 设备可识别 3.3V 为高电平(如 WS2812B)
3.3V 传感器 → 树莓派 可直接连接 :white_check_mark:

电阻分压(5V → 3.3V):

    5V ──┬── R1 (1.8kΩ) ──┬── 树莓派 GPIO
         │                │
        GND ── R2 (3.3kΩ) ─┘

8.2 上拉/下拉电阻

  • 内部上拉:RPi.GPIO 用 pull_up_down=GPIO.PUD_UP
  • 内部下拉:RPi.GPIO 用 pull_up_down=GPIO.PUD_DOWN
  • libgpiod:gpiod.LINE_REQ_FLAG_BIAS_PULL_UP
  • 外部上拉:4.7kΩ ~ 10kΩ 电阻到 3.3V

8.3 电流限制

参数 限制
单个 GPIO 最大输出 16mA
所有 GPIO 总和 50mA
3.3V 引脚总电流 ~500mA
5V 引脚总电流 取决于电源

:light_bulb: 直接驱动 LED 时必须串联 220Ω ~ 330Ω 限流电阻!

8.4 常见错误

错误 原因 解决方法
RuntimeError: No access to /dev/mem 权限不足 sudo python3 script.py
RuntimeError: Pin already in use 引脚被其他程序占用 检查 /sys/class/gpio/,释放或重启
[Errno 13] Permission denied + i2c I2C 未开启或权限不足 将用户加入 i2c
Could not open /dev/spidev0.0 SPI 未开启 检查 /boot/config.txt
LED 接反不亮 正负极接反 LED 长脚接 GPIO,短脚接 GND
按键误触发 未做去抖动 代码加 bouncetime 或延时去抖

8.5 权限设置

# 将当前用户加入 i2c、gpio 组
sudo usermod -aG i2c,gpio $USER

# 重新登录生效
exec su - $USER

8.6 快速在线参考


作者: zeruns
本教程基于树莓派 4B + Debian 12 Bookworm 实测编写