资讯详情

资讯详情

SPI通信协议详解:从时序原理到STM32配置与故障排查

刚把一块屏点亮的时候画面整体偏色还带雪花点排查了半天发现根本不是屏的问题而是SPI的时钟极性和相位配错了。类似这种看似硬件故障、实为时序配置翻车的案例在我接触过的SPI通信项目里一抓一大把。SPI作为嵌入式里出场率最高的通信协议之一门槛看着不高但真正想调通、调稳、调到高速不丢数据还是有不少门道。这篇内容从SPI的核心机制讲起把四线职责、主从模式、四种工作模式、片选策略、Cubemx配置、DMA传输这些关键点逐一拆开最后再给一份从波形到寄存器的排查思路。不管是刚接触通信协议的新手还是已经在用SPI但经常被时序问题困扰的工程师都能在这篇里找到对应的答案。1. SPI到底解决什么问题——从一条调试线上的低谷说起我第一次认真研究SPI是因为一个再常见不过的场景MCU要外挂一颗Flash芯片存参数一开始想用I2C结果发现写入速度实在跟不上业务需求换用SPI之后同样是这颗芯片时钟从400kHz拉到几兆赫兹甚至更高性能完全不是一个量级。SPI全称Serial Peripheral Interface串行外设接口由Motorola在1970年代末提出。它解决的核心问题是在芯片与芯片之间提供一种简单、高效、全双工的数据交换通道。简单到什么程度呢它没有复杂的协议帧、没有地址解析、没有应答重传机制就是最朴素的主设备控制时钟主从设备同步移位交换数据。这种设计哲学让它的实现成本极低无论你在MCU上做软件模拟还是用FPGA写Verilog逻辑都能很快跑起来。在实际选型中SPI通常出现在这样几类场景板级短距离通信一般不超过几十厘米走线越短越稳。对吞吐率有要求的场景比如驱动TFT屏幕刷新、读写外部Flash、采集高速ADC数据。从设备是被动响应型的外设比如传感器、存储芯片、SD卡、以太网控制器等。反过来说SPI不太适合做长距离传输也几乎没有错误重传机制数据线受到干扰时只能靠上层协议去兜底。理解它的边界和会用它的API一样重要。2. 四根线怎么把数据推出去——SPI核心机制与数据交换模型SPI的物理层最多四根线职责非常清晰新手把它们记熟后面所有时序分析都建立在这四根线上。信号线全称方向职责SCLKSerial Clock主→从产生移位时钟所有数据位都在这个时钟边沿上被采样或移出MOSIMaster Out Slave In主→从主设备发送数据给从设备MISOMaster In Slave Out从→主从设备发送数据给主设备CS/SSChip Select / Slave Select主→从低电平有效选中某个从设备让它在总线上开口说话在SPI的世界里通信的最小单位不是字节指令而是时钟沿驱动的移位操作。主设备在SCLK的某一个边沿把MOSI上的一位数据推出去同时在另一个边沿从MISO上采回一位数据。于是发送一个字节的过程同时也接收一个字节这就是SPI全双工的本质。用生活化一点的比喻SPI就像两个人面对面中间放了一条传送带SCLK是传送带转动的节奏。每响一次节拍甲方往传送带上放一个球MOSI发送同时从传送带上取走乙方放的球MISO接收。不管你有没有球要放节拍不能停传送带一直转双方始终在同时进行放球和取球这两个动作。这个机制带出一个特别重要的推论在SPI通信中主设备每发出一个字节必然会收到一个字节。哪怕你只是想读从设备的数据也必须先发出对应的时钟脉冲而这个时钟脉冲通常会配合发送一个空字节或者读命令字节。这也是为什么很多SPI从设备的读操作都要求主设备先发送命令地址再持续给时钟把数据读出来。3. 主从模式与多设备拓扑谁控制时钟谁就掌握主动权SPI总线上永远只有一个主设备可以有多个从设备。主设备拥有SCLK的控制权从设备绝对不能在总线上主动发起通信它只能在片选被拉低、并且SCLK到来时被动响应。多从设备拓扑主要有两种连接方式很多人第一次画原理图时容易混淆。3.1 独立片选模式每个从设备占用一个独立的CS引脚主设备的GPIO够多时就采用这种方式。所有从设备的SCLK、MOSI、MISO并接在总线上但CS互不相同。主设备要跟谁通信就把谁的CS拉低确保同一时刻只有一个从设备在MISO上驱动数据。这种方式的优点是简单可靠软件逻辑清晰缺点是占用主设备引脚多。比如一个MCU接了4个SPI从设备主控就要额外牺牲4个GPIO来做片选。3.2 菊花链模式所有从设备共用一根CS数据的传递像串糖葫芦一样主设备的MOSI先进入第一个从设备它的输出再接到第二个从设备的输入依次往后串。每个SCLK脉冲数据在整条链路上往后移动一位。这种模式适合多个同型号从设备需要同时更新数据的场景最典型的就是多片LED驱动芯片级联、多片移位寄存器级联。菊花链的缺点是延迟是累加的写一个数据要经过所有从设备而且如果链路中某一片芯片不支持菊花链特性整个方案就直接作废。对于大多数工程师来说独立片选模式是首选。它让软件调试的复杂度降到最低也方便你单独对某个设备做读写验证。如果主控GPIO确实不够再考虑用GPIO扩展芯片或者改走菊花链。4. 四种工作模式不是玄学——CPOL/CPHA与时序图的对应关系SPI协议里最容易让人犯迷糊、也是面试和技术社区里被反复讨论的点就是四种工作模式。模式由两个参数决定CPOLClock Polarity时钟极性和CPHAClock Phase时钟相位。先给结论CPOL决定SCLK空闲时的电平CPHA决定数据在SCLK的哪个边沿被采样。CPOL 0SCLK空闲时为低电平有效脉冲是高电平。CPOL 1SCLK空闲时为高电平有效脉冲是低电平。对于新手来说空闲电平乍一看是反的容易记混。CPHA 0数据在SCLK的第一个边沿被采样。如果CPOL0第一个边沿就是上升沿如果CPOL1第一个边沿就是下降沿。CPHA 1数据在SCLK的第二个边沿被采样。也就是第一个边沿用来移位输出数据第二个边沿用来采样。这四种组合形成了SPI Mode 0到Mode 3。它们与常见的器件默认配置对应关系如下模式CPOLCPHASCLK空闲电平数据采样边沿常见器件Mode 000低电平上升沿绝大多数Flash、传感器、屏幕Mode 101低电平下降沿部分音频芯片Mode 210高电平下降沿部分特定外设Mode 311高电平上升沿SD卡、部分无线芯片不少芯片手册会直接写SPI Mode 0/1/2/3或者CPOL1, CPHA1你只需要对应成表格里的配置写到寄存器里就行。但坑在于很多芯片手册用的是波形图而不是文字描述你得能看懂时序图。判断方法很简单看波形里SCLK空闲在哪儿再看数据线在哪个边沿跳变、在哪个边沿保持稳定。数据在某个边沿跳变意味着前一个边沿被用于采样。我在调ST7789屏幕驱动时踩过这个坑。数据手册画的是Data setup on rising edge, data change on falling edge这句话翻译过来就是数据在上升沿采样、在下降沿变化对应CPOL0、CPHA0的Mode 0。但有人想当然地以为数据变化沿采样沿结果配成了Mode 1屏幕整体花掉。遇到这种问题不要急着怀疑芯片坏了先回来看时序图。5. 片选为什么让很多人翻车——硬件片选与软件片选的取舍SPI协议里片选看起来简单就是拉低选中、拉高释放但实际项目中因为片选处理不当引发的通信故障非常多。我整理了一下主要有三种典型场景。5.1 先拉CS再给时钟还是先给时钟再拉CS绝大多数从设备要求CS先拉低、再启动SCLK因为从设备内部需要检测CS的下降沿来复位内部状态机、准备接收第一个字节。反过来如果SCLK先跑起来从设备可能还在上一个通信会话的状态里数据对不上。正确做法是先在软件里拉低CS然后延时一小段哪怕只有几百纳秒视器件要求而定再写数据到SPI数据寄存器。通信完毕要等最后一个字节的TXE标志置位、确保移位寄存器全部送完再拉高CS。5.2 硬件片选与软件片选的迷惑行为STM32系列MCU的SPI外设支持硬件片选NSS硬件控制和软件片选NSS软件管理。很多人打开Cubemx时看到一堆NSS选项就懵了。硬件片选模式下NSS引脚由SPI外设自动控制主设备发送数据前自动拉低、发送完自动拉高好处是少占CPU、时序更精确。但坏处是如果你在一个事务里需要连续发送多个帧而中间不允许CS翻转硬件片选可能会在一个帧结束后就提前拉高CS这在某些从设备看来就是一次通信中断。软件片选模式下NSS引脚完全由GPIO手动控制SPI外设内部则通过配置SSI位来欺骗外设说片选已经有效。这种模式灵活性最高尤其是多从设备场景你可以完全按照自己的节奏控制每个从设备的CS时序。项目里涉及多个SPI从设备或者需要做连续多字节事务时我通常默认选软件片选配合手动GPIO。5.3 CS引脚的电容和走线也一样重要别以为片选只是数字电平就随意处理。CS线如果走线过长或者对地电容偏大会导致边沿变缓。有些从设备对CS上升沿有严格的时间要求边沿过缓可能导致它误判下一次通信的起点。我在样板调试时遇到过一种诡异现象用示波器看波形完全正常但换了一台机器就是偶发读写失败最后定位到CS走线绕了很长一圈寄生电容太大。所以画PCB时SPI四根线尽量等长、短走线、避免打过孔CS线尤其不要绕着板子边缘走一大圈。频率超过10MHz时建议在驱动端串33欧姆左右的电阻既能抑制振铃又能减少EMI。6. STM32 Cubemx配置SPI的完整套路与高频踩坑STM32Cubemx的图形化配置让SPI初始化变得非常简单但恰恰因为简单很多细节被忽略生成的代码里藏着隐患。我以最常见的STM32F103/F401系列为例把配置流程捋一遍并指出哪些地方需要手动改。6.1 时钟与引脚的基础配置步骤打开Cubemx后按照这个顺序操作在左侧Categories里找到SPI选择要使用的SPI外设比如SPI1。在Mode下选择Transmit Only Master、Receive Only Master或者Full-Duplex Master。如果是从设备就选Slave模式。硬件NSS选择Disable然后把片选引脚留作GPIO Output手动控制。在Parameter Settings里配置波特率预分频器。先看APB总线时钟频率假设APB2是72MHz想要SPI时钟18MHz预分频就选4分频。配置CPOL、CPHA为从设备要求的模式绝大多数器件用Mode 0。数据帧格式选8 bit除非你确认外设需要16 bit比如某些音频编解码器。配置MSB First还是LSB First。绝大多数SPI器件是MSB先行但极少数器件是LSB先行比如部分LED驱动芯片。这个配置错了数据看起来就会位序颠倒特征是每个字节的bit0和bit7对调后的错误值。生成代码后Cubemx会在main函数前初始化好GPIO、时钟和SPI外设。这时候如果你是软件片选需要在应用代码里自己写一个CS拉低/拉高的宏。6.2 数据手册里的读命令和实际发送顺序不一致SPI读操作看起来简单但很多人第一次写外部Flash驱动时都会卡住。以W25Q256这颗典型的SPI Flash为例读数据的流程是拉低CS。发送命令0x03Read Data。发送24位地址即3个字节先发高字节。然后主设备连续发送任意字节通常是0x00每发送一个字节就能从MISO上收到一个字节数据。读完需要的长度后拉高CS。有个细节需要注意在发送命令和地址阶段的每一个字节MISO上也在返回数据只不过这部分数据是无效的要丢弃。在读取数据阶段MOSI上发的内容没有实际意义但不能停止时钟。SPI是移位交换的时钟停了数据就出不来。6.3 常见的Cubemx配置翻车点我总结了一下平时在社区里经常看到的问题以及对应的排查方向现象可能原因处理思路读写全FFCS没拉低、模式不对、MISO没接对先检查GPIO电平再用示波器看MISO上有没有波形读回全00从设备没有正确驱动MISO检查从设备是否上电、复位脚是否正常、CS时序数据错位但波形正常CPOL/CPHA配置错误回看时序图确认采样沿和变化沿偶尔通信失败片选时序不满足CS与SCLK之间加延时或检查SCLK频率是否过高首字节丢失从设备需要更长CS建立时间拉低CS后延时再发数据7. 进阶玩法DMA搬运、共享总线与高速场景优化SPI跑通基本收发只是第一步。实际项目里当你需要在屏幕上高频刷新画面或者持续从ADC采集数据写入Flash时CPU轮询发送的方式很快就会撑不住。这时候SPI的进阶玩法就该登场了。7.1 SPI和DMA配合把CPU从搬运中解放出来SPI的轮询发送有一个显著问题每发送一个字节CPU都要等待TXE标志置位然后再次写数据寄存器。假设SPI时钟是18MHz发送一个字节大约需要444纳秒CPU如果以72MHz运行相当于每个字节要等32个CPU周期这段时间全部被浪费掉了。DMADirect Memory Access模式可以解决这个问题。配置好SPI的TX DMA通道后只需要把要发送的数据缓冲区首地址和长度告诉DMADMA就会自动把数据一个一个搬运到SPI数据寄存器搬运完成后再触发中断通知CPU。整套流程中CPU只在启动DMA和接收完成中断时介入。配合DMA使用时有几个要点DMA缓冲区必须是连续内存如果用的是RTOS要特别注意缓冲区在DMA传输期间不能被释放。对于发送缓冲区是const数组的场景DMA要配置成从Flash读取数据这在STM32上需要把DMA的源地址指向Flash对应的总线地址范围部分系列还要开启对应的DMA时钟。接收和发送同时开启DMA时要留意两个DMA通道的优先级别因为总线竞争导致SPI的FIFO溢出。7.2 屏幕和SD卡共享SPI总线仲裁策略决定稳定性以ESP32驱动的TFT屏幕和SD卡为例很多开发板把这两个外设挂在同一条SPI总线上复用SCLK、MOSI、MISO各自独立的CS引脚。这种共享方案可以省引脚但引入了总线仲裁问题。屏幕刷新通常是大批量连续数据SD卡读写也涉及扇区级数据块两者同时工作时容易发生CS交叉、甚至总线冲突。稳定方案是把高频率、大数据的设备优先级调高每次传输一个完整的事务不允许中途切换。在软件上可以用互斥锁或者关中断的方式保证一个事务的原子性比如关中断先写完一整行屏幕数据再开中断。从硬件角度如果板子上空间允许更推荐把屏幕和SD卡分别挂在SPI1和SPI2上。两个外设虽然共用一个物理SPI控制器的MCU也有但如果MCU有多个独立SPI外设分开挂载能省掉很多软件协调的麻烦。7.3 高速SPI的布线要点SPI频率超过20MHz后信号完整性就不能再忽视了。我在一块板子上把SPI时钟跑到40MHz结果数据线长了2厘米就出现误码。后来做了几处调整走线尽量短SCLK与MOSI/MISO的长度差控制在等长范围内。MISO线上不要串大电阻接收端的寄生电容对高速信号影响明显。SCLK两侧用地包一下减少对其他走线的辐射干扰。如果从设备支持优先使用更低的IO电压等级匹配避免电平转换芯片引入额外延迟。8. FPGA视角看SPI——仿真模型与Verilog验证要点除了单片机FPGA也是SPI协议的常见阵地。FPGA里用Verilog实现SPI主从机是把协议理解到位的最佳训练场同时也绕不开一个关键环节仿真验证。很多人写SPI逻辑时直接上板调试波形乱成一团才回来改代码。正确做法是先建仿真环境把时序模型跑通了再上板。8.1 主机的Verilog设计要点一个典型的SPI主机模块包含三个核心部分波特率发生器分频计数器、移位寄存器、状态机。波特率发生器由系统时钟分频产生SCLK。为了适应不同从设备分频系数通常做成可配置寄存器。移位寄存器在SCLK的下降沿把发送寄存器里的数据移出一位到MOSI在上升沿采样MISO并移入接收寄存器。状态机负责管理CS拉低、发送命令、地址、数据、接收数据、CS拉高等完整流程。这里容易踩的坑是复位后的初始状态。CS默认要拉高SCLK要保持空闲电平如果初始时CS恰好被拉低从设备可能误入通信状态。8.2 从机的Verilog设计要点从机模块设计比主机更微妙。由于SCLK由外部主机控制从机内部的时钟域处理是个关键点。常见做法是用两级触发器对SCLK和CS做打拍同步消除亚稳态。利用打拍后的信号检测CS下降沿作为通信开始标志。在检测到SCLK的采样沿时把MOSI上的数据移位进入接收寄存器。在SCLK的变化沿把发送寄存器的数据移位输出到MISO。注意MISO的输出不能一直有效只有在片选被拉低且通信进行中才允许驱动MISO其他时间必须释放为高阻态否则多从机并联时会发生总线冲突。8.3 仿真时用task建主机模型事半功倍在写从机RTL代码的仿真环境时我习惯用Verilog的task来模拟主机行为比手动拉波形高效很多task spi_write_byte; input [7:0] data; integer i; begin for (i 7; i 0; i i - 1) begin mosi data[i]; #100 sclk 1; #100 sclk 0; end end endtask用这种基于延时的task可以快速搭建读、写、连续传输等各种测试场景重点验证CS时序、SCLK边沿采样点和MISO高阻态行为。等到仿真环境全部通过后上板调试出现的问题会少一大半。9. 一张表排查SPI通信故障从波形到寄存器的全链路写到这里我相信你已经对SPI有了体系化的认识。最后分享一套我常用的SPI故障排查流程按顺序执行绝大部分问题都能定位到根因。9.1 第一层先确认电气连接测量SCLK、MOSI、MISO、CS四根线在通信时是否有波形。如果SCLK没有波形查看SPI外设时钟是否开启GPIO复用功能是否配置正确。如果MISO始终为高或低考虑从设备没上电、引脚虚焊、或者从设备输出使能条件不满足。9.2 第二层确认时隙与模式用示波器同时抓CS和SCLK确认CS下降沿早于SCLK第一个边沿。确认SCLK空闲电平与CPOL配置一致。对照数据手册确认数据采样沿是否和配置一致。9.3 第三层检查寄存器与软件逻辑读取SPI状态寄存器查看TXE、RXNE、BSY标志位的状态是否符合预期。如果发送正常但接收全FF检查MISO对应的GPIO是否配置成复用功能、是否有外部上拉影响电平。如果使用DMA检查DMA状态寄存器确认传输是否完成、是否发生传输错误。对于调试中常见的几种波形异常我也做了一个快速对照表波形现象方向处理CS有效期间SCLK无脉冲主检查波特率配置确认SPI已使能确认数据已写入DRSCLK有脉冲但MOSI一直为低主检查发送数据是否写入检查MSB/LSB配置SCLK有脉冲但MISO无响应从检查从设备供电、复位检查CS时序确认模式是否匹配数据线上出现明显台阶物理层调整走线尝试降低SPI时钟频率偶发一个字节错乱时序检查CS建立时间检查发送完成后是否等待BSY清零再拉高CS10. 从IO模拟到实战的一点心得很多人纠结要不要用IO口模拟SPI。我的经验是MCU硬件SPI外设确实好用但在GPIO资源紧张、或者主控根本没有SPI外设时用IO口模拟SPI是完全可行且必要的。模拟SPI的核心就是精确控制时序用延时函数确保SCLK的每个高低电平时间满足从设备要求采样点放在数据稳定区间。关于模拟SPI的采样点选择有一个小技巧在SCLK上升沿采样数据时最好在上升沿之前让SCLK保持半周期的低电平确保MOSI数据已经提前建立如果你不确定时序裕量可以把SCLK的低电平时间拉长一点数据建立时间就更充裕代价是通信速率降低。SPI这个协议乍一看只有四根线似乎没什么深度但真正用起来才会发现它像一把趁手的工具——理解了它的移位交换本质你就能解释为什么读操作也要发数据理解了主从模式的主动权你就知道为什么多从设备必须靠CS仲裁理解了四种时序模式你就能在示波器上一眼看出模式配没配错。希望这篇内容能帮你在SPI通信的路上少走一些弯路把更多时间花在业务逻辑本身。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →