news 2026/10/18 1:01:40

SPI、UART、I2C通信协议选型指南:从原理到实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SPI、UART、I2C通信协议选型指南:从原理到实战

1. 三种通信协议到底在解决什么问题

嵌入式开发干久了,你会发现一个很有意思的现象:新手最怕的不是写代码,而是面对一颗传感器或一块存储芯片时,不知道该用哪种通信方式把它接上去。SPI、UART、I2C这三个词几乎贯穿了整个嵌入式生涯,但很多人对它们的理解长期停留在“考试背过、用的时候查一下”的阶段。我自己带过不少刚入行的朋友,发现大家普遍卡在同一个地方——知道这三种协议的名字,但说不清楚它们各自适合什么场景,更不知道选错了会带来什么后果。

这篇文章想做的事情很直接:把SPI、UART、I2C这三种最常见的板级通信协议彻底拆开讲清楚。不是那种教科书式的“定义加时序图”,而是从实际项目出发,告诉你每种协议为什么被设计成这样、在什么场景下该选谁、接线和调试时容易踩哪些坑。不管你是刚接触单片机的新手,还是已经用过几种传感器但没系统梳理过的开发者,看完之后应该能建立起一套自己的选型判断逻辑。

先说一个基本认知:这三种协议都属于串行通信,也就是数据一位一位地在线上传输。它们解决的问题本质上是一样的——让主控芯片和外设芯片之间交换数据。但它们的“性格”完全不同。UART像两个人在打电话,点对点、简单直接;I2C像一条公交线路,多个设备挂在同一组线上,靠地址区分谁该下车;SPI像一条高速公路,速度快、车道多,但占用的引脚也多。理解这三种“性格”,比死记时序参数有用得多。

我在实际项目中见过太多因为协议选错导致的返工。有人用UART去接多个同型号传感器,结果发现根本没法寻址;有人用I2C驱动高刷新率的显示屏,发现带宽完全不够;也有人用SPI接了一个只需要偶尔读一次温度的芯片,白白浪费了三个引脚。这些问题不是代码写错了,而是一开始选型就没想清楚。所以下面我会从设计思路开始,一层一层往下拆。

2. 三种协议的核心设计思路对比

2.1 UART:最古老的“点对点电话线”

UART的全称是通用异步收发器,关键词在“异步”两个字上。所谓异步,就是通信双方没有共享的时钟线,发送方和接收方各自按照约定的波特率来采样数据。这就像两个人约定好每隔一秒钟说一个字,只要双方的节奏一致,就能正常交流。

UART的硬件连接极其简单:两根线,一根发送、一根接收,交叉连接即可。不需要时钟线,不需要片选线,甚至不需要地址。这种极简设计带来的好处是硬件成本低、实现容易,几乎每颗单片机都自带UART外设。但代价也很明显:只能点对点通信,一条UART总线只能接两个设备。如果你想接三个设备,要么用三组UART,要么加外部多路复用器。

UART还有一个容易被忽视的特点:它是全双工的。发送和接收可以同时进行,因为收发各有一根独立的线。这一点在需要双向实时通信的场景下很重要,比如主控和上位机之间的调试串口,或者两个处理器之间的数据同步。

实际使用中,UART最常见的场景包括:调试信息输出、与PC通信、连接蓝牙模块或4G模块、两个单片机之间的短距离数据交换。波特率的选择也有讲究,常用的有9600、115200、921600等。波特率越高,传输距离越短,抗干扰能力越弱。我在实际项目中一般默认用115200,除非有特殊需求才会调整。

2.2 I2C:一条总线挂多个设备的“公交系统”

I2C的全称是集成电路总线,它的设计初衷就是解决“多个芯片共用少量引脚”的问题。I2C只用两根线:一根时钟线SCL,一根数据线SDA。所有设备都挂在这两根线上,靠设备地址来区分通信对象。

I2C的通信过程有点像老师点名:主设备先发出一个起始信号,然后发送目标设备的地址,总线上所有设备都会收到这个地址,但只有地址匹配的设备才会响应。这种机制使得一条I2C总线上可以挂载几十甚至上百个设备,而主控只需要两根引脚。

I2C的另一个特点是半双工。同一时刻数据只能在一个方向上传输,因为只有一根数据线。主设备发送数据时从设备接收,从设备发送数据时主设备接收,不能同时进行。这在大多数传感器读取场景下不是问题,因为传感器通常是被动响应主控的请求。

I2C的速率相对较低,标准模式100kHz,快速模式400kHz,高速模式3.4MHz。实际项目中400kHz是最常用的档位。速率低带来的好处是抗干扰能力强、走线要求宽松,适合板内短距离通信。但如果你需要高速传输大量数据,I2C就不太合适了。

I2C最典型的应用场景是:连接各种传感器(温度、湿度、加速度、气压等)、EEPROM存储芯片、RTC时钟芯片、IO扩展芯片。这些设备的共同特点是数据量不大、实时性要求不高、但需要多个设备共用总线。

2.3 SPI:高速全双工的“专用车道”

SPI的全称是串行外设接口,它的设计思路和I2C完全相反。SPI不追求引脚少,而是追求速度快。它通常需要四根线:时钟线SCK、主出从入MOSI、主入从出MISO、片选线CS。每个从设备都需要一根独立的片选线,这意味着挂载N个设备就需要N根片选线。

SPI的通信机制很简单:主设备拉低某个从设备的片选线,然后按照时钟节拍同时发送和接收数据。因为是全双工,发送和接收可以同时进行,效率很高。SPI没有地址概念,靠片选线来选中目标设备,所以协议本身的开销极小,几乎可以把所有时钟周期都用于有效数据传输。

SPI的速率是三种协议中最高的,常见的有几MHz到几十MHz,甚至可以达到上百MHz。这使得SPI非常适合需要高速数据传输的场景,比如显示屏、Flash存储芯片、高速ADC、以太网控制器等。

但SPI的缺点也很明显:引脚占用多。每增加一个从设备就要多一根片选线,如果系统中有七八个SPI设备,引脚压力会很大。另外SPI没有标准的协议规范,不同厂商的芯片在时钟极性、相位、位序等参数上可能不同,需要仔细阅读数据手册。

2.4 三种协议关键参数对照

特性UARTI2CSPI
线数2(TX/RX)2(SCL/SDA)4+(SCK/MOSI/MISO/CS)
双工方式全双工半双工全双工
多设备支持不支持(点对点)支持(地址寻址)支持(片选寻址)
典型速率9600~921600bps100k~3.4MHz1M~100MHz
时钟线无(异步)有(同步)有(同步)
引脚开销低低高
协议开销中(起始/停止位)中(地址/ACK)极低
典型距离板间/短距离板内板内
常见应用调试/模块通信传感器/EEPROM显示屏/Flash/ADC

这张表建议收藏,选型时对照着看,基本能覆盖大部分决策场景。

3. 从时序层面理解三种协议的差异

3.1 UART的帧结构与波特率计算

UART虽然没有时钟线,但它的数据格式是有严格规定的。一个完整的UART帧包括:1个起始位(低电平)、5到9个数据位(通常是8位)、可选的校验位、1到2个停止位(高电平)。起始位的作用是告诉接收方“数据要来了”,接收方检测到下降沿后开始按照波特率采样。

波特率的计算是UART配置的核心。假设系统时钟为72MHz,想要得到115200的波特率,分频系数就是72000000除以115200,约等于625。实际配置时还需要考虑过采样率,常见的是16倍过采样,所以实际分频值还要再除以16。这些计算通常由库函数自动完成,但理解原理有助于排查通信异常。

注意:UART通信双方必须使用相同的波特率、数据位、校验位和停止位配置,任何一项不匹配都会导致通信失败或数据错乱。

我在调试UART时遇到最多的问题就是波特率偏差。晶振精度不够、时钟配置错误、分频系数取整误差都可能导致实际波特率偏离理论值。一般来说,偏差在2%以内可以正常通信,超过5%就很容易出错。如果发现接收到的数据偶尔出现乱码,优先检查波特率是否准确。

3.2 I2C的起始、寻址与应答机制

I2C的时序比UART复杂一些,但逻辑很清晰。通信开始时,主设备在SCL为高电平时将SDA拉低,产生起始条件。然后主设备发送7位地址加1位读写标志,共8位。第9个时钟周期,被选中的从设备将SDA拉低作为应答信号,表示“我收到了”。

数据传输阶段,每个字节后面都跟着一个应答位。发送方释放SDA,接收方拉低SDA表示ACK,保持高电平表示NACK。通信结束时,主设备在SCL为高电平时将SDA拉高,产生停止条件。

I2C的时钟拉伸机制值得单独提一下。当从设备来不及处理数据时,它可以保持SCL为低电平,强制主设备等待。这个机制让慢速设备也能挂在高速总线上,提高了兼容性。但并不是所有主控都支持时钟拉伸,配置时需要确认。

提示:I2C总线需要上拉电阻,典型值为4.7kΩ或10kΩ。电阻太小会增加功耗,太大则上升沿变缓影响通信质量。总线电容也会影响上拉电阻的选择,设备越多、走线越长,电阻应该越小。

3.3 SPI的四种模式与时钟配置

SPI的时序核心在于时钟极性和时钟相位这两个参数,它们组合出四种模式。时钟极性决定空闲时SCK是高还是低,时钟相位决定数据在第一个还是第二个时钟边沿采样。

模式CPOLCPHA空闲电平采样边沿
Mode 000低上升沿
Mode 101低下降沿
Mode 210高下降沿
Mode 311高上升沿

Mode 0和Mode 3是最常用的两种。大部分Flash芯片和显示屏支持Mode 0或Mode 3。如果通信不正常,第一个要检查的就是模式是否匹配。我遇到过好几次因为模式设错导致读回来的数据全是0xFF或0x00的情况,换成正确模式后立刻正常。

SPI的片选信号也需要注意。有些芯片要求片选在整个传输过程中保持低电平,有些则允许在每个字节之间拉高。另外,片选的建立时间和保持时间也需要满足芯片手册的要求,否则可能出现数据丢失。

4. 实际项目中的选型逻辑与决策流程

4.1 从设备数量和引脚资源出发

选型的第一步永远是看系统需求。如果你只需要连接一个设备,UART和SPI都可以考虑。UART的优势是简单、占用引脚少,SPI的优势是速度快。如果这个设备是调试串口或无线模块,UART几乎是默认选择;如果是高速ADC或显示屏,SPI更合适。

当设备数量超过一个时,I2C的优势就体现出来了。假设你要接一个温度传感器、一个EEPROM和一个IO扩展芯片,用I2C只需要两根线,用SPI则需要至少六根线(三根共用加三根片选)。在引脚紧张的小型MCU上,这个差距可能是决定性的。

但I2C也不是万能的。如果多个设备中有高速设备,I2C的带宽可能成为瓶颈。比如一个400kHz的I2C总线,理论最大传输速率是400kbps,实际有效数据率还要扣除地址和应答开销,可能只有200kbps左右。如果同时要驱动一个需要频繁刷新的OLED屏和一个高速传感器,总线就会非常拥挤。

4.2 从数据速率和实时性出发

数据速率是选型的第二个关键维度。我一般把应用场景分为三档:低速(小于100kbps)、中速(100kbps到1Mbps)、高速(大于1Mbps)。

低速场景包括温度采集、按键扫描、EEPROM读写等,I2C完全够用。中速场景包括音频编解码器配置、中速ADC采样等,SPI或高速I2C都可以。高速场景包括显示屏刷新、Flash读写、高速数据采集等,SPI是首选。

实时性也要考虑。UART和SPI的全双工特性使它们适合需要同时收发数据的场景。I2C的半双工特性意味着收发不能同时进行,如果应用需要频繁的双向交互,I2C的效率会打折扣。

还有一个容易被忽视的因素是中断开销。UART每收到一个字节就会产生一次中断,高速率下中断频率很高,可能影响系统实时性。SPI和I2C通常以帧为单位处理,中断频率相对较低。如果系统对实时性要求很高,这一点需要纳入考量。

4.3 从距离和抗干扰能力出发

通信距离是选型的第三个维度。UART在板间通信中表现不错,配合RS485或RS232电平转换芯片可以延伸到几十米甚至更远。I2C和SPI的设计初衷是板内通信,通常不超过几十厘米。如果强行拉长走线,信号质量会急剧下降。

抗干扰能力方面,I2C因为速率低、有上拉电阻,在噪声环境下的表现相对稳健。SPI速率高,对走线阻抗和屏蔽要求更高。UART介于两者之间。如果项目环境电磁干扰较强,比如电机控制或工业现场,I2C和UART比SPI更稳妥。

实操心得:在电机控制项目中,我通常会把I2C传感器远离功率线路,并且使用屏蔽线或双绞线。SPI显示屏的排线尽量短,必要时在时钟线上串联33Ω电阻来抑制振铃。

4.4 选型决策流程图(文字版)

面对一个具体项目时,我会按照以下顺序做决策:

  1. 设备数量是一个还是多个?一个的话优先UART或SPI,多个的话优先I2C或SPI。
  2. 数据速率要求是多少?低速选I2C,中高速选SPI,调试通信用UART。
  3. 引脚资源是否紧张?紧张选I2C,充裕选SPI。
  4. 是否需要全双工?需要选UART或SPI,不需要则I2C也可以。
  5. 通信距离和电磁环境如何?恶劣环境优先I2C或UART。
  6. 主控芯片支持哪些外设?有时候硬件资源直接决定了选择范围。

这套流程不是绝对的,但能帮你快速缩小选择范围。实际项目中往往还需要考虑芯片成本、供货情况、开发难度等因素。

5. 实操配置与代码实现要点

5.1 UART初始化与收发配置

以常见的32位MCU为例,UART初始化通常包括以下几个步骤:使能时钟、配置引脚复用、设置波特率、配置数据格式、使能收发、配置中断(如果需要)。

// UART初始化示例(伪代码,具体寄存器名称因芯片而异) void uart_init(uint32_t baudrate) { // 1. 使能UART和GPIO时钟 RCC->APB1ENR |= RCC_APB1ENR_USART2EN; RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; // 2. 配置TX为复用推挽输出,RX为浮空输入 GPIOA->MODER &= ~(3 << (2*2)); GPIOA->MODER |= (2 << (2*2)); GPIOA->AFR[0] |= (7 << (4*2)); // 3. 配置波特率,假设系统时钟84MHz,过采样16 // 分频值 = 84000000 / (16 * 115200) = 45.57 // 实际写入BRR寄存器的值需要根据芯片手册计算 USART2->BRR = 84000000 / baudrate; // 4. 8位数据,1位停止位,无校验 USART2->CR1 &= ~USART_CR1_M; USART2->CR2 &= ~USART_CR2_STOP; // 5. 使能收发和UART USART2->CR1 |= USART_CR1_TE | USART_CR1_RE | USART_CR1_UE; }

发送数据时,等待发送寄存器为空,然后写入数据即可。接收数据通常使用中断或DMA,避免轮询浪费CPU时间。中断方式下,每收到一个字节触发一次中断,在中断服务函数中读取数据并存入缓冲区。

注意:UART发送完成和发送寄存器为空是两个不同的标志。发送完成表示最后一个字节已经完全移出移位寄存器,发送寄存器为空表示可以写入下一个字节。如果需要确保数据完全发送完毕再关闭UART,要等待发送完成标志。

5.2 I2C主机读写操作

I2C的读写操作比UART复杂一些,因为涉及到起始条件、地址发送、应答检测等步骤。以下是一个典型的I2C写操作流程:

  1. 发送起始条件
  2. 发送从设备地址加写标志
  3. 等待应答
  4. 发送寄存器地址
  5. 等待应答
  6. 发送数据字节
  7. 等待应答
  8. 发送停止条件

读操作稍微复杂一些,通常需要先写寄存器地址,然后重新发送起始条件,再发送地址加读标志,最后读取数据。

// I2C写寄存器示例(伪代码) uint8_t i2c_write_reg(uint8_t dev_addr, uint8_t reg_addr, uint8_t data) { i2c_start(); if (i2c_send_byte(dev_addr << 1 | 0) != ACK) { i2c_stop(); return ERROR; } if (i2c_send_byte(reg_addr) != ACK) { i2c_stop(); return ERROR; } if (i2c_send_byte(data) != ACK) { i2c_stop(); return ERROR; } i2c_stop(); return SUCCESS; }

实际项目中,很多MCU的I2C外设支持硬件自动处理起始、地址、应答等流程,只需要配置好寄存器然后读写数据寄存器即可。但理解底层时序对于排查问题非常有帮助。

实操心得:I2C调试时最常用的工具是逻辑分析仪。抓取SCL和SDA的波形,可以直观地看到起始条件、地址、应答位是否正确。如果没有逻辑分析仪,也可以用示波器观察波形,但解码协议会比较麻烦。

5.3 SPI数据传输与片选控制

SPI的配置相对简单,主要是设置时钟极性、相位、速率和位序。以下是一个典型的SPI初始化流程:

// SPI初始化示例(伪代码) void spi_init(void) { // 1. 使能SPI和GPIO时钟 RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; // 2. 配置SCK、MOSI、MISO为复用功能 // 配置CS为普通推挽输出 // 3. 配置SPI参数 SPI1->CR1 &= ~SPI_CR1_SPE; // 先关闭SPI SPI1->CR1 = SPI_CR1_MSTR | // 主机模式 SPI_CR1_BR_1 | // 时钟分频,假设得到4MHz SPI_CR1_SSM | // 软件管理片选 SPI_CR1_SSI; // 内部片选高 SPI1->CR1 &= ~(SPI_CR1_CPOL | SPI_CR1_CPHA); // Mode 0 SPI1->CR1 |= SPI_CR1_SPE; // 使能SPI } // SPI传输一个字节 uint8_t spi_transfer(uint8_t data) { while (!(SPI1->SR & SPI_SR_TXE)); // 等待发送缓冲区空 SPI1->DR = data; while (!(SPI1->SR & SPI_SR_RXNE)); // 等待接收完成 return SPI1->DR; }

片选控制需要手动操作GPIO。在传输开始前拉低片选,传输结束后拉高。对于多字节传输,片选通常在整个传输过程中保持低电平。

注意:SPI的时钟速率不能超过从设备支持的最大值。配置时先查从设备手册,确认最大SCK频率,然后根据主控时钟计算分频系数。速率过高会导致数据错误,速率过低则影响吞吐量。

6. 常见问题排查与避坑指南

6.1 UART通信异常排查

UART通信出问题,表现通常是收不到数据、收到乱码、或者偶尔丢数据。排查顺序建议如下:

现象可能原因排查方法
完全无数据接线错误、波特率不匹配、引脚复用未配置检查TX/RX是否交叉连接,用示波器看TX是否有波形
收到乱码波特率偏差、数据位/校验位配置不一致核对双方配置,测量实际波特率
偶尔丢数据中断优先级过低、缓冲区溢出提高中断优先级,增大缓冲区,使用DMA
数据错位停止位配置错误、噪声干扰检查停止位设置,缩短走线或加屏蔽

我遇到过一个很隐蔽的问题:UART接收中断中做了太多事情,导致下一个字节到来时还没来得及读取数据寄存器,产生了溢出错误。后来把中断处理简化成只存数据,复杂处理放到主循环,问题就解决了。

6.2 I2C总线死锁与恢复

I2C最常见的问题是总线死锁。现象是SCL或SDA被某个设备一直拉低,主设备无法发起新的通信。造成死锁的原因通常是通信过程中从设备复位或断电,导致它没有释放总线。

解决方法是手动模拟时钟脉冲,让从设备释放总线。具体操作是:将SCL配置为普通GPIO,发送9个时钟脉冲,然后发送停止条件。大部分情况下这能恢复总线。

// I2C总线恢复示例(伪代码) void i2c_bus_recovery(void) { // 将SCL和SDA配置为普通GPIO gpio_set_output(SCL_PIN); gpio_set_input(SDA_PIN); // 发送9个时钟脉冲 for (int i = 0; i < 9; i++) { gpio_write(SCL_PIN, 0); delay_us(5); gpio_write(SCL_PIN, 1); delay_us(5); } // 发送停止条件:SCL高时SDA由低变高 gpio_set_output(SDA_PIN); gpio_write(SDA_PIN, 0); delay_us(5); gpio_write(SCL_PIN, 1); delay_us(5); gpio_write(SDA_PIN, 1); delay_us(5); // 重新初始化I2C外设 i2c_init(); }

提示:上拉电阻的选择对I2C稳定性影响很大。如果总线上设备较多或走线较长,建议用2.2kΩ到4.7kΩ的电阻。电阻太大时上升沿变缓,可能导致时序不满足要求。

6.3 SPI数据错误的典型原因

SPI通信出错,最常见的原因是模式不匹配。CPOL和CPHA设置错误会导致数据在错误的边沿被采样,读回来的数据完全不对。其次是片选控制不当,有些芯片要求片选在字节之间也保持低电平,如果代码中每个字节都拉高片选,芯片可能无法正确解析。

还有一个容易忽略的问题是时钟速率过高。SPI的时钟频率受限于从设备的响应速度、走线长度和寄生电容。如果发现数据偶尔出错,可以尝试降低时钟频率。我在驱动一块OLED屏时,20MHz下偶尔花屏,降到10MHz后完全稳定。

另外,SPI的MISO引脚在片选未选中时可能处于高阻态,如果主控的MISO引脚没有配置上拉或下拉,可能读到随机数据。建议在MISO上加上拉电阻,或者在软件中忽略未选中设备的返回值。

6.4 三种协议共通的硬件注意事项

不管用哪种协议,有几个硬件层面的问题都需要注意。电源去耦是基础,每颗芯片的电源引脚附近都要放0.1μF的陶瓷电容,必要时再加一个10μF的钽电容。地线要尽量粗,回流路径要短。信号线避免与高频或大电流线路平行走线。

连接器接触不良也是常见问题。排线、杜邦线在振动环境下容易松动,导致通信时好时坏。如果项目需要长期稳定运行,建议使用带锁扣的连接器,或者直接焊接。

实操心得:调试通信协议时,我习惯先降低速率到最低档,确认基本通信正常后再逐步提高。这样可以把速率相关的问题和其他问题分开排查,效率高很多。

7. 进阶应用与组合使用场景

7.1 协议转换与桥接

实际项目中,经常遇到主控只有一种接口但外设需要另一种接口的情况。比如主控只有UART,但传感器是I2C接口。这时候可以用一颗带协议转换功能的MCU做桥接,或者使用专用的转换芯片。

软件桥接的思路是:主控通过UART发送命令给桥接MCU,桥接MCU解析命令后通过I2C读写传感器,再把结果通过UART返回。这种方案灵活度高,但增加了成本和开发工作量。硬件桥接芯片如SC16IS752可以把I2C转成UART,使用起来更简单,但功能受限。

7.2 多协议共存时的资源分配

一个稍微复杂的系统往往同时使用多种协议。比如主控通过SPI驱动显示屏,通过I2C读取传感器,通过UART与上位机通信。这时候需要注意引脚分配、中断优先级和DMA通道的冲突。

引脚分配上,尽量把高速信号(SPI时钟)和低速信号(I2C)分开,避免相互干扰。中断优先级上,实时性要求高的(比如UART接收)设高优先级,低速的(比如I2C传感器读取)设低优先级。DMA通道如果不够用,可以把低速数据传输改成中断方式。

7.3 从协议层面看通信可靠性设计

不管用哪种协议,可靠性设计都是绕不开的话题。软件层面可以加CRC校验、重传机制、超时检测。硬件层面可以加TVS管防静电、加磁珠滤高频噪声、加隔离芯片防地环路。

我在一个工业采集项目中,I2C传感器偶尔会返回错误数据。后来在软件中加了CRC校验和三次重读机制,错误率降到了可接受范围。又在硬件上给I2C总线加了磁珠和TVS管,进一步提高了稳定性。这种软硬结合的思路,比单纯依赖某一种手段更有效。

提示:CRC校验会增加通信开销,对于低速总线可能影响吞吐量。如果数据量很小,可以用简单的校验和代替CRC。如果数据量较大且对可靠性要求高,CRC是更好的选择。

8. 我个人在实际项目中的选型体会

干了这么多年嵌入式,我对这三种协议的感情挺复杂的。UART是最早接触的,也是最容易上手的,但它的点对点限制在某些项目里确实让人头疼。I2C一度是我最喜欢的协议,两根线挂一堆设备的感觉很优雅,但总线死锁和上拉电阻的坑也没少踩。SPI是最后才用顺手的,一开始觉得四根线太麻烦,后来发现它的速度和灵活性是另外两种协议比不了的。

如果让我给新手一个建议,我会说:不要试图记住所有参数和时序,而是理解每种协议的设计哲学。UART是为简单点对点通信设计的,I2C是为多设备低速总线设计的,SPI是为高速数据传输设计的。理解了这一点,选型时就不会迷茫。

另外,逻辑分析仪真的是调试通信协议的神器。几百块钱的入门款就能解码UART、I2C、SPI,把波形和协议内容对应起来看,很多问题一眼就能定位。比起盲目改代码,先用工具看清楚总线上的实际情况,效率高得多。

最后分享一个小技巧:在项目初期做硬件设计时,可以给每种协议都预留测试点和上拉电阻位置。即使当前方案不用,后续调试或功能扩展时可能会用到。PCB改版的成本远高于多留几个焊盘的成本。这个习惯帮我省过好几次事,推荐你也试试。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/18 1:01:24

ESP32-C3 Super Mini 连不上WiFi?从供电到NVS的排查手册

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/18 1:01:24

STM32+FreeRTOS+MQTT接入阿里云物联网平台全流程实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/18 1:00:48

GD32H759 RT-Thread USB CDC ACM虚拟串口配置与实战避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/18 0:58:50

网络分段标准化构建:从规划到运维的完整落地指南

有一类项目&#xff0c;接单时客户就扔过来一句话&#xff1a;"我们网络太乱了&#xff0c;合规审查提了一堆整改项&#xff0c;今年必须把网络分段做掉。"听起来好像就是把几个网段隔开、加几条策略的事&#xff0c;实际从规划走到上线再走到稳定运维&#xff0c;少…

作者头像 李华
网站建设 2026/10/18 0:54:37

AI伙伴全栈实战:云端Agent、边缘视觉与端侧硬件的三层架构详解

我最早做AI伙伴项目时&#xff0c;踩过一个特别大的坑&#xff1a;以为“AI伙伴”就是接一个大模型API&#xff0c;能聊天就完事了。结果做到第三个月&#xff0c;这台机器人才算真正“活”过来——它能在我喊它名字时转头&#xff0c;能认出桌上的水杯&#xff0c;能在断网时依…

作者头像 李华