🍓 第七章 GPIO 硬件接口
📄 一句话概括

前面六章你都在跟软件打交道;从这一节起,你开始跟电打交道。 板子边上那排 40 根针(GPIO)就是树莓派伸向外界的"手"——本节要把这排针看清楚:哪些是电源、哪些是地、哪些能自己控制,以及"第 11 针"到底该怎么说。

📝 本节和前面几节的关系

1-3 讲硬件规格时,只把 GPIO 作为"八类零件之一"点了一句(三类针 + 3.3V 铁律);本节把它摊开来讲透,因为后面五节全都在跟它打交道。 6-5 你学会了装库、6-6 你学会了处理列表;本节起,Python 的每一行代码都会直接变成一根针上的电压——这是本课最激动人心也最容易烧东西的地方。 还要用上 2-4 的 raspi-config:I2C、SPI、串口这些"复用功能"要先在那里打开,否则接上去也不认。

一、GPIO 是什么:能自己控制的一排针

GPIO = General Purpose Input/Output,通用输入输出。

拆开读就懂了:

"电平"就是电压高低。在这台机器上:

叫法 电压 意思
高电平 / HIGH / 1 3.3V "通电了"
低电平 / LOW / 0 0V "没电"

所以一根 GPIO 能表达的,只有"两种情况"。想让 LED 亮或灭、按钮按了或没按——够用。但想表达"亮度 37%"这种连续的量,一根针就做不到(那是 7-4 要讲的难题)。

💡 为什么叫"通用",而不是像 Arduino 那样叫"D2、D3"

因为树莓派的这排针能换身份:同一个物理位置,既可以是普通 GPIO,也可以变成 I2C 的数据线、SPI 的时钟线(见第四节)。 代价是"编号"这件事变得很绕——这是本节最需要认真看的部分。

二、40 针全景:先把三类针分清

树莓派从 2014 年的 B+ 起就是 40 针,一直没变过(Pi 3/4/5 的排针位置与编号完全一致)。

40 根针里,只有 28 根是 GPIO,剩下 12 根是"供电和接地":

类别 数量 作用 能不能写代码控制
3.3V 电源针 2 根 给外接模块供电 ❌ 不能(永远输出 3.3V)
5V 电源针 2 根 给外接模块供电 ❌ 不能(永远输出 5V)
GND 接地针 8 根 电流的回路终点 ❌ 不能(永远是 0V)
GPIO 针 28 根 可编程的输入/输出 ✅ 能

GND 有 8 根、而且分散在整排各处,这是故意的:方便你接线时就近找地,不用把线拉很远。

2.1 怎么找到"针 1"(不然整排都会数错)

排针是两列:从上看下去,靠近板子外边缘的一列是奇数针(1、3、5…39),靠里那一列是偶数针(2、4、6…40)。

"针 1"有两个特征,配合着认:

  1. 它在靠近 SD 卡那一头(不是靠近 USB 那一头);
  2. 它的焊盘是方的(其余 39 个都是圆的)——这是最可靠的判据,翻过来看板子背面最清楚。
⚠️ 数错针 = 接错电 = 可能烧板子

"-"这个坑没有第二次机会。接线前暂停三秒,把针 1 认准了再动。习惯做法:先插一根线在针 1 上做标记,或者用 pinout 命令把图调出来对着看(见动手 Demo)。

三、⚠️ 本节最大的坑:引脚编号有三套

同一个物理位置,可以有三个名字。这是新手接错线、代码不生效的头号原因。

以"靠板边第 6 根针"为例(从上往下数第 6 个奇数针,即物理针 11):

编号体系 这个名字叫 谁会这么叫
物理针号(BOARD) 11 教程里的接线图、卖家商品页
BCM(也叫 GPIO 号) 17 几乎所有 Python 代码
WiringPi 0 老的 shell/C 教程(这套已经废弃)

三套编号里,只有 BCM 是"代码要用的"。所以你看接线图时永远要做一次翻译:板子上的第几根针 → BCM 号是多少。

⚠️ 本章所有实验统一用 BCM 编号

为了让接线图和代码对得上,本章所有实验的接线表都会写成 BCM 17(物理针 11)这种"两个都写"的形式。 你自己看别的教程时,先确认它用的是哪一套——如果它写"接着 11 号针"又说代码里是 17,那就是 BOARD 和 BCM 混着用,两个说的其实是同一个位置。

3.1 本章用到的几根针(先记这一张就够)

BCM 物理针 本章用来做什么
17 11 7-3 的 LED(数字输出)
27 13 7-3 的按钮(数字输入)
18 12 7-4 的 PWM 调光(正好是硬件 PWM 通道之一)
8 / 9 / 10 / 11 24 / 21 / 19 / 23 7-5 的 MCP3008(SPI 四根线)

另外记住两根"别碰"的针:BCM 0 和 BCM 1(物理针 27、28)。

它们是给 HAT 扩展板做身份识别用的(板上存着"我是什么板子"的小芯片,系统开机时会去读)。你把它当普通 GPIO 用,可能会和系统抢线。所有型号都一样,不是 Pi 5 独有的规矩。

3.2 怎么查:pinout 命令

树莓派预装了 gpiozero(7-2 要讲),它带一个特别好用的命令:

pinout

它会用彩色画出整排 40 针,每个位置都标着 BCM 号、物理针号、以及这个位置的复用功能(I2C/SPI/GND…)。这是你手头最好用的一张"接线图",比网上的图靠谱(因为它认得你这台机器到底是哪个型号)。

四、这些针还能"变身":复用功能

同一根针,除了当普通 GPIO,还能切换成某条总线上的一根信号线。本章会遇到两条:

总线 用哪几根针(BCM) 用它接什么
I2C 2(SDA)、3(SCL) 传感器、小屏幕、7-6 的 Sense HAT
SPI 11(SCLK)、10(MOSI)、9(MISO)、8(CE0) 7-5 的 MCP3008(ADC 芯片)、显示屏
UART(串口) 14(TXD)、15(RXD) 串口模块、和别的单片机通信

"总线"的意思可以这么理解:不是一根线传一位,而是几根线配一套规矩,把一整包数据可靠地送过去(I2C 用两根线管一串设备,SPI 用四根线跑得更快)。

⚠️ 用复用功能前,必须先在系统里"打开"

本节只讲针,不讲开开关——但记住这件事:接 I2C 或 SPI 之前,要去 sudo raspi-config → Interface Options 里把对应接口打开(2-4 讲过这个菜单,那里说过"别全开",就是这个道理),打开后要重启。 忘了这一步的典型症状:接好了、代码也抄对了,但 i2cdetect 一个设备都扫不到。

五、两条必须记住的红线

5.1 3.3V 铁律(1-3 已讲,这里再钉一遍)

这排针的逻辑电平是 3.3V,"高电平"就是 3.3V——不是 5V。

接任何外部模块前,第一句要问的是:它是 3.3V 逻辑还是 5V 逻辑?很多模块两种都有版本,买 3.3V 的那个(1-4 讲配件时提过这条)。

5.2 电流红线:它只能"发信号",不能"干重活"

一根 GPIO 针能输出的电流只有几毫安(mA)级——够点亮一颗小 LED,远远不够驱动电机、继电器、大功率灯带、电磁阀。

想接的东西 能直接接 GPIO 吗 正确做法
一颗普通 LED ✅ 但必须串限流电阻 串 220Ω~1kΩ 电阻(7-3 会算)
蜂鸣器(有源小蜂鸣器) ⚠️ 勉强,最好串电阻 串个电阻更安全
电机 / 舵机 / 继电器 ❌ 绝对不行 用三极管或专用驱动板,电源另接
LED 灯带 / 大功率灯 ❌ 绝对不行 用 MOS 管驱动 + 单独的电源
🚨 为什么"直接接"会出事

电机这类负载要的电流是 GPIO 上限的几十上百倍。GPIO 针内部就是一小段极细的硅通路——你要走大电流,它会先发热、再烧断。 而且电机停机瞬间会产生反向电压尖峰,这股电压会倒着打回 GPIO 针上。这就是"必须用驱动电路"的双重理由:电流不够 + 会反噬。

六、动手 Demo:把你自己这台机器的 40 针画出来

这一步不需要接任何线,纯看。建议每个命令都跑一遍——你现在看到的就是后面五节的"地图"。

第 1 步 · 让 pinout 画出整排针

pinout

你会看到什么:一张彩色的排针图。中间两列写着每个位置的 BCM 号和物理针号,图上还标出 3V3、5V、GND,以及 SDA、SCL、MOSI、MISO、SCLK 这些复用名字;下方还印着你这块板子的型号、内存、当前温度。

第 2 步 · 用命令确认板子型号(和 pinout 下方那行对一对)

cat /proc/device-tree/model; echo

你会看到什么:类似 Raspberry Pi 5 Model B Rev 1.0(型号随你的板子而变)。末尾那个 echo 是为了换行——这个文件本身不带换行符,不补的话你的提示符会挤在同一行。

第 3 步 · 看看内核眼里有几个 GPIO 控制器

gpiodetect

你会看到什么:一行行形如 gpiochip0 [pinctrl-rp1] (54 lines)。

读结果:能看见 pinctrl-rp1(Pi 5)或 pinctrl-bcm2711(Pi 4)的那个 gpiochip,就是管这排排针的。

💡 关于 `gpiochip0` 还是 `gpiochip4`

你可能看到某些老教程写"Pi 5 的排针在 gpiochip4"。那是 2024 年秋天之前的老镜像才有的情况——新系统的内核更新后,Pi 5 的排针已经和其他型号一样归在 gpiochip0。 所以:以 gpiodetect 实际输出为准,别背数字。(/dev/gpiochip4 这个老路径在新系统里仍做了个指向 gpiochip0 的软链接,就是为了让老代码还能跑。)

第 4 步 · 数一数三类针

pinout | grep -o "GND" | wc -l

你会看到什么:8。

读结果:8 个 GND,和第二节那张表对上了。你可以把 GND 换成 3V3、5V 各数一遍(分别得到 2 和 2)。这是让你亲手验证"表上的数字不是抄来的"。

第 5 步 · 认一下"针 1"在哪

断电,把板子翻过来看排针那一面:找那个方形焊盘(其余都是圆形)。它对应的就是针 1。

如果不想断电:pinout 图的最下面一行会告诉你针 1 靠近哪一端("靠近 SD 卡")。用眼睛确认一次,比记十遍都牢。

⚠️ 这一步之后、下一节动手接线之前,请守住两条习惯
  1. 接线时一定断电(拔掉电源线),接完检查一遍再上电;
  2. 上电前用眼睛把线从针脚一路"走"到底,确认没有一根搭错或跨到相邻针上(面包板相邻孔很容易虚搭)。

七、30 秒实验:把编号三套"翻"成一张便条

拿张纸(或新建一个 pins.md),把下面这张表抄一遍——抄的过程就是记住的过程:

我接的物理针 BCM 号(代码要写这个) 这根针还能干什么
11 17 普通 GPIO
12 18 硬件 PWM
13 27 普通 GPIO
3、5 2、3 I2C(SDA、SCL)
19、21、23、24 10、9、11、8 SPI(MOSI、MISO、SCLK、CE0)

然后回答一个问题:如果你照着某篇教程把 LED 接在"物理针 12",代码里应该写几?

答案:18。物理针 12 = BCM 18。(写 12 是错的——代码里写 12 指的是 BCM 12,那是物理针 32,位置差了十万八千里。)

八、常见误区

  1. "GPIO 针能输出 5V" —— 不能。高电平就是 3.3V。5V 只从那两根专用的 5V 电源针出来,而那两根不受代码控制。
  2. "40 根针都能编程" —— 只有 28 根是 GPIO。2 根 3.3V、2 根 5V、8 根 GND,它们只是电源。
  3. "代码里写 11 就是第 11 根针" —— 代码默认按 BCM 解释,11 指的是物理针 23。接的针和写的号必须已经翻译过一次。
  4. "针 1 是最靠边的那根,随便数就行" —— 两列并排,数错方向是常事。认方焊盘,或先跑 pinout 看图。
  5. "LED 直接接针和地就能亮,不用电阻" —— 会亮,但可能在烧掉。LED 内阻极小,GPIO 会被它拉走超过上限的电流。永远串一个 220Ω~1kΩ。
  6. "我接的是 3.3V 逻辑的模块,肯定安全" —— 还要看它自己是不是会往外送 5V(有些模块用 5V 供电时,它的信号线也是 5V 电平)。买之前看清逻辑电平这一项。
  7. "BCM 0 和 1 也是普通针,空着可惜" —— 它们是 HAT 身份识别专用,别动。
自测三问(点开对答案) 1. 你想把一个按钮接在物理针 13 上,代码里该写几?为什么? 2. 为什么 GND 针要有 8 根,而不是 1 根? 3. 有人告诉你"树莓派的 GPIO 可以直接驱动一个 5V 小继电器模块",你怎么判断这句话对不对? **参考答案** 1. **BCM 27**。因为**物理针 13 对应的 BCM 号是 27**;而 Python 代码默认按 BCM 解释,写 `13` 会指到 BCM 13(物理针 33)——**接的和写的不一致,现象是"程序跑起来了,但那个按钮按了没反应"**。 2. **接线方便,还为了分散电流**。外接模块多了以后,如果所有地都挤在一根针上,那根针要承受全部回流电流,更容易过热;而且线会拉得很长、很乱。**分散 8 根是树莓派官方设计上的贴心之处。** 3. **不对**。理由有两条:① **GPIO 输出的高电平只有 3.3V**,很多 5V 继电器模块的触发端认不出 3.3V(表现为"时灵时不灵"或完全不动作);② **继电器线圈的电流和反向尖峰都超出 GPIO 的承受范围**,正确做法是用三极管/MOS 管驱动、继电器电源单独供。**"能买到便宜的继电器模块"不等于"能直接接在 GPIO 上"。**

相关笔记