UART、I2C 与 SPI——三种总线是什么,接线前怎么查一个引脚
本页回答的问题:“UART vs I2C vs SPI 到底差在哪?以及往引脚上接设备之前,怎么知道这个引脚在我的板上合法、空闲且安全?”
一句话差异
| 总线 | 线 | 谁什么时候说话 | 典型用途 |
|---|---|---|---|
| UART | TX、RX(异步、双向) | 双方随时(约定波特率) | 控制台/串口、调制解调器 |
| I2C | SDA、SCL(+共享总线、地址) | 控制器按地址点名外设 | 低速传感器、配置 EEPROM |
| SPI | MOSI、MISO、SCK、CS(每设备一根片选) | 控制器片选、全双工 | 高速 flash、屏幕、SD |
UART 是典型的点对点选择(两个设备);I2C 把多个设备挂在两条共享线上;SPI 通常是三者中最快的,但每个设备要多花一根片选线。
它们藏在这些板的哪里
- ESP32-S3-DevKitC-1——USB 转 UART 桥经 UART0(排针表里的 U0TXD/U0RXD,GPIO43/44)与芯片通信。“串口控制台"不用接线就能工作的原因:桥永久焊在那两个引脚上。J3 若干脚还带 FSPI* 名字——芯片的 flash-SPI 功能组。
- ESP32-DevKitC——D0/D1/D2/D3/CMD/CLK 是一条工作中的 SPI:焊在板上的 SPI flash。WROVER 变体上同一条 SPI 总线还带 PSRAM——这就是 GPIO16/17 在那些变体上消失的原因(见板卡页)。
- Pico / Pico 2——两块板的 SDK 板头都把 UART0 默认到 GP0/1、I2C0 默认到 GP4/5(pico.h 与 pico2.h,commit
079c6f39)。PIO(可编程状态机)能干什么是另一个问题——协议的软件实现,与硬件 UART/I2C/SPI 块分开。
接线之前:三层引脚检查
“GP_n 能不能给我的总线用?“其实是三个独立的问题。按顺序查,任何一层都能单独否决这个引脚:
- SDK 默认——软件约定。
PICO_DEFAULT_I2C_SDA_PIN 4的意思是 SDK 板头替你选了 GP4;代码里可以改。默认值写在逐板文件里,它不证明哪些引脚合法——也不执行任何配置:宏只给出默认选择,初始化控制器、选定引脚功能是应用(或框架)的事。 - 芯片复用表——硬件事实。一个硬件 UART/I2C/SPI 块只存在于每颗芯片固定的复用引脚集上。对 RP2040,本站固定了官方 io_bank0.h:UART0 TX/RX 在 GP0/1,GP12/13 与 GP16/17 是 UART0 的其他合法选项——绝不在任意 GP 脚上。对 RP2350,本站尚未把官方复用表固定到固定来源,因此本页不列举其合法组合——以 RP2350 数据手册为准;Pico 2 板头的默认(GP0/1、GP4/5)是第 1 层事实,不能证明其他引脚合法或不合法。
- 板级接线——什么真正走到排针、什么已被占用。这是板卡页的字段表:物理排针位置、板内功能(LED、VBUS 检测……)、逐修订。
通电之前:四块板的 GPIO 都是 3.3 V 逻辑(见 3.3 V 与 5 V),与外设共地;I2C 总线在 SDA/SCL 上需要上拉到 3.3 V(开漏线)——很多传感器模块板载;查你的模块,别默认。
查表实例:用 GP4/GP5 接一个 I2C 传感器
对两个世代诚实地走一遍检查:
- 第 1 层——
pico.h和pico2.h都设PICO_DEFAULT_I2C_SDA_PIN 4、PICO_DEFAULT_I2C_SCL_PIN 5:两块板上 SDK 对 I2C0 的默认选脚是 GP4/5——宏只指定默认引脚,不初始化控制器、不复用引脚功能。 - 第 2 层——GP4/GP5 是两代芯片的文档化默认。RP2040 有固定复用表确认 I2C0 在 GP4/5;RP2350 本站未核到第二层复用来源,这里不把板头默认重复充作复用证明——完整合法脚集仍属数据手册范围。
- 第 3 层——Pico 与 Pico 2 记录显示 GP4/GP5 引出到 J1 排针,无板内功能占用。
结论:两个世代上 GP4/5 都是文档化默认对,两块板都引出且无占用——模块接这里意味着顺着 SDK 默认走而不是对抗它。这是起点不是保证:第一次通信之前,控制器仍须初始化、上拉到 3.3 V、共地、总线地址正确。
误用反例:GP25 不是自由脚
镜像错误:因为引脚离传感器近就选它,跳过第 3 层。Pico 与 Pico 2 上 GP25 都接着板载 LED,且未引出到 J1/J2 排针(两块板页的固定记录)——SDK 不会拦你的代码,第 1、2 层也不报错,但它根本没有排针脚可接,把这条线当总线驱动还会与板载 LED 冲突。同一层在 ESP32-S3-DevKitC-1 上否决得更狠:GPIO43/44 看着像"UART0 的默认脚”,也确实是——但被 USB 转 UART 桥永久占用。自己的链路用另一个 UART 实例,否则你会和控制台抢引脚。
要记住的那个陷阱
总线控制器不稀缺,引脚才稀缺。DevKitC 的 flash-SPI 引脚是不能共享的总线;Pico 的"默认"引脚可以挪——但只能挪到该芯片该外设的合法复用脚上;DevKitC-1 的 U0TXD/U0RXD 已被桥占用。
本页不能告诉你的
- 电气/协议细节(上拉阻值、时钟拉伸、SPI 模式 0-3)——芯片数据手册领域;本页是定位层。
- 每颗芯片有几个 UART/I2C/SPI 硬件实例——见芯片页的固定来源记录与厂商数据手册。
- RP2350 的完整合法复用组合——尚未固定到本站的官方来源;在此之前本页只断言其文档化默认。
来源
- MCUID 数据记录:ESP32-S3-DevKitC-1(U0TXD/U0RXD、FSPI* 引脚名)、ESP32-DevKitC(flash-SPI 线、WROVER GPIO16/17 条件)、Pico 与 Pico 2(GP4/GP5 排针引出、GP25 板载 LED)
- pico-sdk pico.h / pico2.h 板头——SDK 默认:两代均 UART0 GP0/1、I2C0 SDA 4 / SCL 5(commit
079c6f39) - pico-sdk io_bank0.h(RP2040 IO bank 功能选择)——RP2040 硬件复用表,仅按 RP2040 引用(commit
079c6f39) - 引脚号、GPIO 号与引脚功能——编号系统的配套页