news 2026/10/14 16:49:58

UART、SPI、I²C总线选型指南:从原理到实战避坑

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UART、SPI、I²C总线选型指南:从原理到实战避坑

1. 三种总线的本质差异与选型逻辑

1.1 先搞清楚它们到底在解决什么问题

做嵌入式开发的人,绕不开UART、SPI、I²C这三个名字。新手看到它们的第一反应往往是“都是串行通信,能连外设就行”,但真到了画板子、写驱动的时候,选错了总线,轻则调试三天找不到问题,重则整版PCB推倒重来。我自己就经历过因为I²C上挂了一个地址冲突的传感器,导致整条总线间歇性挂死,最后不得不飞线改板的事故。

这三个总线的本质差异,不在于“谁更快”,而在于它们各自的设计哲学完全不同。UART解决的是“两个设备之间点对点、异步、不需要时钟线”的通信问题;SPI解决的是“一个主设备带多个从设备、高速、全双工、需要片选”的通信问题;I²C解决的是“两个信号线挂一堆设备、地址寻址、速度要求不高但布线极简”的通信问题。理解了这个层次,选型就有了根基。

从硬件资源角度看,UART通常只需要两根线(TX、RX),SPI需要四根线(SCLK、MOSI、MISO、CS),I²C只需要两根线(SCL、SDA)。但线数少不代表简单,I²C的协议复杂度反而是三者中最高的,因为要处理起始条件、停止条件、应答位、时钟拉伸、仲裁等机制。SPI协议最简单,基本上就是把数据移位出去再移位进来,但每增加一个从设备就要多一根片选线。UART最“古老”,但因为没有时钟线,收发双方必须提前约定好波特率,一旦波特率偏差超过容忍范围,通信就会出错。

1.2 选型时最该先问自己的四个问题

我在实际项目中总结出一个选型决策顺序,每次遇到新外设,先问自己这四个问题:

第一,通信距离有多远?板内通信和板间通信的选型逻辑完全不同。UART在板内可以跑到几兆波特率,但出了板子走排线,超过几十厘米就容易受干扰,通常需要加收发器芯片转成差分信号。I²C设计之初就是板内总线,规范建议走线不超过几十厘米,实际项目中超过20厘米就要谨慎评估。SPI同样适合板内短距离,高速模式下走线长度更受限。

第二,需要挂多少个设备?如果只有一个外设,UART和SPI都很合适。如果需要挂多个同类型传感器,I²C的地址寻址优势就体现出来了。SPI挂多个设备需要多个片选引脚,如果主控引脚紧张,就要加译码器或者用菊花链方式,复杂度上升。

第三,速度要求是多少?这里要区分“够用”和“越快越好”。一个温度传感器每秒读一次,I²C的100kHz标准模式绰绰有余。但如果是TFT屏幕或者高速ADC,SPI的几十兆赫兹才能满足。UART的速度通常介于两者之间,常见波特率从9600到几兆不等。

第四,主控和外设的引脚资源是否紧张?这是最现实的问题。很多低成本MCU的引脚数量有限,如果已经用了I²C挂EEPROM和传感器,再增加一个SPI屏幕可能引脚就不够了。这时候要么换主控,要么用I²C接口的屏幕(速度会慢),要么用UART接口的屏幕(通常内置驱动芯片)。

1.3 一张表看清三者的核心参数对比

特性UARTSPII²C
信号线数量2(TX/RX)4(SCLK/MOSI/MISO/CS)2(SCL/SDA)
通信方式异步同步同步
双工方式全双工全双工半双工
拓扑结构点对点一主多从(片选)一主多从(地址)
典型速率9600bps~几Mbps几Mbps~几十Mbps100kHz~几MHz
时钟线无有有
应答机制无(可选校验)无有(ACK/NACK)
多主支持不支持不支持支持(仲裁)
引脚开销低高(每从设备一根CS)低
协议复杂度低低中高
典型应用调试口、GPS、蓝牙模块Flash、屏幕、ADC传感器、EEPROM、RTC

这张表不是让你背的,而是让你在选型时快速定位。比如你拿到一个外设,先看它支持哪些接口,然后对照这张表,看哪个接口的“代价”最小。很多时候外设同时支持SPI和I²C,这时候就要看你的主控资源、速度需求和布线难度来综合判断。

2. 三种总线的协议细节与硬件设计要点

2.1 UART:最简单也最容易踩坑的异步通信

UART的全称是通用异步收发器,关键词是“异步”。它没有时钟线,收发双方靠预先约定的波特率来同步。一个完整的UART帧包括起始位、数据位、校验位和停止位。起始位是一个下降沿,接收方检测到这个下降沿后,按照约定的波特率在每一位的中间时刻采样。

这里有个容易被忽略的细节:波特率误差。假设主控时钟是12MHz,你想用115200的波特率,分频系数是12M/115200≈104.17,不是整数。如果取104,实际波特率是115384,误差约0.16%,在容忍范围内。但如果时钟是8MHz,分频系数是69.44,取69的话实际波特率是115942,误差约0.64%,接近容忍极限。很多新手调试UART收不到数据,第一反应是接线问题,实际上可能是波特率误差太大。我的经验是,选主控时钟频率时,尽量选能被常用波特率整除的值,比如7.3728MHz、11.0592MHz、14.7456MHz这些“奇怪”的频率,就是为了UART分频方便。

UART的硬件连接也有讲究。TX接对方的RX,RX接对方的TX,这是最基本的。但如果两个设备电平标准不同,比如一个是3.3V一个是5V,直接连可能烧毁IO口。这时候需要电平转换电路,最简单的方案是用两个电阻分压,但分压会影响上升沿速度,高速通信时不推荐。更稳妥的方案是用专用的电平转换芯片,或者用MOS管搭建双向电平转换电路。

注意:UART的TX和RX千万不要接反,虽然有些芯片内部有保护,但接反了通信肯定不通。调试时先用示波器看TX脚有没有波形输出,这是最快的排查方法。

2.2 SPI:速度最快但引脚开销最大的同步总线

SPI的全称是串行外设接口,它的协议简单到可以用一句话概括:主机拉低片选,然后在时钟的边沿把数据移出去,同时在另一个边沿把数据移进来。SPI有四种模式,由时钟极性(CPOL)和时钟相位(CPHA)组合而成。CPOL决定空闲时时钟是高还是低,CPHA决定在第一个边沿还是第二个边沿采样。

这四种模式是新手最容易搞混的地方。我教过一个简单的记忆方法:CPOL看空闲电平,CPHA看采样边沿。模式0(CPOL=0,CPHA=0)是最常用的,空闲低电平,上升沿采样。模式3(CPOL=1,CPHA=1)也很常见,空闲高电平,下降沿采样。模式1和模式2用得相对少。关键是,主从设备的模式必须一致,否则数据会错位。如果你发现读出来的数据总是差一位或者全是0xFF,先检查SPI模式。

SPI的片选信号设计也有讲究。每个从设备需要一根独立的片选线,如果从设备多,主控引脚不够用,可以用3-8译码器来扩展。但译码器会引入额外的传播延迟,高速通信时要算进时序余量。另一个方案是菊花链,所有从设备的MOSI和MISO串联,数据像流水一样穿过所有设备,但这种方式要求从设备支持菊花链模式,不是所有SPI设备都支持。

SPI的PCB布线是硬件工程师的基本功。SCLK是时钟线,频率高,要走等长线,尽量短,远离模拟信号。MOSI和MISO是数据线,相对宽松一些,但也要注意不要跨分割地平面。如果SPI速率超过10MHz,建议在源端串接22Ω到33Ω的电阻,抑制过冲和振铃。我见过一个项目,SPI屏幕花屏,查了半天是时钟线走得太长,加了串阻就稳定了。

2.3 I²C:两根线挂一堆设备的代价是协议复杂度

I²C的全称是集成电路总线,它的精髓在于“两根线挂一堆设备”。SCL是时钟线,SDA是数据线,两根线都要接上拉电阻。上拉电阻的取值是个经典问题:太大则上升沿太慢,太小则功耗太高。标准模式100kHz下,4.7kΩ是常见值;快速模式400kHz下,2.2kΩ到4.7kΩ都可以;高速模式几MHz下,上拉电阻要更小,但很多MCU的IO口灌电流能力有限,这时候要用有源上拉或者专用I²C缓冲器。

I²C的协议比UART和SPI复杂得多。一次完整的传输包括起始条件、地址帧、数据帧、停止条件。起始条件是SCL高时SDA从高变低,停止条件是SCL高时SDA从低变高。地址帧是7位地址加1位读写位,从设备收到匹配的地址后拉低SDA作为应答。如果从设备没有应答,主机就会收到NACK,通常意味着从设备不存在或者地址错了。

时钟拉伸是I²C的一个特色机制。从设备如果处理不过来,可以把SCL拉低,强制主机等待。这个机制很实用,但也会带来问题:如果从设备固件有bug,一直拉低SCL不放,整条总线就挂死了。我遇到过一款传感器,上电后如果初始化时序不对,就会一直拉低SCL,导致同一总线上的EEPROM也读不了。解决办法是在SCL和SDA上加一个总线复位电路,或者用带复位功能的I²C缓冲器。

I²C的地址冲突是另一个常见坑。很多传感器地址是固定的,比如某款温度传感器地址是0x48,另一款EEPROM地址也是0x48,挂在一起就冲突了。有些传感器提供了地址选择引脚,可以改地址;有些则没有,只能换型号或者用I²C多路复用器。选型时一定要确认地址是否可配,这是血泪教训。

提示:I²C总线上所有设备的地必须共地,否则电平参考不一致,通信会随机出错。如果两个模块来自不同的电源域,建议用I²C隔离器,既解决地电位差问题,又提高抗干扰能力。

3. 实际项目中的选型案例与配置方法

3.1 案例一:环境监测节点,多个传感器如何选总线

假设你要做一个环境监测节点,需要接温度、湿度、气压、光照四个传感器,主控是一款低功耗MCU,引脚数量中等,电池供电,对功耗敏感。这种情况下,I²C几乎是唯一合理的选择。四个传感器如果都用SPI,需要四根片选线加三根共用线,一共七根线;用I²C只需要两根线,而且大部分环境传感器都原生支持I²C。

但这里有个细节:上拉电阻和总线电容。I²C规范规定总线电容不能超过400pF,每个设备的引脚有几十pF的电容,走线也有电容。如果四个传感器分布在板子不同位置,走线总长度可能超过30厘米,电容很容易超标。这时候要么减小上拉电阻(增加功耗),要么用I²C缓冲器把总线分段。我的做法是,在板子布局阶段就把I²C设备尽量放近,走线控制在10厘米以内,上拉电阻用2.2kΩ,实测400kHz下波形依然干净。

功耗方面,I²C的上拉电阻在空闲时会有持续电流。假设上拉电阻2.2kΩ,电源3.3V,空闲时SDA和SCL都是高电平,每个电阻上的电流是1.5mA,两个电阻就是3mA。对于电池供电的设备,这个电流不算小。解决办法是选用更大的上拉电阻,比如10kΩ,但这样上升沿会变慢,高速通信可能不达标。折中方案是:通信时用低阻上拉,空闲时断开上拉,用MOS管切换。不过这样会增加电路复杂度,需要根据实际功耗预算来权衡。

3.2 案例二:高速数据采集,SPI如何配置才能跑满速率

另一个项目是高速数据采集,用一个12位ADC,采样率要求1MSPS,数据通过SPI传给主控。ADC支持SPI模式0,最高时钟20MHz。主控的SPI时钟可以配置到系统时钟的一半,系统时钟100MHz,所以SPI时钟可以到50MHz,但ADC只支持20MHz,所以配置为20MHz。

这里的关键是时序计算。SPI时钟20MHz,周期50ns。ADC的数据建立时间是10ns,保持时间是5ns。主控在时钟上升沿采样,那么数据必须在上升沿前10ns就稳定。ADC在时钟下降沿输出数据,下降沿到上升沿是25ns,减去ADC的输出延迟(假设15ns),还剩10ns,刚好满足建立时间。如果ADC的输出延迟更大,或者主控的采样时间更早,就可能采到不稳定的数据。这时候要么降低SPI时钟,要么调整SPI模式,让采样发生在下降沿。

实际调试时,我先用逻辑分析仪抓了SPI波形,确认时钟频率和模式正确,然后看数据线在采样沿附近是否稳定。如果发现数据跳变沿离采样沿太近,就降低时钟频率或者换SPI模式。最终这个项目跑在15MHz,留了25%的余量,连续采集一小时没有丢数据。

注意:SPI的MISO线在主设备不发起传输时是高阻态,如果从设备的片选没有正确拉高,MISO可能会被从设备驱动,导致总线冲突。调试时如果发现MISO电平异常,先检查所有从设备的片选信号。

3.3 案例三:调试口和固件升级,UART的不可替代性

UART虽然“古老”,但在调试和固件升级场景中几乎不可替代。几乎所有的MCU都有UART,几乎所有的开发板都引出了UART调试口。打印日志、输入命令、升级固件,UART都是最方便的选择。原因很简单:UART不需要时钟线,对时序要求宽松,而且PC端的串口工具极其成熟。

但UART调试口也有坑。最常见的是波特率不匹配。PC端串口工具默认可能是9600,而MCU固件用的是115200,打开串口看到一堆乱码,新手往往以为是固件问题。我的习惯是,在固件启动时先打印一段固定的字符串,比如“BOOT OK”,这样即使波特率不对,也能看到有规律的乱码,从而判断是波特率问题而不是固件没跑起来。

另一个坑是流控。如果MCU和PC之间数据量较大,没有流控的话,PC端缓冲区满了就会丢数据。硬件流控需要额外的RTS和CTS线,很多USB转串口模块不支持。软件流控用XON/XOFF字符,但二进制数据中可能恰好出现这些字符,导致误判。我的做法是,调试日志用文本格式,避免二进制数据,同时PC端用支持大缓冲区的工具,降低丢数据概率。

固件升级场景下,UART的可靠性很重要。我通常会在协议层加校验和重传机制。每包数据带CRC校验,接收方校验失败就发NACK,发送方重传。虽然UART本身没有应答机制,但在应用层加上这些,可靠性不输于I²C。升级速度方面,115200波特率下,传输1MB固件大约需要90秒,可以接受。如果嫌慢,可以提高到921600甚至更高,但要注意线材质量和干扰。

4. 常见问题排查与实战避坑指南

4.1 通信完全不通,怎么快速定位

通信不通是最常见的问题,排查要讲顺序,不要东一榔头西一棒子。我的排查顺序是:先看电源和地,再看时钟和信号,最后看协议配置。

电源和地的问题占了一半以上。两个设备通信,地必须连在一起,否则电平没有参考。我见过一个案例,两个模块用UART通信,TX和RX都接了,但地没接,结果通信时好时坏。原因是两个模块各自的地电位不同,共模电压超出了接收器的容忍范围。接上地线后问题消失。

时钟和信号的问题用示波器看最直接。UART看TX脚有没有波形,SPI看SCLK有没有时钟,I²C看SCL和SDA有没有起始条件。如果波形幅度不对,检查上拉电阻和电源电压。如果波形有毛刺,检查走线和干扰源。如果完全没有波形,检查引脚配置是否正确,有没有被复用成其他功能。

协议配置的问题最隐蔽。UART的波特率、数据位、停止位、校验位,SPI的模式、位序、片选极性,I²C的地址、速率,任何一个不对都会导致通信失败。我的经验是,先用最简单的配置跑通,再逐步调整。比如SPI先用1MHz、模式0、MSB优先,跑通了再提高速率、换模式。

4.2 通信时好时坏,间歇性出错怎么查

间歇性出错比完全不通更难查,因为问题不是一直存在。常见原因有:时序余量不足、干扰、电源波动、总线冲突。

时序余量不足的典型表现是,常温下正常,高温或低温下出错;或者低速正常,高速出错。解决办法是留足余量,SPI时钟不要用到极限,I²C上拉电阻不要太大,UART波特率误差控制在2%以内。

干扰问题在电机、继电器、无线模块附近特别常见。SPI和I²C的时钟线是主要的干扰接收天线。解决办法包括:缩短走线、远离干扰源、加屏蔽、加滤波电容、降低速率。我做过一个项目,I²C传感器在电机启动时必挂,后来在SCL和SDA上各加了一个100pF的电容到地,问题解决。但电容不能太大,否则上升沿变慢,高速通信会出错。

电源波动也会导致间歇性出错。如果主控和外设用同一个电源,外设突然大电流工作时,电源电压跌落,可能导致通信失败。解决办法是给外设单独加去耦电容,或者用独立的LDO供电。

总线冲突在多主I²C系统中可能出现。两个主机同时发起传输,I²C有仲裁机制,但仲裁失败的主机需要重新发起。如果固件没有正确处理仲裁失败,就可能出现间歇性错误。SPI没有仲裁机制,多主系统需要额外的硬件协调,一般不建议。

4.3 常见问题速查表

现象可能原因排查方法解决措施
UART收不到数据TX/RX接反交换TX/RX测试更正接线
UART乱码波特率不匹配检查双方波特率配置统一波特率
UART偶尔丢数据无流控、缓冲区溢出降低速率、加流控应用层加校验重传
SPI读全0xFF片选未拉低、模式错误示波器看CS和SCLK检查片选和SPI模式
SPI数据错位位序错误、模式不匹配对比主从模式配置统一位序和模式
SPI高速出错时序余量不足降低速率测试降低时钟、加串阻
I²C无应答地址错误、设备未供电示波器看地址帧检查地址和供电
I²C总线挂死从设备拉低SCL不放测量SCL电平加总线复位电路
I²C间歇出错上拉电阻过大、电容超标测量上升沿时间减小上拉、分段缓冲
多设备I²C冲突地址重复逐个挂载测试改地址或用多路复用器

这张表是我自己踩坑总结的,不一定覆盖所有情况,但能解决八成以上的常见问题。遇到新问题,先对照这张表,找不到再深入分析。

4.4 几个容易被忽略的实战技巧

技巧一:UART调试口加一个LED指示。在固件的UART发送函数里翻转一个GPIO,接LED。这样即使没有示波器,也能通过LED闪烁判断固件有没有在发送数据。如果LED不闪,说明固件卡在别的地方了。

技巧二:SPI片选信号加下拉电阻。主控复位时,IO口是高阻态,片选信号可能浮动,导致从设备误触发。加一个10kΩ下拉电阻,确保复位期间片选为低(假设低有效),从设备不会误动作。

技巧三:I²C上拉电阻靠近主控放置。上拉电阻的位置影响上升沿波形。放在主控端,整个总线的电容都由主控端的强驱动来充电,上升沿更快。放在从设备端,主控到从设备的走线电容会导致上升沿变慢。

技巧四:SPI的MISO线加一个缓冲器。如果从设备多,MISO线的电容大,高速通信时上升沿变慢。加一个缓冲器可以隔离电容,提高信号质量。但缓冲器会引入延迟,要算进时序余量。

技巧五:UART的TX和RX加TVS管。如果调试口引出到外部连接器,容易受静电冲击。加TVS管可以保护IO口,成本很低,但能避免很多返修。

这些技巧看起来不起眼,但在实际项目中能省下大量调试时间。我刚开始做嵌入式的时候,觉得这些都是“多余”的,后来踩坑多了才明白,硬件设计上的一个小改动,可能省下软件调试上的三天三夜。

5. 从选型到落地的完整决策流程

5.1 第一步:梳理外设清单和接口需求

拿到一个项目,先把所有需要接的外设列出来,每个外设标注:支持的接口类型、最高速率、数据量大小、是否需要中断、供电电压、封装尺寸。这一步看起来简单,但很多项目后期出问题,就是因为前期没梳理清楚。比如一个传感器支持I²C和SPI,你选了I²C,后来发现数据量大了I²C速度不够,再想换SPI发现引脚已经不够了。

我的习惯是做一个表格,每个外设一行,接口类型、速率、引脚数、地址/片选需求都列清楚。然后统计总引脚需求,和主控的引脚资源对比。如果引脚不够,优先考虑I²C设备,因为I²C最省引脚。如果速度不够,优先考虑SPI设备。UART通常留给调试口或者必须用UART的模块(比如某些蓝牙模块)。

5.2 第二步:评估总线负载和时序余量

选好接口类型后,要评估总线负载。I²C总线要看总电容和上拉电阻的匹配,SPI要看时钟频率和走线长度的匹配,UART要看波特率误差和缓冲区大小。这一步需要一些计算,但不用很精确,留足余量就行。

以I²C为例,假设总线上挂4个设备,每个设备引脚电容10pF,走线电容每厘米1pF,走线总长20厘米,总电容是4×10+20×1=60pF。上拉电阻4.7kΩ,上升时间约等于2.2×R×C=2.2×4700×60e-12≈0.62微秒。I²C快速模式400kHz,周期2.5微秒,上升时间占25%,可以接受。如果总电容到200pF,上升时间2.07微秒,占周期83%,就太慢了,需要减小上拉电阻或者分段缓冲。

SPI的时序余量计算更直接:时钟周期减去从设备输出延迟、走线延迟、主控建立时间,剩下的就是余量。余量至少留20%,否则温度变化或电压波动就可能导致出错。

5.3 第三步:画原理图和PCB时的注意事项

原理图阶段,UART的TX/RX要交叉连接,SPI的片选要一一对应,I²C的上拉电阻不要漏掉。这些看起来是常识,但每年都有新手画错。我的做法是,画完原理图后,用不同颜色的高亮笔把每个总线的信号线标出来,逐个检查连接关系。

PCB布局阶段,SPI的时钟线要短且直,远离模拟信号和电源开关节点。I²C的两根线要并行走,间距保持一致,减少环路面积。UART的TX/RX如果走长线,要考虑串阻匹配。所有总线的走线都不要跨分割地平面,否则回流路径断裂,信号质量会急剧下降。

地平面的处理也很关键。SPI和I²C都是单端信号,参考地平面必须完整。如果板子有多个地平面,要确保总线走线下面的地平面是连续的。我见过一个案例,SPI时钟线跨了模拟地和数字地的分割缝,导致时钟抖动,屏幕显示异常。后来在分割缝上加了缝合电容,问题解决。

5.4 第四步:软件驱动的配置和调试顺序

软件调试要遵循“先通再快”的原则。先把总线速率降到最低,用最简单的配置跑通读写,确认硬件连接和基本协议没问题。然后逐步提高速率,观察波形和误码率。最后加上错误处理和重传机制,提高可靠性。

UART的调试顺序:配置GPIO复用→配置波特率→发送固定字符串→PC端接收确认→接收PC端数据→加校验和重传。

SPI的调试顺序:配置GPIO复用→配置SPI模式→拉低片选→发送一个字节→读回一个字节→确认数据正确→提高速率→加DMA。

I²C的调试顺序:配置GPIO复用→配置I²C速率→发送起始条件→发送地址→检查ACK→发送寄存器地址→读数据→确认数据正确→加错误处理。

每个步骤都要用示波器或逻辑分析仪确认波形,不要只靠打印信息判断。打印信息可能因为缓冲区或中断问题而失真,波形是最真实的。

5.5 第五步:量产前的可靠性验证

样品阶段跑通不代表量产没问题。量产前要做几项验证:高低温测试、电压拉偏测试、长时间老化测试、EMC测试。

高低温测试可以发现时序余量不足的问题。有些SPI设备在低温下输出延迟变大,常温下正常的时序在低温下就出错了。电压拉偏测试可以发现电源波动导致的问题。长时间老化测试可以发现间歇性故障。EMC测试可以发现干扰问题。

我经历过一个项目,样品阶段一切正常,量产时发现千分之三的板子I²C通信失败。查了半天,发现是某批次的传感器芯片引脚电容偏大,加上PCB走线电容,总电容超过了400pF,导致上升沿太慢。后来把上拉电阻从4.7kΩ改成2.2kΩ,问题解决。这个教训告诉我,选型时不仅要看典型值,还要看最坏情况。

提示:量产前一定要做小批量试产,至少50到100片,覆盖不同批次的元器件。试产中发现的问题,比实验室里发现的问题更有价值。

6. 一些个人体会和后续扩展方向

6.1 我踩过的那些坑

做嵌入式这些年,UART、SPI、I²C的坑我基本都踩过一遍。最惨的一次是一个项目用了I²C的EEPROM存储配置参数,量产时发现部分板子配置丢失。查了三天,发现是EEPROM的写周期需要5毫秒,而固件在写完之后立刻读,读到了旧数据。后来在写和读之间加了10毫秒延时,问题解决。这个坑让我明白,数据手册上的时序参数不是摆设,每一个都要认真对待。

还有一次是SPI屏幕的片选信号被复用成了其他功能,固件初始化时忘了重新配置,导致屏幕一直不亮。查了半天硬件,最后发现是软件配置问题。从那以后,我养成了一个习惯:每个总线的引脚配置都写在一个独立的初始化函数里,上电后统一调用,避免遗漏。

UART的坑相对少一些,但有一次是PC端串口工具的流控设置和MCU不一致,导致数据丢失。后来我在固件里加了软件流控,PC端也配置成软件流控,问题解决。但软件流控对二进制数据不友好,所以后来调试日志都改成文本格式了。

6.2 后续可以扩展的方向

这三个总线是嵌入式的基础,但实际项目中还会遇到更复杂的场景。比如多主I²C系统,需要处理仲裁和时钟同步;SPI的DMA传输,可以大幅降低CPU占用;UART的DMA加空闲中断,可以实现不定长数据接收。这些进阶用法我后续可以单独写文章展开。

另一个方向是总线扩展。I²C设备多了可以用多路复用器,SPI设备多了可以用译码器或者菊花链,UART设备多了可以用多路复用器或者软件模拟。这些扩展方案各有优劣,选型时要考虑成本、复杂度、可靠性。

还有电平转换和隔离。不同电压域的设备通信需要电平转换,工业现场还需要隔离。这些电路的设计和选型也有不少讲究,后续可以专门聊。

6.3 给新手的几点建议

如果你是刚接触嵌入式的新手,我的建议是:先把UART玩透,再学SPI,最后学I²C。UART最简单,适合理解串行通信的基本概念。SPI协议简单但硬件设计有讲究,适合学习时序和PCB布局。I²C协议复杂但应用广泛,适合学习状态机和错误处理。

调试工具方面,逻辑分析仪是必备的。一个几十块钱的入门级逻辑分析仪,能抓UART、SPI、I²C的波形,还能自动解码,比示波器更方便。我刚开始学的时候没有逻辑分析仪,靠示波器和打印信息调试,效率很低。后来买了逻辑分析仪,调试效率至少提高三倍。

最后,多动手,多踩坑。看再多的文章,不如自己画一块板子、写一遍驱动。踩过的坑才是真正学到的知识。我到现在还记得第一次用I²C读EEPROM失败时的困惑,以及后来发现是上拉电阻没接时的恍然大悟。这些经历比任何教程都深刻。

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

C++知识地图:从语法到对象模型的系统学习路线

1. 为什么我建议每个C学习者都该有一张自己的知识地图刚入行那几年,我学C的方式特别“野”:今天看两章《C Primer》,明天刷几道算法题,后天又去折腾模板元编程。结果就是——面试时被问到“虚函数表在多重继承下怎么布局”能答个七…

作者头像 李华
网站建设 2026/10/14 16:49:48

那些又爱又恨的槽点

1. 引言:为什么开源项目也需要吐槽 开源项目为技术世界贡献了无数优秀的工具和框架,但并非所有开源项目都完美无瑕。文档缺失、API 频繁变动、社区维护不力等问题,常常让开发者在使用过程中又爱又恨。本文以轻松吐槽的方式,盘点开…

作者头像 李华
网站建设 2026/10/14 16:48:56

博途SCL编码器圈数与单圈脉冲计算算法详解

1. 项目背景与核心需求拆解在工业自动化现场,编码器就像设备的“眼睛”,它把机械轴的旋转角度、速度、位移这些物理量,转换成PLC能读懂的脉冲信号。但问题来了——PLC读到的永远只是一串脉冲数,而操作人员关心的是“转了多少圈”“…

作者头像 李华
网站建设 2026/10/14 16:48:47

HW8227安卓导航刷机指南:系统固件与MCU升级从识别到排查

简介:安卓导航HW8227车机系统刷机固件及MCU升级资料包,面向需要刷机、修改协议或恢复系统的车主、维修人员与玩机爱好者。压缩包约511MB,共22个文件,包含bin格式系统分区镜像与bootloader、ext4系统镜像、gz/tar压缩的内核与根文件…

作者头像 李华
网站建设 2026/10/14 16:48:45

嵌入式面试必考:UART、I2C、SPI串行总线高频考点详解

很多朋友在准备嵌入式岗位面试时,都会在简历上写一句"熟悉UART、I2C、SPI"。这句话我看了太多次,而面试时真正能把这三条串行总线讲透的人,确实不多。之前帮我带过的几位新人做模拟面试,光是"SPI和I2C的区别"…

作者头像 李华
网站建设 2026/10/14 16:47:43

企业微信机器人开发实战:回调加解密与Spring Boot集成全攻略

去年有个内部项目,需要把工单状态变化、服务器异常告警、发布流水线结果全部实时推到企业微信。一开始大家觉得简单,调个接口发条消息而已,结果从回调握手到消息加解密,折腾了整整一周。这篇文章就把当时踩过的坑和最终沉淀的集成…

作者头像 李华