树莓派GPIO接线总翻车?一文讲透物理编号和BCM到底怎么用
你有没有过这样的经历:照着教程把LED接到树莓派上,代码跑起来却一点反应都没有?查了又查,线路没错、电源正常、程序也看着没问题——最后才发现,原来是引脚编号搞混了。
在树莓派的世界里,同一个金属针脚,居然有两种“名字”:一个叫物理编号,另一个叫BCM编号。它们指向的是同一根硬件引脚,但如果你在编程时弄错了,轻则外设不工作,重则烧板子。
这不是玄学,而是每个刚入门嵌入式开发的人都会踩的坑。今天我们就来彻底说清楚:
这两种编号到底有什么区别?什么时候该用哪个?为什么大多数代码都推荐用BCM?
从一块板子说起:树莓派的GPIO排针长什么样?
拿起你的树莓派,你会看到一排20或40个金属针脚整齐排列在边缘。这就是我们常说的GPIO排针(General Purpose Input/Output),是连接外部传感器、按钮、电机等设备的关键接口。
这40个针脚并不是随便安排的。它们中有一些是固定的电源和地线(比如3.3V、5V、GND),还有一些是可以编程控制的通用IO口,也就是我们说的GPIO。
但问题来了:当我们要写代码去控制某个引脚时,该怎么告诉程序“我要操作哪一个”?
答案就是——编号系统。
而树莓派偏偏提供了两种不同的编号方式。
物理编号(Physical Pin Numbering):按位置数数
想象你在数一排座位:“第一排左边第一个是1号,右边那个是2号,下面依次是3、4、5……”
这就是物理编号的本质:完全按照引脚在电路板上的实际位置来编号,从1开始顺序递增。
它的特点很直观:
- 左上角第一个引脚是Pin 1
- 往下是 Pin 3、5、7…
- 右边一列是 Pin 2、4、6、8…
- 所有型号只要排针布局一样,这个编号就一致
适合谁用?
- 刚入门的新手
- 做实验需要快速插线的人
- 出接线图、教学PPT的时候标注用
因为你看一眼板子就能找到“第12个针脚”,不需要查资料。
但它有个致命弱点:
不是所有物理编号对应的都是可编程GPIO!
比如:
- Pin 1 → 3.3V 电源(不能做输入输出)
- Pin 2 → 5V 电源
- Pin 6 → GND(地)
这些都不是你能通过代码控制高低电平的“GPIO”。如果你在程序里试图对Pin 1设置output HIGH,那不仅没意义,还可能造成短路风险。
所以记住一句话:
物理编号 ≠ GPIO编号
它只是一个物理位置标签,包含了电源、地、保留引脚和真正的GPIO。
BCM编号(Broadcom SOC Channel):芯片级的真实身份
现在换个视角:你不看板子了,转而去研究树莓派的核心芯片——博通(Broadcom)设计的SoC。
在这个芯片内部,每一个可以被软件控制的IO通道都有一个唯一的数字代号,比如 GPIO18、GPIO21……这些就是BCM编号。
举个例子:
你在程序里写GPIO.setup(18, OUT),这里的“18”指的就是 BCM18,对应的是SoC内部第18号通用IO通道。
无论这个引脚在PCB上位于左上角还是右下角,只要它是BCM18,操作系统就会准确找到并控制它。
这种编号的优势在哪?
| 维度 | 说明 |
|---|---|
| ✅ 精准映射 | 直接关联到芯片寄存器,没有歧义 |
| ✅ 功能支持完整 | PWM、SPI、I²C等功能只绑定特定BCM引脚 |
| ✅ 行业标准 | 几乎所有官方文档、库、示例都默认使用BCM |
比如你想用硬件PWM输出方波信号,只有 BCM12、BCM13、BCM18 支持。你不可能靠“物理位置”实现这种功能。
再比如 I²C 的 SDA 和 SCL 引脚,在大多数树莓派上分别是 BCM2 和 BCM3 —— 而它们的物理编号是 Pin 3 和 Pin 5。
一张表看清本质区别
| 对比项 | 物理编号(BOARD) | BCM编号(BCM) |
|---|---|---|
| 编号依据 | 板子上的物理位置 | SoC内部通道编号 |
| 是否连续 | 是(1,2,3,…) | 否(跳着来,如2,3,4,7,8,9…) |
| 包含哪些引脚 | 所有针脚(含5V/3.3V/GND) | 仅可编程GPIO |
| 编程中常用吗 | 很少 | 极其常见 |
| 推荐用于 | 接线图、硬件连接 | 写代码、调API |
| Python中如何设置 | GPIO.setmode(GPIO.BOARD) | GPIO.setmode(GPIO.BCM) |
🛑重点提醒:如果你用了
GPIO.setmode(GPIO.BCM),那你后面写的引脚号就必须是BCM编号;反之亦然。一旦错配,后果就是“接对了线,却控制错了脚”。
实战案例:为什么我的LED不亮?
假设你想点亮一个LED,把它接到了树莓派的物理编号12上。
查一下引脚图你会发现:
👉 物理编号12 =BCM18
接下来你写了段Python代码:
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BOARD) # 注意这里设的是BOARD模式 LED_PIN = 18 # 你以为这是BCM18? GPIO.setup(LED_PIN, GPIO.OUT) for _ in range(5): GPIO.output(LED_PIN, GPIO.HIGH) time.sleep(0.5) GPIO.output(LED_PIN, GPIO.LOW) time.sleep(0.5) GPIO.cleanup()结果呢?灯没亮。
错在哪?
虽然你接的是物理12(BCM18),但在代码中你用了GPIO.setmode(GPIO.BOARD),这意味着LED_PIN = 18指的是物理编号18!
而物理编号18对应的是BCM24—— 完全不是你接的那个引脚!
这就相当于:你买了张12号座位的票,却坐到了18号位上,当然没人给你发餐。
正确做法一(推荐):
统一使用BCM编号:
GPIO.setmode(GPIO.BCM) LED_PIN = 18 # 明确表示BCM18 GPIO.setup(LED_PIN, GPIO.OUT)正确做法二(仅限简单项目):
坚持用物理编号,那就必须用物理编号写代码:
GPIO.setmode(GPIO.BOARD) LED_PIN = 12 # 物理编号12 GPIO.setup(LED_PIN, GPIO.OUT)✅ 总结一句口诀:
接线看物理,编程用BCM;模式要匹配,别让脚乱跑。
如何快速查清对应关系?三个实用工具推荐
1. 终端命令:pinout
如果你用的是较新的 Raspberry Pi OS,直接在终端输入:
pinout它会打印出当前树莓派型号的完整引脚图,清晰标注每个针脚的物理编号、BCM编号、功能名称(如SDA、SCL、TXD等),甚至还有文字说明。
2. 在线可视化工具
搜索 “raspberry pi pinout interactive” 可以找到很多图形化网页工具,比如 pinout.xyz 。
鼠标悬停就能看到详细信息,特别适合初学者学习。
3. 打印一张贴纸贴在板子旁
老司机的做法:下载一份高清引脚图,打印出来贴在工作台或盒子盖上,随时对照。
高阶提示:别忽视特殊功能引脚
有些BCM引脚具备复用功能,比如:
| BCM编号 | 特殊功能 |
|---|---|
| BCM18 | 支持硬件PWM0 |
| BCM8 / BCM7 | SPI CS0 / CS1 |
| BCM2 / BCM3 | I²C SDA / SCL |
| BCM14 / BCM15 | UART TXD / RXD |
如果你想实现精确的PWM调光、高速SPI通信或者稳定I²C读取,一定要优先选择这些原生支持的引脚,而不是随便找个GPIO凑合。
否则只能靠软件模拟,性能差、不稳定、占用CPU资源。
团队协作中的最佳实践
当你和其他人一起做项目时,最容易出问题的就是编号混乱。
为了避免扯皮,建议遵循以下规范:
代码中一律使用 BCM 编号
- 统一标准,减少误解
- 更容易移植到其他项目注释中标明物理编号
python LED_PIN = 18 # BCM18, 物理Pin 12绘制接线图时双标
- 同时写出物理编号和BCM编号
- 标注功能用途(如“连接DHT11数据线”)在README中声明编号模式
⚠️ 本项目使用 BCM 编号,请确保代码开头设置: GPIO.setmode(GPIO.BCM)
最后划重点:别再被编号绊倒了
回到最初的问题:
物理编号和BCM有什么区别?
答案已经很清楚了:
- 物理编号是给人看的——方便你动手接线;
- BCM编号是给程序看的——确保指令精准送达。
你可以把它们理解为:
📍 地址门牌 vs 户主身份证号
你在地图上找地方靠门牌号(物理编号),但银行开户必须用身份证号(BCM编号)。两者有关联,但用途完全不同。
掌握这一点,你就迈过了树莓派GPIO编程的第一道门槛。下次再遇到“接了线没反应”的情况,先别急着重启树莓派,花30秒检查一下:
“我是不是把物理编号当成BCM用了?”
往往问题就出在这儿。
如果你正在做一个物联网项目、自动化小车,或是学生实验作业,不妨现在就打开终端敲一遍pinout,重新认识一下这块小板子上的每一根针脚。
毕竟,真正的嵌入式开发,从来都不是“接上线就能跑”,而是理解每一行代码背后真实的硬件世界。
如果你在实践中还遇到过其他GPIO相关的坑,欢迎留言分享,我们一起避坑前行。