news 2026/9/25 7:32:20

一文读懂I2C、SPI、I2S、UART:串行通信选型与时序分析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一文读懂I2C、SPI、I2S、UART:串行通信选型与时序分析

1. 先用一张"出行方式"的图看懂四种串行协议

我做了这么多年硬件,发现一个挺有意思的现象:很多刚入行的朋友一听到 I2C、SPI、UART、I2S 这四个名字,第一反应是"又要背协议了",然后就是拿着数据手册啃时序图,越啃越晕。其实换个角度,把这四种协议想象成四种城市交通方式,瞬间就好记多了。

  • I2C 是公交车:两根线(SDA 数据线、SCL 时钟线),一条线路挂很多站点(设备),有地址,上下车要遵守规则(起始/停止条件),速度不快,但胜在布线省。
  • SPI 是高速专线小巴:四根线(MOSI、MISO、SCLK、CS),专车接送,一对一或一对几,跑得快,实时性好,但每接一个新设备通常要占一根片选线。
  • I2S 是音频专用车道:三根线(BCLK、LRCLK、SDATA)专门用来传输数字音频,左右声道轮流上,流水线一样,别拿它传别的数据。
  • UART 是打电话:就两根线(TX、RX),没有时钟线,全靠双方提前约定好"语速"(波特率),一对接一通,简单、通用、方便调试。

这四种协议本质都是串行通信,也就是按位挨个传输数据,但它们面向的场景完全不同。在实际项目中,我经常看到的情况是:一个板子上既有 I2C 挂在传感器和 EEPROM,又有 SPI 连着 ADC 或 Flash,UART 接到调试串口或蓝牙模块,音频部分再用 I2S 连解码芯片。所以理解它们之间的边界和取舍,比死记协议细节更重要。

这篇文章我就结合自己调板子的实际经历,把这四种协议掰开揉碎讲清楚,重点放在它们的设计思路差异、时序图上到底看什么、以及选型时最容易忽略的几个坑上。不管是做单片机开发、Linux 驱动,还是 FPGA 逻辑,这篇都值得先收藏再慢慢看。

提示:这篇文章不教你每一个寄存器的配置,而是帮你建立"选型 → 看时序 → 定位问题"的完整思路。参数我尽量给出典型值和推导过程,方便你对照自己的硬件去延伸。

2. I2C:两根线走天下,但每一处细节都在暗处

2.1 为什么两条线就能挂一堆设备

I2C 的全称是 Inter-Integrated Circuit,1982 年由飞利浦提出。它最核心的设计是:一根数据线 SDA、一根时钟线 SCL,所有设备并联在总线上,通过地址区分彼此。SDA 和 SCL 都是开漏输出,需要外部接上拉电阻到 VCC。

开漏 + 上拉这个设计非常聪明。为什么不用推挽输出?因为如果两个设备同时往总线上写相反的电平,推挽输出会直接短路。开漏输出只会把线拉低,不会主动拉高,拉高全靠上拉电阻,这样即使多个设备同时操作总线也不会打架。

通信流程简单归纳一下:

  • 起始条件:SCL 为高电平时,SDA 从高变低。
  • 地址字节:主机先发送 7 位设备地址 + 1 位读写方向位(0 写、1 读)。
  • ACK:从机收到地址匹配后,在第 9 个时钟周期拉低 SDA 表示应答。
  • 数据阶段:每个字节 8 位,MSB 先行,每字节后跟一个 ACK/NACK。
  • 停止条件:SCL 为高电平时,SDA 从低变高。

实际用起来,你会发现标准模式 100kHz、快速模式 400kHz、高速模式 1MHz,这些速率对应的上升时间要求完全不同。比如 100kHz 时 SDA 和 SCL 上升时间最大 1000ns,400kHz 时就只有 300ns。这也是为什么总线长度不能太长、上拉电阻不能乱选的原因。

2.2 上拉电阻不是随便焊一个 4.7k 完事

很多板子默认放 4.7k 上拉,但如果你做了两块板子,一块是 5V 供电、挂 3 个设备,另一块是 1.8V 供电、挂 8 个设备,还都用 4.7k,大概率会出现如下诡异现象:

  • 电平拉不低:某些从机的输入阈值偏高,电阻太大导致低电平不够低,通讯时好时坏。
  • 波形边沿太缓:上升时间超标,从机采样到的时钟沿位置不对,数据偶尔错位。

上拉电阻的选择其实是个物理计算题,不是我瞎猜。最小值的限制来自器件能灌入的电流,IOL 最大灌电流一般是 3mA,VOL(低电平最大值)在 3.3V 系统中通常是 0.4V,那么最小电阻:

Rmin = (VCC - VOL) / IOL = (3.3 - 0.4) / 0.003 ≈ 967Ω

最大值的限制来自总线电容。总线等效电容约 50pF~100pF,如果需要上升时间不超过 300ns(400kHz 模式),那么从 RC 充电模型可以估算出:

Rmax = Trise / (0.8473 × Cbus) = 300ns / (0.8473 × 100pF) ≈ 3.5kΩ

所以 400kHz 下 4.7k 在某些走线较长、容性负载较重的板子上就显得临界。我的习惯是:低速短走线用 4.7k,高速长走线用 1k~2.2k,低功耗应用在允许上升沿不那么陡的前提下用 10k。别嫌这事琐碎,很多"I2C 偶尔挂死"的玄学问题,最后都查到电阻上去了。

2.3 常见的三个 I2C 老坑

第一坑:地址冲突。一个 I2C 总线上两个设备默认地址相同,又没有地址脚去改,那读写就乱套了。市面上常见的做法是给芯片加 A0/A1/A2 引脚,组合出多个地址。但总设备数超过地址组合上限时,就得用多路复用器(比如 TCA9548A),硬分总线。

第二坑:I2C 从机把 SDA 拉死不放开。这往往发生在从机内部时钟没跑起来、或者额外复位逻辑有缺陷时。表现形式是:主机发起始位后,SDA 一直被拉低,ACK 永远等不到。处理方式一般是在硬件上给 SCL 多打几个时钟,让从机状态机跳出来;严重的就要断电复位。我碰到过 GT911 触摸屏在固件异常时把 I2C 总线钳死的情况,排查了整整一个下午,最后是硬件复位脚解决。

第三坑:I2C 速率不是越高越好。很多传感器数据手册写"支持 1MHz",但实际布线上拉阻容极限摆在那里,1MHz 下上升时间余量很小。稳定的 400kHz 往往比"看似快"的 1MHz 可靠得多。尤其像 Linux 下 i2c-dev 或嵌入式 RTOS 里,别把一个设备速率调高结果导致整条总线上别的从机都不稳定。

2.4 热搜词里说的 PMBus 和 I2C 是什么关系

顺带提一下 PMBus。现在服务器电源管理芯片很流行 PMBus,它本质上就是 I2C 的延伸:物理层沿用 I2C,但约定了一组标准的电源管理命令字(读电压、读电流、设置余量等)。所以你在电源芯片的数据手册里看到的 SDA/SCL/地址位时序,核心还是 I2C 那套,只是命令格式换了。理解 I2C 的底层,PMBus 只是"换了一本字典"而已。

3. SPI:全双工的高速专线,片选信号才是灵魂

3.1 四根线如何做到收发同时进行

SPI(Serial Peripheral Interface)由 Motorola 提出,四根线:

  • SCLK:主机输出的时钟。
  • MOSI(Master Out Slave In):主机输出、从机输入。
  • MISO(Master In Slave Out):从机输出、主机输入。
  • CS/SS:片选,低有效,一条线通常对应一个从机。

SPI 是环形移位寄存器结构:主机和从机各自有一个移位寄存器,每个时钟周期同时移出一位、移入一位,所以一个时钟周期内收发各一位,天然全双工。比如主机写 0xA5 的同时,从机可能把 0x3C 挪回来,这就是 SPI 和 I2C 最大的差异——I2C 读数据时必须先发地址、再切方向、再读回,半双工;SPI 想读想写,同一时刻都在做,全双工。

速度方面,SPI 没有上限标准,完全看器件的极限。常见的 Flash 或 ADC 跑 10MHz~50MHz 很常见,FPGA 和 MCU 之间跑到 66MHz 甚至更高也可以。做高速采样、图片传输、固件更新这类任务时,SPI 几乎是默认选项。

3.2 CPOL 和 CPHA:四种模式区别在哪

这是很多人第一次接触 SPI 时最容易懵的地方。四种模式由两个参数组合而来:

  • CPOL(Clock Polarity):空闲时 SCLK 是高电平还是低电平。
  • CPHA(Clock Phase):数据采样沿是第一个边沿还是第二个边沿。

组合下来就是表里这样:

模式CPOLCPHA采样沿典型器件
Mode 000上升沿绝大多数 Flash、传感器
Mode 101下降沿部分 ADC
Mode 210下降沿部分 LCD 控制器
Mode 311上升沿很多 SPI NOR Flash

我建议你入手任何新器件时,第一件事就是看数据手册里的时序图,数一下"数据在哪个边沿稳定、哪个边沿采样",然后对着寄存器设 CPOL/CPHA。永远不要凭经验默认 Mode 0。我之前调一个 ADS 系列的 ADC,数据手册要求 Mode 2,我用了 Mode 0,结果读回来的数据高几位偶尔跳变,特征就是:大部分数据对,但顶位偶发错误——这种情况排查有多头疼,懂得都懂。

3.3 硬件片选和软件片选怎么选

关于片选,网上每天都在讨论硬件片选和软件片选的取舍。我的实践结论是:

维度硬件片选软件片选
响应速度由外设自动拉低拉高,响应快依赖 CPU 操作 GPIO,有延迟
多设备轮询每个从机一根线,天然理解"现在轮到谁"需要软件管理状态,容易出错
CPU 占用几乎为零每次传输都要操作 GPIO
典型场景高速采集、传感器以固定频率上报低速调试、Linux 下 GPIO 模拟

实际项目里,硬件片选更省心。尤其是 Linux 下的 spi-dev 或 SPI-NOR 驱动,设备树里 cs-gpios 只要配好,内核自己管理拉高拉低。但要注意:硬件片选的高电平恢复时机(CS hold time)得符合从机要求,尤其是 Flash 在读状态寄存器时。有些 Flash 在 CS 拉高的瞬间还希望 SCLK 保持稳定若干 ns,如果你在 FPGA 里实现的 SPI 主机没留这口气,偶尔就会遇到状态读错。

软件片选则更灵活,适合走线紧张、多个从机共用一根片选线再加 GPIO 译码的情形,但速率上来之后,片选的 GPIO 反转时间反而成了瓶颈。所以我的做法是:时钟速率超过 20MHz,尽量用硬件片选;低速且只有两三个从机,软件片选也够用。

3.4 SPI 的进阶玩法:半双工和 DMA

SPI 表面上四线全双工,但很多器件只用部分线:比如只读数据、只发命令、甚至用 MOSI 和 MISO 短接做半双工单总线。STM32 的半双工 SPI 模式,就是把 MOSI 变成双向数据线,适合一些节省引脚的传感器。

另一个高频话题是 SPI + DMA。如果没有 DMA,CPU 每一字节都要等待 SPI 中断,高速传输时 CPU 占用率极其难看。用 DMA 后,比如 STM32 + SPI Flash 刷固件,可以把 CPU 几乎完全解放出来。配置时注意一个细节:DMA 的传输长度要和处理的数据量严格对应,尤其 SPI 全双工时,DMA 的 TX 和 RX 要一起启动,RX 空数据时及时关闭,不然最后多读出来几个字节,校验失败。

另外,FPGA 与 MCU 之间用 SPI 通信,尤其热门。FPGA 端可以做 SPI 从机,MCU 端用 SPI 主机,互补协作。这里最常见的坑是时序约束:FPGA 逻辑里采样时钟边沿要留出足够的建立保持时间,不然高速传输时偶尔丢数据。你在网上一搜"FPGA SPI ADC",几乎一大半问题都出在采样沿选错了。

4. I2S:只为音频而生的流水线协议

4.1 为什么音频非要单独一个协议

很多人第一次看到 I2S 会问:I2C 和 SPI 不是挺通用吗,为什么音频芯片要用专门协议?原因在于数字音频有几个固有的痛:采样率固定、左右声道各一路、位深明确,而且必须严格等时传输——声音只要卡一下或错位,人耳立刻能听出来。

I2S(Inter-IC Sound)由飞利浦在 1986 年制定,总线就三根:

  • BCLK(也叫 SCK 或 WCLK):位时钟,每个 bit 对应一个脉冲。
  • LRCLK(也叫 WS):声道选择时钟,低电平左声道,高电平右声道(Philips 标准)。
  • SDATA:串行数据,二进制补码,MSB 先出。

所以 I2S 本质上就是一个极简的串行协议,但它把时钟关系安排得明明白白:LRCLK 的频率就是采样率(如 44.1kHz),BCLK 的频率是采样率 × 位深 × 通道数。比如 44.1kHz/16bit/双声道就是:

BCLK = 44100 × 16 × 2 = 1.4112MHz

这套关系意味着音频系统中所有设备必须共用同一个时钟域,不然 LRCLK 和 BCLK 无法对齐,声音就撕裂。你看到的那些发烧友整天说的"时钟抖动"“jitter”,就是围绕 BCLK 的稳定性在较劲。

4.2 I2S 时序图怎么看

用逻辑分析仪抓 I2S 波形时,你会看到:

  • BCLK 是连续且等间隔的方波,没有任何停歇。
  • LRCLK 翻转一次代表一个声道完成,翻转频率等于采样率。
  • SDATA 在每个 BCLK 周期里送一个 bit,数据的首位(MSB)与 LRCLK 边沿大概延迟一个 BCLK 周期后出现。

这最后一个"延迟一个 BCLK"是 I2S 标准的经典设计。为什么故意延迟一拍?因为要让接收方能在时钟边沿稳定采样到最高位。有些 DAC 芯片也支持"左对齐"或"DSP 模式"等变体,那时序就和标准 I2S 不太一样了。所以我抓到波形后,第一步永远是拿标准 I2S 的时序图对一下 SDATA 的首位到底和 LRCLK 对齐还是偏了一拍。

逻辑分析仪使用建议:采样率至少比 BCLK 高 10 倍以上,不然边沿位置量化误差太大,看不出延迟。比如 1.4112MHz 的 BCLK,分析仪至少要设 16MHz 以上采样率,如果测 24bit/192kHz,BCLK 到 11.2896MHz,采样率就得开 100MHz 往上。

4.3 主从时钟关系:谁是老板是关键

I2S 通信里,主从关系决定谁产生时钟。常见两种接法:

  • MCU 做主机:MCU 产生 BCLK 和 LRCLK,DAC 被动接收。这种接法最简单,MCU 内部音频外设直接输出。
  • DAC 做主机:DAC 自己产生时钟,MCU 只读数据。这常见于一些高精度音频方案,因为时钟源离 DAC 近,抖动更小。

问题来了:如果两边的时钟不是同一个源头,而系统中又同时有 MCU 产生的其他时钟,就可能出现采样率不一致,最终表现为音频慢慢变调。所以设计上我建议,音频相关系统尽量保证 MCLK(主时钟)统一供给,MCU、DAC、音频 PLL 共用一个晶振或时钟芯片。

MCLK 本身又是另一个容易遗漏的引脚。有些 DAC 需要 MCLK(典型是采样率 × 256 或 × 512),有些内置 PLL 不需要。如果你用的是需要 MCLK 的芯片,而代码里没初始化对应引脚,解码器会一直静音,但 I2S 数据波形是正常的——这种"波形正常但不响"的问题,排查起来相当的绕。

4.4 I2S 和 PDM/TDM 的扩展

现代音频系统里还冒出来两个兄弟:PDM 和 TDM。

PDM 用一根数据线把一个 bit 当"密度调制"送出来,适合麦克风阵列,因为走线少。但 PDM 不是 I2S,时序上它只有一根时钟一根数据,数据处理也是在 MCU 内部做滤波,而不是直接解码成 PCM。做低成本的语音采集方案时,很多 MEMS 麦克风都是 PDM 输出,这时你的 MCU 得自带 PDM 接口或者外挂解码芯片。

TDM 则可以理解为"多声道的 I2S":一条数据线上分时隙跑 4 个、8 个甚至 16 个声道。汽车音响、多声道 DSP 方案里非常常见。如果你看到芯片手册上写"TDM512"或者"I2S/TDM 共享引脚",其实就是这个意思。有了 TDM 之后,I2S 那套 LRCLK 的含义变成了"帧同步信号",不再简单对应左右声道。

5. UART:没时钟还能稳定通信,凭的是性能预留

5.1 靠波特率约定好"语速"

UART(Universal Asynchronous Receiver/Transmitter)是四种协议里物理层最"朴素"的:就一根 TX、一根 RX,双方没有共享时钟,必须在通信前约定好波特率(每秒传输的码元数,即 bit/s)。

为什么没有时钟还能通信?因为 UART 是一帧一帧异步传输的。发送方在每个字节前发一个起始位(拉低),接收方在这个下降沿触发采样,然后按约定波特率在后续位中心点持续采样。只要两边的时钟误差不超过一定范围,就能在窗口内正确读到位。

帧格式通常是:

  • 空闲:高电平。
  • 起始位:1 个低电平。
  • 数据位:5~8 位,常见 8 位。
  • 校验位:可选,偶校验/奇校验/无校验。
  • 停止位:1 或 2 个高电平。

两台设备之间要在"波特率误差多少才不会乱码"上留余量。UART 的位中心采样有容差,经验上总误差要小于 4%-8%。两个设备各自晶振误差 2%,看似轻微,累计起来在数据连续发送 10 位时,误差就会被放大。

举一个实际例子:曾经有一个项目,主机用内部 RC 振荡器跑 115200,从机用外部晶振,结果接收端偶尔收到 0x00 或 0xFF 这类明显异常的字节。用频率计一量,主机实际波特率 114500,误差约 0.6%,按理说不算大,但那个劣质内部 RC 温漂严重,一发热就掉到 112000,误差逼近 3%,自然就随机乱码了。后来的做法是换成外部晶振或选择支持自动波特率检测的芯片。

5.2 TTL、RS232、RS485:同一个协议,三种"电压语言"

UART 的协议是逻辑层的,电气层可以完全不同,这一点经常有人混淆:

电气标准电压范围传输距离典型应用
TTL UART高 3.3V/5V,低 0V小于 1 米MCU 之间、板级通信
RS232负逻辑,±12V 左右15 米左右老式工业设备、PC 串口
RS485差分 A/B,2~5V 差模1200 米工业总线、多机联网

你拿 USB 转 TTL 模块和一台工控机通信,如果工控机是 RS232 电平,直接接上去烧不烧取决于模块的耐压,但大概率读不到数据。正确姿势是用带 RS232 电平的转接线,或者加一颗 MAX3232 电平转换芯片。

RS485 则是差分传输,抗干扰能力强,适合远距离多点组网。但是 RS485 是半双工的,发送和接收要切换方向,这在代码里经常忘了拉高 DE(方向使能),导致发送完不切换回接收,对方回的数据就丢了。之前有读者问过我"用了 RS485 后只能发不能收",十有八九是 DE 引脚没控制好。

5.3 中断、DMA、阻塞和非阻塞,怎么选

热搜词里有"uart 阻塞和非阻塞"“STM32F103 标准库 uart DMA 中断接收发送通信”,这都是 UART 工程化的经典话题。

简单区分:

  • 阻塞式:调用发送函数后一直等待发送完毕,期间 CPU 不能干别的。适合裸机简单任务。
  • 非阻塞式:发送函数开启中断或 DMA 后立即返回,CPU 继续跑主逻辑,发完由中断通知。
  • 中断接收:每收到一个字节触发一次中断,适合短报文,但高速大数据下中断频繁,CPU 压力大。
  • DMA 接收:硬件自动把一串数据搬进内存,到达指定量后中断一次,适合大量接收,比如 OTA 升级、文件传输。
  • 空闲中断(IDLE):很多 MCU 的 UART 外设支持总线空闲检测,配合 DMA 可以"等到线空了,就知道一帧收完了",这是实现不定长帧接收非常舒服的方式。

我个人的实战建议是:凡是报文长度不确定的(AT 指令、自定义帧、串口命令行),优先"DMA + 空闲中断"或"逐字节中断 + 超时判断";凡是定长小帧(传感器每 100ms 上报 8 字节),逐字节中断就够了,没必要上 DMA。非要用 DMA 接定长帧,反而要小心超长和错位的边界处理。

之前调一个 STM32F103 的标准库工程,想实现 DMA 接收不定长帧,网上大部分教程都是修改 DMA 缓冲大小,其实更省心的是开 IDLE 中断。IDLE 中断标志在收到起始位后总线空闲时置位,DMA 已经把数据存好,你只要在中断里读 DMA 剩余计数就知道这一帧有多长。这套组合下来,稳定性和 CPU 占用比老式逐字节中断好太多。

5.4 UART 调试时最实用的排查顺序

如果你遇到 UART 完全不通,我建议按下面的顺序排查,基本不会两手空空:

  1. 量 TX/RX 电平:空闲是高电平吗?如果一直是低,可能芯片引脚被强制拉低或者波特率太高导致示波器看不出变化。
  2. 用逻辑分析仪抓起始位和停止位:确认帧格式(1 起始 + 8 数据 + 无校验 + 1 停止)是否两端一致。
  3. 量实际波特率:抓一个字节,用两个下降沿之间的时间反推波特率,对照配置。
  4. 检查交叉连接:MCU 的 TX 要接对端的 RX,很多人两根线接反了。
  5. 查看地线:两个设备之间必须有共地,否则电平参考不一致,偶发乱码。

6. 四种协议到底怎么选:从参数表到决策逻辑

6.1 一张表看全对比

对比维度I2CSPII2SUART
引脚数2(SDA/SCL)4 及以上3 或 42(TX/RX)
时钟线有有有无,异步
数据方向半双工全双工单向数据流(发射/TX 侧)全双工(独立 TX/RX)
多设备一套地址总线挂多个一主多从,片选线较多通常点对点点对点(RS485 可多机)
典型速率100k~1M10M~100MBCLK 由采样率决定9600~3M 不等
抗干扰一般一般一般RS232/RS485 形式可变
典型应用传感器、EEPROM、PMBusFlash、ADC、LCD、FPGA音频 DAC/ADC、蓝牙音频调试口、GPS、蓝牙模块、RS485
CPU 负载中低(配 DMA 极低)中中高(配 DMA 低)

6.2 选型判断路径

每当我在新项目里定通信接口,我脑子里是有一套决策树的:

  1. 先看传输距离和抗干扰。超过 1 米环境又嘈杂?直接考虑 RS485/UART 方案。板内通信再谈 I2C/SPI。
  2. 看数据量和实时性。大数据量、高速、连续(Flash 刷写、图像)?SPI。低频、小数据、要省引脚?I2C。
  3. 看有多少设备需要挂。设备多且允许低速?I2C 的多点拓扑最省引脚。设备多但都要求高速?可以用 SPI 多片选,但引脚和冲突管理要谨慎。
  4. 看是否需要全双工。传感器上报数据为主,主从一问一答,I2C 够用。双向大数据流,果断 SPI。
  5. 看数据格式是否天然是音频流。采样率 + 左/右声道 + 高位宽?直接 I2S,别拿 SPI 硬凑。
  6. 看调试便捷性。UART 绝对是拿来调试的第一选择,几乎所有 MCU 都有串口,printf 一挂,问题就少一半。

这些顺序不是绝对的,但按这个思路走,很少会选错。

6.3 混合使用才是常态

一个复杂产品里,四种协议同时存在的例子非常多。比如 RK3588 平台的混合存储方案:SPI NOR 存引导程序,PCIe NVMe 存系统,中间调试靠 UART,传感器的状态回传用 I2C,音频语音助理模块走 I2S。这种设计不是因为某一种协议万能,而是每一种协议都在自己最适合的位置上发挥优势。

所以我不太建议问"哪个协议最好",这个问题本身就问错了。更好的问法是:我的应用场景里,数据速率是高是低?节点多少?距离远不远?实时性要求多高?把这几个参数列清楚,答案自然浮现。

7. 个人调试心得与常用工具位

最后再分享几个掏心窝子的经验,这些都是在项目里被折磨过之后攒下来的:

第一,I2C 时序图上的 ACK/NACK 不只是 0 和 1 的问题。调试带 I2C 的屏或者触摸时,如果主机发完寄存器地址后一直收不到 ACK,不要只怀疑硬件连接,先确认你发的 7 位地址写的对不对。有些芯片默认地址末尾带了 R/W 位配置,地址计算错一位就能让整个总线"找不到设备"。

第二,SPI 的 CS 时序一定要用示波器看。很多人在软件里以为 CS 拉低后立刻就能传数据,但某些器件的 CS 下降沿到第一个 SCLK 上升沿之间有最小的 tsu(建立时间)要求,不满足时偶尔第一字节丢失。你用逻辑分析仪抓波形,一看 CS 和 SCLK 的距离,就能判断到底是软件发早了还是硬件片选配置慢了。

第三,I2S 波形"看着没问题"绝不代表音频正常。之前调一块音频板,I2S 三根线波形完美,但就是没声音。查到最后发现 MCLK 没有初始化,解码芯片 PLL 没锁定。I2S 协议管的是数据链路,MCLK 管的是音频时钟的源头,两个维度都要检查。

第四,UART 调试时先送一长串 0x55(01010101),方便看波形边沿。0x55 这样的交替位能让逻辑分析仪自动测量每 bit 宽度,直接反推出实际波特率,比猜快得多。

关于工具,我常用的配置是:USB 转 TTL(基于 FT232R 或 CH340)+ 逻辑分析仪(至少 8 通道)+ 示波器。USB 转 TTL 看 UART 通不通最快;逻辑分析仪抓 I2C/SPI/I2S 时序和总线电平最直观;示波器用来量边沿和时序余量。程序上,SPI/I2C 的抓包用 PulseView 这类开源软件就够,它带协议解码器,直接标出地址、ACK、数据帧,比盯着裸波形脑补要省事得多。

这些工具不需要多贵,但你折腾完一遍四种协议后,会发现收益远超那几百块钱。希望这篇文章能帮你把 I2C、SPI、I2S、UART 这四种"串行语言"串起来:看懂它们的设计哲学、会用它们各自的优势、避开那些藏在细节里的坑。到了真调板子的那天,你会发现脑子里有这张图,比记住哪本数据手册都管用。

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

部署和发布PHP网站到IIS服务器的全过程

稳定版本博主当前时间最新稳定版本是Current Stable PHP 8.3.13,点击Windows downloads即可线程安全版在跳转页面,建议选择VS16 x64 Thread Safe(线程安全版本,以及直接是Zip压缩包,下载后,直接解压复制文件…

作者头像 李华
网站建设 2026/9/25 7:29:57

vim全选、全部复制、全部删除:模式与寄存器核心操作详解

刚接触Linux的人,十有八九会在vim里卡住。图形编辑器里CtrlA全选、CtrlC复制、CtrlD删除,一套肌肉记忆带进终端,结果vim愣是没反应。这个场景我见过太多次:有人以为vim坏了,有人干脆放弃,还有人直接在终端里…

作者头像 李华
网站建设 2026/9/25 7:28:35

OCS网课助手题库API配置全攻略:从原理到实战提升答题正确率

1. 从“手动刷课”到“自动答题”:OCS网课助手到底在解决什么问题如果你正在看这篇文章,大概率是手里已经装了 OCS 网课助手,或者正准备装,卡在了“题库 API 怎么配”这一步。先说结论:OCS 本身只是一个“壳”&#xf…

作者头像 李华
网站建设 2026/9/25 7:28:18

智能车视觉实战:OpenART Plus上的AprilTag检测与AR叠加全攻略

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

作者头像 李华
网站建设 2026/9/25 7:26:17

51单片机16×16点阵流动字幕实现原理与硬核调优

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

作者头像 李华