尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

I2C、I2S、SPI、UART总线选型指南:从物理层到实战调试

发布时间:2026/9/28 19:47:38

资讯中心
01
ARTICLE

I2C、I2S、SPI、UART总线选型指南:从物理层到实战调试

I2C、I2S、SPI、UART总线选型指南:从物理层到实战调试
1. 四种总线摆在面前到底该怎么选做嵌入式开发的人迟早都会遇到这样一个场景项目立项主控选好了传感器、存储器、显示屏、无线模组一堆外设列在BOM表里然后你打开数据手册一看有的写着I2C接口有的写着SPI有的只支持UART还有一颗音频codec用的是I2S。这时候问题就来了——主控的引脚资源是有限的PCB面积是有限的固件工程师的头发也是有限的到底哪个外设接哪条总线我见过太多项目在这件事上翻车。有人把该走SPI的ADC挂到了I2C上采样率死活上不去有人把两个I2C从设备地址配成一样的总线直接锁死还有人做音频项目I2S的时钟配置错了出来的声音像机器人变声。这些坑说到底都是对I2C、I2S、SPI、UART这四种总线的本质差异理解不够深。这篇文章不打算写成教科书式的协议规范翻译而是从实际选型和调试的角度把这四种总线拉出来做一次彻底的横向对比。我会讲清楚每种总线的物理层长什么样、协议层怎么跑、速度能到多少、适合接什么类型的外设、以及在STM32、ESP32、RK3588这类常见平台上实际配置时容易踩的坑。不管你是刚入行的嵌入式新人还是做了几年但一直只用过其中一两种总线的工程师看完应该都能对什么场景该选什么总线有一个清晰的判断。先给一个最粗粒度的结论方便你建立第一印象I2C是低速设备管理总线SPI是高速数据通道UART是点对点异步串行口I2S是专门为音频数据流设计的同步串行总线。记住这句话后面的细节都是围绕它展开的。2. 先搞清楚每种总线在物理层上到底长什么样2.1 I2C两根线挂一堆设备靠地址区分I2C的物理层极简只有两根线SCL串行时钟和SDA串行数据。这两根线都是开漏输出必须外接上拉电阻才能正常工作。开漏结构带来的一个天然好处是支持线与逻辑——只要总线上任何一个设备把线拉低整条线就是低电平。这个特性是I2C仲裁机制的基础。上拉电阻的取值是个经常被忽视的细节。典型值在4.7kΩ到10kΩ之间但具体取多少要看总线电容和通信速率。总线电容包括PCB走线电容、引脚电容和器件电容标准模式100kHz下总线电容不能超过400pF快速模式400kHz下要求更严。如果上拉电阻太大上升沿会变缓高速通信时波形还没到高电平就被下一个时钟沿打断了如果太小灌电流太大可能超过器件的驱动能力。我一般先用4.7kΩ起步用示波器看上升沿如果上升时间超过1μs就适当减小。I2C的寻址机制是它最核心的特征。标准模式下是7位地址理论上可以挂128个设备但实际可用的地址范围要扣掉保留地址大概能挂112个左右。10位地址模式可以扩展到1024个但用得很少。每个从设备出厂时都有一个固定地址或者可配置地址比如常见的EEPROM AT24C02地址是0x50温度传感器LM75是0x48到0x4F可配。注意I2C总线上所有设备必须共地而且上拉电阻只需要一对不要每个设备都加一对否则等效上拉阻值会变小可能导致灌电流超标。2.2 SPI四根线跑全双工片选决定跟谁说话SPI的物理层比I2C多两根线SCLK时钟、MOSI主出从入、MISO主入从出、CS片选。时钟由主机产生数据在MOSI和MISO上同时双向传输这就是所谓的全双工。SPI没有地址概念靠CS线来选通从设备——每个从设备需要一根独立的CS线。这意味着SPI的引脚开销随从设备数量线性增长。挂4个SPI从设备就需要4根CS线加上SCLK、MOSI、MISO总共7根线。如果主控引脚紧张这是个不小的负担。有些设计会用译码器比如74HC138来扩展CS线用3根地址线译出8个片选但这样同一时刻只能选通一个设备失去了SPI可以多个设备共享总线的优势。SPI的时钟极性和相位组合出四种模式这是新手最容易搞混的地方。CPOL决定空闲时时钟是高还是低CPHA决定数据在第一个还是第二个时钟沿采样。四种组合对应Mode 0到Mode 3。大部分器件用Mode 0或Mode 3但总有一些器件用Mode 1或Mode 2配置错了就是读出来全是0xFF或者0x00。模式CPOLCPHA空闲时钟采样沿Mode 000低第一个上升沿Mode 101低第二个下降沿Mode 210高第一个下降沿Mode 311高第二个上升沿2.3 UART没有时钟线靠约定好的波特率UART的物理层最简单只有TX和RX两根线交叉连接——A的TX接B的RXA的RX接B的TX。没有时钟线收发双方靠预先约定好的波特率来同步。这意味着如果双方的时钟源有偏差累积到一定程度就会采样错位导致通信失败。UART的数据帧格式是1个起始位低电平 5到9个数据位 可选的校验位 1到2个停止位高电平。起始位的作用是告诉接收方数据来了接收方检测到下降沿后开始按波特率采样。典型的配置是8N1——8个数据位、无校验、1个停止位。波特率误差是UART通信中最常见的坑。一般要求误差在2%以内超过这个值就可能出现误码。如果主控用的是内部RC振荡器作为时钟源温漂可能达到几个百分点高速通信时很容易出问题。所以UART通信对时钟精度的要求其实比想象中高尤其是波特率超过115200之后。2.4 I2S音频专用时钟线有三根I2S是专门为数字音频传输设计的物理层至少三根线SCK位时钟也叫BCLK、WS字选择也叫LRCLK、SD串行数据。SCK的频率等于采样率乘以位深乘以声道数比如48kHz采样、16位深、双声道SCK就是48000×16×21.536MHz。WS用来指示当前传输的是左声道还是右声道频率等于采样率。I2S的时序和SPI很像但有几个关键区别。首先I2S的数据是MSB先出而且WS信号在数据开始前一个时钟周期就切换了这样接收方有足够的时间准备。其次I2S通常只支持单向音频流要么播放要么录音全双工需要两组SD线。I2S的时钟配置是音频项目中最容易出问题的地方。主控需要提供精确的MCLK主时钟通常是采样率的256倍或384倍。如果MCLK有偏差音频播放速度就会不对表现为音调偏高或偏低。我遇到过用ESP32-C3做I2S输出时因为时钟源选择不当播放出来的音乐明显偏快后来把MCLK源从PLL切换到晶振才解决。3. 协议层拆解数据到底是怎么在线上跑的3.1 I2C的起始、地址、应答和停止I2C的一次完整传输由几个阶段组成。起始条件是SCL为高时SDA从高变低这个特殊电平组合不会出现在正常数据传输中所以被用作帧起始标志。起始之后主机发送7位从机地址加1位读写方向位然后释放SDA等待从机应答。从机如果存在且地址匹配会在第9个时钟周期把SDA拉低这就是ACK如果没拉低就是NACK说明从机没响应。数据传输阶段每个字节后面都跟一个ACK/NACK位。主机写完一个字节等从机ACK从机读完一个字节也要发ACK给主机。最后主机发送停止条件——SCL为高时SDA从低变高结束本次传输。I2C还有一个容易忽略的机制叫时钟拉伸。从机如果处理不过来可以把SCL线拉低强制主机等待。这个机制在低速从机比如某些传感器上很常见但有些主机的I2C控制器不支持时钟拉伸遇到从机拉低SCL就会报总线错误。选型时要确认主控的I2C外设是否支持这个特性。3.2 SPI的全双工移位本质SPI的协议层比I2C简单得多本质上就是两个移位寄存器首尾相连。主机和从机各有一个8位或更多位移位寄存器在时钟驱动下主机的MSB移出到MOSI从机的MSB移出到MISO同时各自移入对方的数据。8个时钟周期后两个寄存器的内容就交换了。这个机制意味着SPI的读写是同时发生的。你发一个字节出去同时也会收到一个字节。如果只想读不想写就发一个哑元字节通常是0x00或0xFF来产生时钟。很多SPI从设备比如Flash的读命令就是先发命令字节再发地址字节然后连续发哑元字节来读出数据。SPI没有应答机制主机发了数据不知道从机有没有收到。也没有错误检测全靠应用层自己保证。这是SPI比I2C简单但也更裸的地方。3.3 UART的异步采样与帧同步UART接收方在检测到起始位下降沿后会等待半个位周期然后在每个位周期的中间采样。这样做的目的是避开信号边沿的不确定性在信号最稳定的时刻取值。采样时钟通常是波特率的16倍这样可以在一个位周期内采样16次取中间几次的多数值作为最终结果提高抗噪能力。UART的帧同步完全依赖起始位。如果总线上有噪声导致误触发起始位接收方会收到一个错误的帧。校验位可以检测部分错误但只能检错不能纠错。所以UART通信中协议层通常还要加帧头、长度、CRC等字段来保证可靠性。3.4 I2S的声道对齐与数据格式I2S的数据格式有几种变体标准I2S、左对齐、右对齐、TDM时分复用。标准I2S中WS信号在第一个数据位之前一个时钟周期切换数据在WS切换后的第二个时钟沿开始有效。左对齐格式中数据在WS切换后立即有效没有那个一个时钟周期的延迟。右对齐格式中数据在WS切换前有效。TDM模式可以在一条数据线上传输多个声道WS信号变成帧同步信号每帧包含多个声道的数据。这在多声道音频系统中很有用比如车载音响的8声道输出。4. 速度、距离、拓扑三种维度的硬碰硬对比4.1 速率对比从100k到几十兆的跨度四种总线的速率差异巨大这是选型时最直观的指标。总线标准速率高速模式典型应用速率I2C100kHz400kHz/1MHz/3.4MHz100k-400kHzSPI几MHz几十MHz甚至上百MHz1M-50MHzUART9600bps几Mbps115200bps-1MbpsI2S取决于音频参数取决于音频参数1M-12MbpsI2C的标准模式只有100kHz快速模式400kHz高速模式3.4MHz但很少用。这个速率决定了I2C只适合传输控制命令和少量数据比如配置传感器寄存器、读写EEPROM的一个字节。想用I2C传图像或者音频数据基本不现实。SPI的速率可以做到很高STM32的SPI在72MHz主频下可以跑到18MHzRK3588的SPI可以到50MHz。这个速率足够传输ADC采样数据、LCD显示数据、Flash读写数据。SPI是四种总线中唯一能胜任高速数据流传输的。UART的速率通常不高115200bps是常见配置高速可以到1Mbps甚至3Mbps。但UART是异步的速率越高对时钟精度要求越严实际项目中超过1Mbps就要仔细评估时钟误差。I2S的速率由音频参数决定48kHz/16bit/双声道需要1.536MHz的位时钟这个速率不算高但I2S要求时钟非常精确抖动要小否则音频质量会下降。4.2 拓扑结构点对点、总线型、星型I2C是总线型拓扑所有设备挂在同一对线上靠地址区分。优点是引脚少扩展方便缺点是总线电容限制设备数量而且一个设备故障可能拉死整条总线。SPI是星型拓扑每个从设备一根CS线主机在中心。优点是每个设备独立互不影响缺点是引脚开销大。UART是点对点拓扑只能两个设备之间通信。如果需要多个设备要么用多个UART要么加RS485收发器组成总线。I2S也是点对点一个发送端对一个接收端。多设备需要多组I2S或者用TDM。4.3 传输距离板内、板间、设备间这四种总线都是为板级通信设计的传输距离通常不超过几十厘米。I2C和SPI在PCB上走线UART可以拉长到几米用RS232电平I2S一般不超过十几厘米。如果需要更长距离I2C可以加总线扩展器SPI可以加差分收发器UART可以转RS485或RS232。但这些都属于加外挂不是总线本身的能力。5. 选型决策什么外设该挂什么总线5.1 传感器类I2C是首选但要看数据率温度传感器、湿度传感器、气压计、加速度计、陀螺仪、磁力计——这些低速传感器几乎都支持I2C。原因是I2C引脚少多个传感器可以共享总线主控只需要一对引脚就能管理一堆传感器。但要注意数据率。加速度计如果只需要几十Hz的输出率I2C完全够用。但如果要做振动分析需要几kHz的采样率I2C的400kHz可能就不够了这时候要选SPI接口的传感器。实操心得选传感器时不要只看接口类型还要看数据手册里的输出数据率和接口速率两个参数。有些传感器标称支持I2C 400kHz但内部转换时间很长实际有效数据率远低于总线速率。5.2 存储器类SPI Flash是主流EEPROM走I2CSPI NOR Flash和SPI NAND Flash是嵌入式系统中最常见的存储方案。SPI Flash的速率可以到几十MHz容量从几MB到几百MB适合存固件、文件系统、日志数据。RK3588的混合存储方案中SPI NOR存引导程序PCIe NVMe SSD存系统这是典型的搭配。小容量EEPROM几KB到几MB通常用I2C接口因为速率要求不高而且I2C的引脚少。AT24C系列是经典选择地址可以通过引脚配置一条总线上可以挂多个。5.3 音频类I2S是唯一选择音频codec、数字麦克风、音频DAC、音频ADC——这些器件几乎都支持I2S。I2S的同步时钟机制保证了音频数据的连续性和低抖动这是UART和SPI做不到的。有些codec同时支持I2C和I2SI2C用来配置寄存器I2S用来传音频数据。这种组合很常见比如WM8960、ES8388都是这样。5.4 通信模组类UART最普遍SPI用于高速WiFi模组、蓝牙模组、4G模组、GPS模组——这些通信模组大部分用UART接口。原因是UART简单、通用、引脚少而且模组的AT命令交互不需要很高的速率。但有些高速WiFi模组用SPI接口比如ESP32作为从机时可以通过SPI与主控通信速率比UART高得多。选型时要看模组的数据吞吐需求如果只是发AT命令UART足够如果要传视频流SPI更合适。5.5 显示类SPI和I2C各有分工小尺寸OLED和LCD通常用I2C或SPI。I2C适合低分辨率、低刷新率的显示比如128×64的OLED。SPI适合高分辨率、高刷新率的显示比如320×240的TFT LCD。有些显示模组支持RGB接口或MIPI DSI那是另一套体系不在本文讨论范围内。6. 实战配置在STM32和ESP32上把四种总线跑起来6.1 STM32 HAL库的初始化套路STM32的HAL库把四种总线的初始化都封装成了结构体配置。以I2C为例需要配置时钟速率、地址模式、自身地址、应答使能等参数。SPI需要配置模式、数据大小、时钟极性相位、片选方式、波特率预分频等。UART需要配置波特率、字长、停止位、校验位、流控等。I2S需要配置模式、标准、数据格式、MCLK输出使能、音频频率等。用CubeMX生成初始化代码时有几个参数容易配错。I2C的时钟速率要跟从设备匹配配高了从设备不响应。SPI的波特率预分频要算清楚STM32的SPI时钟来自APB总线预分频值决定了实际SCK频率。UART的过采样率默认是16如果波特率很高可以改成8但抗噪能力会下降。// STM32 I2C初始化示例 hi2c1.Instance I2C1; hi2c1.Init.ClockSpeed 400000; // 400kHz快速模式 hi2c1.Init.DutyCycle I2C_DUTYCYCLE_2; // 占空比1:2 hi2c1.Init.OwnAddress1 0; // 主机模式不用自身地址 hi2c1.Init.AddressingMode I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode I2C_DUALADDRESS_DISABLE; hi2c1.Init.GeneralCallMode I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode I2C_NOSTRETCH_DISABLE; // 允许时钟拉伸6.2 ESP32-C3的I2S输出配置要点ESP32-C3的I2S外设比较灵活可以配置成标准I2S、TDM、PDM等模式。做I2S输出时关键参数是采样率、位深、声道数和MCLK倍数。ESP32-C3的I2S时钟源可以选PLL_D2、XTAL、PLL_F160M等。PLL时钟频率高但抖动大XTAL时钟频率低但稳定。做音频播放时如果对音质要求高建议选XTAL作为时钟源。但XTAL频率固定通常40MHz需要仔细计算分频系数才能得到精确的音频时钟。// ESP32-C3 I2S配置示例 i2s_config_t i2s_config { .mode I2S_MODE_MASTER | I2S_MODE_TX, .sample_rate 48000, .bits_per_sample I2S_BITS_PER_SAMPLE_16BIT, .channel_format I2S_CHANNEL_FMT_RIGHT_LEFT, .communication_format I2S_COMM_FORMAT_STAND_I2S, .dma_buf_count 8, .dma_buf_len 1024, .use_apll true, // 使用音频PLL获得精确时钟 };6.3 SPI硬件片选与软件片选的取舍SPI的CS信号可以用硬件自动控制也可以用软件手动拉低拉高。硬件片选由SPI外设自动管理在传输开始前拉低传输结束后拉高时序精确。软件片选需要手动控制GPIO灵活但占用CPU时间。STM32的SPI支持硬件片选NSS输出但有个坑硬件片选在传输结束后会立即拉高如果从设备需要CS保持低电平一段时间才能完成内部操作比如Flash的写操作硬件片选就不合适了。这时候要用软件片选手动控制CS的时序。注意SPI的CS建立时间和保持时间要满足从设备的要求。有些高速ADC要求CS在时钟开始前至少10ns拉低在时钟结束后至少10ns拉高。如果主控的SPI外设不满足这个时序就要用软件片选加延时来保证。6.4 UART的DMA接收与空闲中断UART接收不定长数据是个经典问题。用轮询方式接收会阻塞CPU用中断方式每来一个字节中断一次效率太低。最好的方案是DMA接收加空闲中断——DMA负责把数据搬到缓冲区空闲中断在总线空闲时触发告诉CPU一帧数据接收完毕。STM32的UART支持空闲中断配合DMA可以实现高效的不定长数据接收。配置时要注意DMA的缓冲区大小要足够大空闲中断里要重新设置DMA接收地址和长度。// STM32 UART DMA空闲中断接收 void USART1_IRQHandler(void) { if (__HAL_UART_GET_FLAG(huart1, UART_FLAG_IDLE)) { __HAL_UART_CLEAR_IDLEFLAG(huart1); HAL_UART_DMAStop(huart1); uint16_t len BUFFER_SIZE - __HAL_DMA_GET_COUNTER(huart1.hdmarx); // 处理接收到的len字节数据 HAL_UART_Receive_DMA(huart1, buffer, BUFFER_SIZE); } }7. 调试现场那些让人抓狂的波形和报错7.1 I2C总线锁死与GT911通信失败I2C总线锁死是最常见的故障。现象是SCL或SDA被某个设备一直拉低主机无法发起新的传输。原因通常是从设备在传输过程中复位或断电导致它正在拉低SDA时突然停止总线就卡住了。GT911触摸屏的I2C通信失败是很多人的噩梦。GT911上电后有地址选择过程如果复位时序不对它会用错误的地址。而且GT911的I2C时序对时钟拉伸比较敏感有些主控的I2C控制器处理不好。解决办法是仔细看GT911的数据手册确保复位引脚和中断引脚的时序正确必要时用软件I2C来替代硬件I2C。实操心得遇到I2C总线锁死可以尝试发送9个时钟脉冲来解锁。具体做法是把SCL配置成GPIO输出手动翻转9次然后发送停止条件。这个方法的原理是让从设备把剩余的位移完释放SDA线。7.2 SPI读出来全是0xFF或0x00SPI读数据异常通常有三个原因模式配错、片选不对、时钟太快。模式配错是最常见的CPOL和CPHA的组合有四种配错了数据采样点就错了。片选不对包括CS极性搞反、CS时序不满足要求、多个从设备CS冲突。时钟太快会导致从设备来不及响应尤其是长走线或高电容负载时。排查方法是用逻辑分析仪抓波形看SCK、MOSI、MISO、CS四根线的时序关系。先确认CS在传输期间保持有效再看数据在时钟的哪个沿变化、哪个沿采样跟从设备手册对比。7.3 UART乱码与波特率误差UART乱码的原因很多波特率不匹配、时钟源偏差、电平不匹配、地线没接好。波特率不匹配是最常见的双方配置的波特率不一致或者主控的时钟源精度不够导致实际波特率偏离。计算波特率误差的公式是误差 (实际波特率 - 目标波特率) / 目标波特率 × 100%。一般要求误差小于2%超过3%就可能出现误码。如果主控用内部RC振荡器温漂可能达到±5%高速通信时很容易出问题。7.4 I2S波形异常与逻辑分析仪抓包I2S的波形问题通常表现为SCK频率不对、WS相位不对、数据对齐方式不对。用逻辑分析仪抓I2S波形时要同时抓SCK、WS、SD三根线然后按照I2S的时序规范逐位检查。逻辑分析仪的解码功能可以自动解析I2S数据但前提是配置正确的协议参数。如果解码出来的数据跟预期不符先检查逻辑分析仪的采样率是否足够高至少是SCK频率的4倍以上再检查协议配置是否正确。8. 进阶话题那些教科书不会告诉你的细节8.1 I2C自由数据模式与PMBus的区别I2C自由数据模式是指不遵循标准I2C协议格式的传输方式通常用于特殊应用。PMBus是建立在I2C物理层之上的电源管理协议有自己的一套命令格式和数据类型。PMBus和I2C的区别在于PMBus规定了具体的命令集、数据格式、故障处理机制而I2C只定义了物理层和基本的传输协议。8.2 SPI的CS最小脉宽能到多少SPI的CS最小脉宽取决于从设备的要求和主控的驱动能力。从设备手册通常会给出CS建立时间tCSS、CS保持时间tCSH、CS高电平最小时间tCSHIGH等参数。主控的SPI外设如果支持硬件片选CS脉宽由硬件决定通常是一个SCK周期。如果从设备要求更长的CS脉宽就要用软件片选加延时。8.3 UART转GPIB与16550标准UART转GPIB是测试仪器领域的应用GPIB是IEEE 488标准用于连接测试仪器。16550是经典的UART芯片定义了UART的寄存器接口和FIFO机制。现代MCU的UART外设大多兼容16550的寄存器模型但增加了DMA、空闲中断等高级功能。8.4 Linux下PHY不用MDIO而用I2C的场景Linux网络子系统中PHY芯片通常通过MDIO接口管理。但有些PHY芯片支持I2C管理接口这时候需要在设备树中配置I2C节点而不是MDIO节点。这种场景在嵌入式Linux中比较少见但确实存在配置时要注意PHY驱动是否支持I2C接口。9. 我个人的选型决策树和踩坑清单经过这么多项目我总结了一个简单的选型决策树如果是音频数据流直接选I2S没有第二个选项。如果是高速数据采集或存储选SPI速率是硬道理。如果是低速传感器或配置寄存器选I2C引脚少是优势。如果是与PC或模组通信选UART通用性最好。如果引脚极度紧张且速率要求不高优先I2C。如果速率要求高且引脚充足优先SPI。踩坑清单I2C上拉电阻不要每个设备都加整条总线一对就够。SPI的CPOL/CPHA一定要跟从设备手册核对不要凭经验猜。UART的波特率误差要算不要假设主控时钟一定准。I2S的MCLK要精确音频项目建议用外部晶振。逻辑分析仪是调试总线的必备工具没有它等于盲人摸象。总线速率不要一上来就拉满先低速跑通再逐步提高。多个I2C从设备的地址要提前规划避免冲突。SPI的CS线如果走线很长要考虑加缓冲器。最后再分享一个小技巧调试I2C时如果怀疑某个从设备有问题可以先用I2C扫描程序扫一遍总线看哪些地址有应答。这个程序很简单就是遍历所有7位地址发起始条件加地址看有没有ACK。扫出来的地址列表可以跟原理图上的器件地址对比快速定位问题设备。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。