当前位置: 首页 > news >正文

SPI通信协议深度解析:从寄存器操作到中断与错误处理实战

1. SPI数据传输机制与错误处理详解:从寄存器操作到中断控制

搞嵌入式开发,SPI(Serial Peripheral Interface)几乎是绕不开的通信协议。从简单的EEPROM读写到复杂的传感器数据采集,SPI以其简单、高速、全双工的特性,在各类MCU和DSC(数字信号控制器)中扮演着关键角色。但很多开发者,尤其是刚入行的朋友,往往只停留在“配好时钟、读写数据”的层面,一旦遇到数据错乱、通信中断或者莫名其妙的溢出错误,就有点抓瞎。

今天,我就结合飞思卡尔(现恩智浦)5685X系列DSC的SPI模块手册,把SPI从数据传输的底层寄存器操作,到错误处理的完整逻辑,以及如何利用中断构建稳健驱动,彻底讲透。这不仅仅是手册翻译,而是我十多年踩坑填坑后,对SPI核心机制的理解和实战经验的总结。无论你是用STM32、NXP还是其他家的MCU,SPI的核心思想和寄存器操作逻辑都是相通的,这篇文章能帮你建立起一套完整的调试和问题排查框架。

2. SPI核心机制深度拆解:不止于四根线

很多人对SPI的印象就是SCK、MOSI、MISO、SS四根线。这没错,但仅仅是物理层。在控制器内部,SPI模块是一个精密的“数据流水线”和“状态机”,其稳定运行依赖于对一系列寄存器和标志位的精确操控。理解这个内部状态机,是写出高效、可靠SPI驱动的关键。

2.1 双缓冲机制:流畅传输的基石

SPI通信是同步的,意味着数据传输的节奏完全由时钟(SCLK)控制。数据从主设备的MOSI引脚移出,同时从从设备的MISO引脚移入,实现全双工。但这里有个关键问题:当移位寄存器正在一位一位地向外发送数据时,如果CPU想准备下一帧要发送的数据,或者读取刚刚接收完的数据,该怎么办?如果只有一个共享的数据寄存器,就会发生冲突。

飞思卡尔5685X的SPI模块采用了一种经典且高效的解决方案:双缓冲数据寄存器

  • SPDTR (SPI Data Transmit Register)数据发送寄存器。这是一个只写(Write-Only)寄存器。当CPU需要发送数据时,就将数据写入这里。注意,写入SPDTR并不意味着数据立刻被发送到引脚上,它只是进入了“发送缓冲区”。
  • 移位寄存器 (Shift Register): 这是真正进行“串行化”操作的硬件单元。它从SPDTR中加载并行数据,然后在SCLK的每个时钟沿,将数据一位一位地通过MOSI(主模式)或MISO(从模式)推出去。同时,它也从对应的输入引脚接收数据,并组装成并行数据。
  • SPDRR (SPI Data Receive Register)数据接收寄存器。这是一个只读(Read-Only)寄存器。当移位寄存器接收完一整帧数据(例如16位)后,会自动将组装好的并行数据转存到SPDRR中,等待CPU读取。

这个“双缓冲”流程是这样的:

  1. CPU检查SPTE (SPI Transmitter Empty)标志。如果SPTE=1,表示发送缓冲区(SPDTR)为空,可以写入新数据。
  2. CPU将数据DATA_A写入SPDTR。写入操作会自动清除SPTE标志(置0),表示缓冲区已满。
  3. 当移位寄存器空闲(即上一帧数据已发送完毕)时,硬件会自动将DATA_A从SPDTR加载到移位寄存器中。这个加载操作会自动置位SPTE标志(置1),通知CPU:“缓冲区又空了,你可以准备下一帧数据DATA_B了”。
  4. 与此同时,移位寄存器开始在SCLK驱动下,一边发送DATA_A的位,一边接收从设备返回的数据位。
  5. 当一整帧数据接收完成,硬件会将移位寄存器中接收到的数据DATA_RX转存到SPDRR,并自动置位SPRF (SPI Receiver Full)标志(置1),通知CPU:“有数据收到了,快来读”。
  6. CPU读取SPDRR,读取操作会自动清除SPRF标志(置0)。

关键点与避坑指南:

  • SPTE是“可写”标志SPTE=1是写入SPDTR的唯一安全时机。如果在SPTE=0时强行写入,会覆盖尚未被加载到移位寄存器的数据,导致发送数据错误。手册中明确警告:“Do not write to the SPI Data Register unless the SPTE bit is high.”
  • SPRF是“可读”标志SPRF=1是读取SPDRR的时机。及时读取非常重要,否则会导致溢出错误(OVRF),我们后面会详细讲。
  • “背靠背”传输:双缓冲的精妙之处在于支持“背靠背(Back-to-Back)”传输。CPU可以在当前帧(DATA_A)还在移位寄存器中发送时,就将下一帧数据(DATA_B)写入SPDTR进行排队。这样,当前一帧发送完成的瞬间,DATA_B可以立即被加载,开始下一帧传输,最大限度地利用了总线带宽,减少了帧间的空闲时间。

2.2 时钟相位与极性:主从设备对话的“暗号”

CPOL (Clock Polarity) 和 CPHA (Clock Phase) 是SPI配置中最容易混淆,也最关键的参数。它们共同定义了数据采样和变化的时钟边沿。主从设备必须配置一致,否则通信必然失败。

  • CPOL (时钟极性): 定义SCLK在空闲状态(无数据传输时)的电平。
    • CPOL=0: SCLK空闲时为低电平。
    • CPOL=1: SCLK空闲时为高电平。
  • CPHA (时钟相位): 定义数据在SCLK的哪个边沿被采样(捕获),以及在哪个边沿发生变化(输出)。
    • CPHA=0: 数据在SCLK的第一个边沿(对于CPOL=0是上升沿,对于CPOL=1是下降沿)被采样,在下一个边沿发生变化。
    • CPHA=1: 数据在SCLK的第二个边沿被采样,在第一个边沿发生变化。

手册中的时序图(Figure 11-10)清晰地展示了CPHA:CPOL = 1:0模式下的波形。在这种模式下:

  • CPOL=0: 空闲时SCLK为低。
  • CPHA=1: 数据在SCLK的第二个边沿(下降沿)被采样,在第一个边沿(上升沿)发生变化。
  • 因此,MOSI数据在SCLK上升沿时变化,在下降沿时被从设备稳定采样。

为什么需要两种模式?这主要取决于从设备(如传感器、ADC芯片)的硬件设计。有些芯片要求在时钟边沿A采样,有些则在边沿B。作为主设备,我们必须严格按照从设备数据手册的要求来配置CPOL和CPHA。一个常见的记忆方法是:CPHA决定了采样边沿是“奇数”还是“偶数”个边沿(从帧同步信号开始算)。

实战经验:

  1. 先查从设备手册: 在编写驱动前,第一件事就是确认从设备的SPI模式(Mode 0, 1, 2, 3)。Mode 0对应CPOL=0, CPHA=0,Mode 1对应CPOL=0, CPHA=1,以此类推。
  2. 示波器是终极裁判: 当通信不通时,用示波器同时抓取SCLK和MOSI/MISO波形。对照理论时序,看数据变化和采样边沿是否匹配。这是排查SPI硬件问题最直接有效的方法。
  3. CPHA=0的特殊要求: 手册特别指出,当CPHA=0时,从设备的SS引脚必须在两次完整的数据传输之间被拉高(置为逻辑1)。这是因为在CPHA=0模式下,SS的下拉沿本身就标志着传输的开始(MISO会立即输出MSB)。如果SS一直为低,从设备会认为传输一直在持续,导致逻辑混乱。在使用CPHA=0时,务必在软件中控制好SS引脚的电平切换。

3. 寄存器操作详解:与硬件对话的语言

理解了核心机制,我们来看看如何通过寄存器来指挥这个硬件模块。5685X的SPI模块主要涉及四个寄存器,它们的访问类型和功能各不相同,操作不当会导致未定义行为。

3.1 核心寄存器功能解析

寄存器缩写全称访问类型核心功能
SPSCRSPI状态与控制寄存器读/写 (Word)核心控制中心。包含波特率选择、主从模式、时钟相位/极性、模块使能、中断使能以及所有关键状态标志(SPTE, SPRF, OVRF, MODF)。
SPDSCRSPI数据大小与控制寄存器读/写 (Word)配置传输数据位宽(2-16位)、使能DMA模式、使能Wired-OR模式。
SPDRRSPI数据接收寄存器只读 (Word)存放从移位寄存器转存过来的已接收数据。读取该寄存器会清除SPRF标志。
SPDTRSPI数据发送寄存器只写 (Word)存放待发送的数据。写入该寄存器会清除SPTE标志。

重要警告: SPSCR和SPDSCR这两个读/写寄存器必须使用字(Word)访问。使用字节或半字访问会导致“未定义的结果”,通常意味着某些位可能被错误地写入或读取,引发难以排查的故障。在C语言中,确保将它们定义为volatile的32位或16位(取决于架构)变量,并使用指针进行字访问。

3.2 关键控制位与状态位操作指南

SPSCR寄存器中的关键位:

  1. SPE (Bit 5) - SPI使能: 这是SPI模块的总开关。SPE=0时,模块被禁用,会进行一次“部分复位”(清空移位寄存器、状态计数器等),但控制位(如MODFEN, ERRIE)和状态标志(SPRF, OVRF, MODF)不会被清除。这允许你在传输间隙关闭SPI以省电,而无需重新配置所有参数。再次开启时,直接置SPE=1即可。
  2. SPMSTR (Bit 8) - 主模式选择1为主机,0为从机。这个位决定了SCLK、MOSI、MISO引脚的方向。特别注意:在主机模式下,如果MODFEN=1,SS引脚被意外拉低会产生模式故障(MODF),这会导致SPE被自动清零,SPI被禁用!这是一个重要的硬件保护机制。
  3. SPRIE (Bit 9) & SPTIE (Bit 4) - 接收/发送中断使能
    • SPRIE=1: 当SPRF(接收寄存器满)置位时,产生接收中断。
    • SPTIE=1: 当SPTE(发送寄存器空)置位时,产生发送中断。注意:此中断仅在SPE=1(SPI使能)时有效。
  4. ERRIE (Bit 11) - 错误中断使能: 这是一个“总开关”,同时控制着OVRF(溢出)和MODF(模式故障)两个错误标志是否能产生中断。ERRIE=1,则两者任一置位都会触发“接收/错误中断”。不能单独使能OVRF或MODF的中断
  5. MODFEN (Bit 10) - 模式故障检测使能: 此位控制是否检测SS引脚上的模式故障。如果MODFEN=0,则SS引脚的电平变化不会被监控,MODF标志永远不会被置位。这在一些特殊应用(如多主机软件模拟)中可能有用,但通常建议保持使能(MODFEN=1)以利用硬件保护。

状态位操作与清除机制:

  • SPTE(Bit 0):只读。当SPDTR的数据被加载到移位寄存器后,硬件自动置1。清除它的唯一方法是向SPDTR写入新数据。
  • SPRF(Bit 3):只读。当接收数据从移位寄存器转存到SPDRR后,硬件自动置1。清除它的唯一方法是读取SPDRR。
  • OVRF(Bit 2):只读。发生接收溢出时置1。清除它需要一个特定序列:先读取SPSCR(此时OVRF=1),然后再读取SPDRR。这个顺序不能错。
  • MODF(Bit 1):只读。发生模式故障时置1。清除方法是向该位写1(注意,是写1清零,这是一种常见的标志清除方式)。但手册强调,清除操作必须在MODF条件已不存在(即SS引脚电平已恢复正常)时进行,否则写1无效。

避坑指南:操作寄存器的“潜规则”

  • 避免使用位操作指令: 手册明确警告,避免使用BFCLR(位清除)或BFSET(位置位)这类指令来修改SPSCR。因为这类指令是“读-修改-写”操作,在读取和回写之间,硬件可能已经改变了状态位(如SPRF、SPTE),你的回写操作可能会意外地清除这些由硬件置位的标志,导致数据丢失或状态机混乱。安全的做法是:先读取整个寄存器值到一个变量,在变量中修改控制位,再将整个变量写回寄存器。
  • 数据对齐: 无论数据位宽(TDS)设置是多少,SPDRR和SPDTR都是16位寄存器。当传输数据小于16位时(例如8位),数据总是存放在寄存器的低有效位,高位用0填充。写入SPDTR时,也只需将数据放在变量低字节,高位写0即可。

4. 错误处理机制:构建稳健通信的防线

SPI通信在复杂电磁环境或多设备系统中,出错是难免的。硬件提供的错误检测机制是我们构建稳健系统的第一道防线。5685X的SPI模块主要提供了两种错误检测:溢出错误(OVRF)和模式故障错误(MODF)。

4.1 溢出错误:数据丢失的“元凶”

溢出错误(OVRF)的本质是:CPU读取数据的速度跟不上SPI接收数据的速度

触发条件: 当SPRF标志已经为1(表示SPDRR中有未读数据),而下一帧数据的第一个位的捕获时钟沿(对于16位数据,是第15个SCLK的中间点)到来时,OVRF标志就会被置位。

严重后果

  1. 触发溢出时正在接收的这帧数据(图11-11中的DATA 3)会丢失,不会被转移到SPDRR。
  2. SPRF标志不会被置位(因为新数据没进来)。
  3. 之前已经存在于SPDRR中的旧数据(DATA 2)仍然可以正常读取。
  4. 如果ERRIE=1,会触发接收/错误中断。

最危险的情况——静默数据丢失: 这是手册(Figure 11-11)重点警告的场景。假设我们只使能了SPRF中断(SPRIE=1)来处理接收数据,而没有使能错误中断(ERRIE=0)。流程如下:

  1. DATA 1接收完成,SPRF置位,触发中断。
  2. 中断服务程序(ISR)中,我们读取SPSCR(看到SPRF=1),然后读取SPDRR获取DATA 1。读取SPDRR会清除SPRF
  3. 在ISR执行期间或之后,DATA 2接收完成,SPRF再次置位,等待下次中断。
  4. 然而,在CPU来得及响应DATA 2的中断之前,DATA 3已经开始接收了。此时SPDRR中仍然是未读的DATA 2,于是OVRF在DATA 3接收中途被置位,DATA 3丢失。
  5. 由于OVRF中断未使能,CPU对此一无所知。DATA 2的SPRF中断终于到来,ISR读取DATA 2。
  6. 后续的DATA 4接收时,因为OVRF标志未被清除(我们没处理它),硬件会阻止SPRF再次被置位。于是,DATA 4及之后的所有数据都“静默”丢失了,SPRF中断再也无法触发,程序看似正常,实则通信已断。

解决方案

  1. 启用错误中断(推荐): 直接设置ERRIE=1。这样一旦发生OVRF,会立即进入错误中断服务程序。在错误ISR中,按照“读SPSCR -> 读SPDRR”的顺序清除OVRF标志,并记录错误、尝试恢复通信(例如重置缓冲区)。
  2. 双读SPSCR法(无错误中断时): 如果因某些原因不能启用错误中断,则必须在每次SPRF中断服务程序中,采用以下安全读取序列:
    // 在SPRF中断服务程序中 volatile uint16_t status = SPI_SPSCR; // 第一次读SPSCR,获取状态 volatile uint16_t data = SPI_SPDRR; // 读数据,清除SPRF status = SPI_SPSCR; // 第二次读SPSCR,检查OVRF是否在刚才被置位 if (status & SPI_OVRF_MASK) { // 发生了溢出!需要处理:清除OVRF,并可能丢弃缓冲区的数据或进行复位 data = SPI_SPDRR; // 再次读SPDRR以清除OVRF(根据手册序列) // ... 错误处理逻辑 ... } // 正常处理 `data`
    第二次读取SPSCR就是为了捕捉在“第一次读SPSCR”和“读SPDRR清除SPRF”这个极短时间窗口内可能发生的溢出。

4.2 模式故障:硬件冲突的“保险丝”

模式故障(MODF)是一种硬件保护机制,用于防止因主从模式配置与SS引脚电平冲突而导致的总线竞争和硬件损坏

触发条件

  • 主机模式(SPMSTR=1): 当MODFEN=1时,如果SS引脚被拉低(变为逻辑0),则立即触发MODF。
  • 从机模式(SPMSTR=0): 当MODFEN=1时,如果SS引脚在传输过程中被拉高,则触发MODF。这里的“传输过程”定义与CPHA有关:
    • CPHA=0: 传输从SS变低开始,到最后一个数据位移出后SCLK回到空闲电平结束。在此期间SS变高即触发。
    • CPHA=1: 传输从SCLK离开空闲电平开始(此时SS必须已为低),到SCLK回到空闲电平结束。在此期间SS变高即触发。

触发后的硬件行为

  • 在主机上: MODF是严重错误。一旦发生,硬件会自动:
    1. 清除SPE位(禁用SPI模块)。
    2. 置位SPTE
    3. 清除SPI状态计数器。
    4. 如果ERRIE=1,产生中断。 这相当于对SPI进行了一次“急刹车”,防止主机在SS被拉低(可能意味着另一个设备想成为主机)时继续驱动总线,造成短路。
  • 在从机上: MODF不会禁用SPI。它只是置位MODF标志,如果ERRIE=1则产生中断。从机的MISO引脚会进入高阻态,并忽略所有SCLK时钟。软件可以通过清除SPE位来主动中止传输。

清除MODF: 需要向MODF位写1来清除。但前提是导致MODF的条件已经消失(主机上SS已恢复为高,从机上SS已稳定为低或传输已结束)。否则,写1操作无效。

实战心得:MODF的预防与处理

  • 主机SS引脚处理: 在标准单主机、多从机系统中,主机通常将SS引脚配置为通用输出(GPIO),并直接控制其电平来选通从机。此时,务必设置主机的MODFEN=0,或者确保主机的SS引脚(即使配置为输入)不会被意外拉低。否则,任何干扰导致主机SS引脚为低,都会触发MODF并禁用SPI,导致通信瘫痪。
  • 从机SS引脚连接: 从机的SS引脚必须由主机可靠控制。在CPHA=0模式下要特别注意,SS的下降沿和上升沿都是传输的一部分,必须保证时序。长线缆可能引入毛刺,导致意外MODF。必要时可考虑在软件中暂时禁用MODF检测(MODFEN=0),但会失去保护。
  • 多主机系统: 在多主机争用总线的系统中,MODF机制是关键。每个主机平时配置为从机(SPMSTR=0),当要发送数据时,先尝试拉低总线上的SS线(通常作为总线仲裁线)。如果自己拉低成功且未触发MODF(说明没有其他主机在活动),则将自己切换为主机(SPMSTR=1)开始通信。通信结束后,再切换回从机。这个过程需要软件精心设计。

5. 中断与DMA配置:解放CPU,实现高效传输

对于需要连续、高速传输大量数据的应用(如音频流、图像传感器),依赖CPU轮询SPTESPRF标志是不现实的,会消耗大量CPU资源。中断和DMA才是正确的选择。

5.1 中断驱动传输流程设计

一个典型的中断驱动、双缓冲SPI发送流程如下(以主机发送为例):

  1. 初始化

    • 配置GPIO、时钟、SPI为主机模式、设置CPOL/CPHA、波特率等。
    • 使能发送中断(SPTIE=1)和接收中断(SPRIE=1)。
    • 使能错误中断(ERRIE=1)。
    • 使能SPI模块(SPE=1)。此时发送缓冲区为空,SPTE会立即置位,触发第一次发送中断。
  2. 发送中断服务程序 (SPTE中断)

    void SPI_Transmit_IRQHandler(void) { if (tx_buffer_index < tx_buffer_length) { SPI->SPDTR = tx_buffer[tx_buffer_index++]; // 写入数据,清除SPTE } else { // 所有数据发送完毕 SPI->SPSCR &= ~SPI_SPTIE_MASK; // 可选:禁用发送中断 tx_complete_flag = 1; // 设置完成标志 } // 清除中断标志(通常写SPDTR即清除了SPTE中断源) }

    关键点:只要SPTE=1,中断就会触发。在ISR中写入SPDTR,硬件加载数据后SPTE会再次置1,从而触发下一次中断,形成链式反应,直到我们主动停止(如禁用中断或不再写入数据)。

  3. 接收中断服务程序 (SPRF中断)

    void SPI_Receive_IRQHandler(void) { volatile uint16_t status = SPI->SPSCR; // 先读状态 uint16_t data = SPI->SPDRR; // 读数据,清除SPRF // 安全检测:检查是否发生溢出 if (status & SPI_OVRF_MASK) { // 发生了溢出错误! data = SPI->SPDRR; // 再次读SPDRR以清除OVRF(遵循手册序列) overflow_counter++; // 可能需要重置接收状态或上报错误 } else { // 正常处理数据 if (rx_buffer_index < rx_buffer_size) { rx_buffer[rx_buffer_index++] = data; } } }

    关键点:遵循“先读SPSCR,再读SPDRR”的规范,并在读数据后检查OVRF,以实现安全的数据读取。

5.2 DMA模式:极致性能的追求

对于超高带宽或极低CPU占用的场景,DMA(直接存储器访问)是终极方案。SPI模块的DMA模式通过TDMAEN(发送DMA使能)和RDMAEN(接收DMA使能)位来启用。

DMA模式下的变化

  • 中断抑制: 当DMA使能后,正常的SPTESPRF中断被抑制。取而代之的是,硬件会向DMA控制器发出传输请求。
  • 标志清除机制简化: 在DMA模式下,清除SPTESPRF标志的机制从“读SPSCR+读/写数据寄存器”简化为直接读写数据寄存器本身。DMA控制器在完成一次SPDTR写入或SPDRR读取后,会自动完成标志清除工作,无需软件干预。
  • 错误中断依然有效OVRFMODF错误中断(由ERRIE控制)不受DMA模式影响,依然可以触发CPU中断。这对于在DMA传输过程中监控致命错误至关重要。

DMA配置步骤

  1. 配置SPI为所需的工作模式。
  2. 设置TDMAEN和/或RDMAEN
  3. 配置DMA控制器:
    • 设置源/目标地址(内存缓冲区地址 vs. SPI数据寄存器地址)。
    • 设置传输数据宽度(与SPI的TDS设置一致)。
    • 设置传输数量。
    • 将DMA请求与SPI的TX/RX请求线连接。
  4. 启动DMA传输,然后启动SPI传输(例如,向SPDTR写入第一个数据,或由外部主机提供时钟)。
  5. 在DMA传输完成中断或SPI错误中断中处理后续事宜。

性能调优与注意事项

  • 缓冲区管理: 中断驱动下,双缓冲(乒乓缓冲)是常见策略,即准备两个缓冲区,一个用于发送/接收,另一个用于CPU处理,交替使用。DMA模式下,可以设置更大的循环缓冲区。
  • 中断优先级: SPI接收中断的优先级通常应高于发送中断,因为接收数据不及时会导致溢出。错误中断(OVRF/MODF)的优先级应设为最高,以便及时响应致命错误。
  • 波特率与CPU速度: 高速SPI通信时,必须确保ISR的执行时间足够短,能在下一帧数据到来前完成读写操作。计算一下:假设SPI波特率为10 Mbps,传输16位数据,则一帧耗时1.6微秒。你的ISR必须在1.6微秒内完成,否则就可能溢出。此时DMA几乎是必须的。
  • CPHA=0与DMA: 手册特别指出,不要在DMA模式下使用CPHA=0。这是因为在CPHA=0模式下,从机的SS引脚需要在帧��切换,而DMA传输是连续的,很难精确插入SS的控制时序,容易导致通信故障。在DMA应用中,优先使用CPHA=1模式。

6. 典型问题排查与调试技巧实录

即使理解了所有原理,实际调试中还是会遇到各种问题。下面是我总结的一些常见问题场景和排查思路。

6.1 通信完全无反应

  • 检查清单
    1. 电源与时钟: 测量MCU和从设备供电是否正常。确认MCU的SPI外设时钟是否使能(例如,在STM32中需要开启APB总线时钟)。
    2. 引脚配置: 确认SCK、MOSI、MISO、SS引脚是否已正确配置为SPI复用功能,而非普通GPIO。用万用表或示波器检查引脚是否有输出。
    3. SPE位: 确认SPI使能位SPE是否已设置为1。这是一个非常低级但常见的疏忽。
    4. 主从模式: 确认SPMSTR位设置是否正确。主机应设为1,从机设为0。
    5. SS引脚(主机): 如果主机MODFEN=1,检查SS引脚电平。如果被意外拉低,会触发MODF并自动禁用SPI(SPE被清0)。读取MODF标志确认。

6.2 能发送,但接收不到数据,或数据全为0/0xFF

  • 检查清单
    1. CPOL/CPHA这是最常见的原因!用示波器同时测量主机的SCK和MOSI,以及从机的MISO。对照数据手册,检查数据采样边沿是否匹配。主从设备的CPOL和CPHA必须绝对一致。
    2. 从设备是否被选中: 确认从设备的SS引脚已被主机拉低。有些从设备在SS为高时会关闭MISO输出(高阻态),导致主机读到全1(0xFF)。
    3. MISO引脚连接: 检查MISO线路是否连接正确,有无虚焊或短路。
    4. 从设备本身: 确认从设备是否工作正常,是否需要特定的初始化序列(例如,某些Flash芯片需要先发送命令才能读数据)。
    5. 接收中断或轮询: 确认是否已使能接收中断(SPRIE=1)或在轮询SPRF标志。数据收到后必须及时从SPDRR读出,否则会卡住。

6.3 数据错位或字节顺序错误

  • 检查清单
    1. 数据移位顺序: 检查DSO位。DSO=0为MSB先出,DSO=1为LSB先出。主从设备必须一致。常见协议如SD卡多用MSB first,而有些ADC芯片用LSB first。
    2. 数据位宽: 检查TDS位设置。主从设备传输的数据位数必须相同。如果你配置为8位(TDS=7),却按16位去读写寄存器,就会发生错位。
    3. 软件数据处理: 读取SPDRR后,是否根据DSOTDS对数据进行了正确的移位和掩码操作?例如,12位ADC数据在16位寄存器中,可能左对齐或右对齐,需要移位才能得到真实值。

6.4 偶尔发生数据丢失或溢出错误

  • 检查清单
    1. 中断响应延迟: 这是导致OVRF的主要原因。检查系统中断是否被长时间关闭(全局中断禁用、高优先级中断阻塞)。优化ISR代码,使其尽可能短小精悍。
    2. 缓冲区处理不及时: 在中断服务程序中,如果只是将数据复制到软件缓冲区,要确保缓冲区足够大,不会因为生产速度大于消费速度而被写满。考虑使用环形缓冲区。
    3. 遵循安全读取序列: 是否在接收ISR中遵循了“读状态->读数据->再读状态查溢出”的安全序列?如果没有,可能会漏检溢出。
    4. 波特率过高: 计算一下CPU处理中断的最坏情况时间,是否超过SPI传输一帧数据的时间?如果接近或超过,必须降低波特率或使用DMA。

6.5 调试工具与技巧

  • 逻辑分析仪: 这是调试SPI的神器。可以同时捕获SCK、MOSI、MISO、SS四路信号,直观地看到每一位数据、每个帧的时序。能清晰展示CPOL/CPHA配置是否正确,数据内容是什么。
  • 示波器: 用于观察信号质量,检查是否有过冲、振铃、毛刺。测量SCK频率是否与配置相符。
  • 寄存器查看: 在调试器中实时查看SPSCR等关键寄存器的值。观察SPTESPRFOVRFMODF标志的变化,可以快速定位是发送卡住、接收未就绪还是发生了错误。
  • 软件模拟: 在硬件问题难以排查时,可以尝试将SPI引脚先配置为GPIO,用软件模拟SPI时序(位翻转)来与从设备通信。如果软件模拟能通,但硬件SPI不通,问题很可能出在SPI模块的配置上。
http://www.jsqmd.com/news/1030425/

相关文章:

  • 2026年制造业转型升级咨询服务商全景对标|IATF16949、精益生产、数字化一站式解决方案 - 年度推荐企业名录
  • 涵盖多领域!2026十大高质量可免费下载图片素材的网站推荐,自媒体电商设计通用 - 品牌2026
  • 2026年查标讯工具对比参考 轻量化找标提升投标效率 - 速递信息
  • 禹州装修设计公司推荐,专业设计首选禹州一品装饰 - 猜不透的vv
  • 国产大模型免登录直用指南:通义千问、Kimi、GLM-4网页实测
  • 2026保姆级指南:免费录音转文字工具大全,手机电脑离线本地软件手把手教程 - 办公小帮手
  • CLEVR-IEP高级技巧:10个优化策略提升程序推断准确率与执行效率
  • FusionFix:让GTA IV完整版在现代系统上焕发新生的终极修复方案
  • 2026济南手表回收避坑大全!5家老牌门店实测,新手卖表不被宰 - 奢侈品回收评测
  • 终极指南:用G-Helper轻松恢复华硕笔记本出厂级色彩显示
  • 2026年长沙零基础学化妆:从转行小白到月入万元的完整进阶指南 - 精选优质企业推荐官
  • Java毕业设计基于 SpringBoot+Vue 的数码产品电商商城系统的设计与实现 前后端分离架构下数码产品购物平台的设计与开发-(源码+LW+部署文档+全bao+远程调试+代码讲解等)
  • 从SEO到GEO,如何用数据分析工具驱动AI搜索排名精准监测
  • 2026四川省学费便宜的师范类学校,报考参考大盘点 - 品牌2026
  • 喀什地面工程推荐!4 家本地地坪商家实测对比,施工避坑干货汇总 - 国麟测评
  • LabVIEW路径处理实战:从开发到部署的避坑指南
  • 2026年长沙化妆培训学校怎么选?零基础美业转行必读的深度横评与官方联系指南 - 精选优质企业推荐官
  • 终极Minecraft基岩版启动器:如何用Bedrock Launcher彻底改变你的游戏体验
  • 曲靖宽带2026技术实力排行榜,哪家办理最值得选? - 热点速览
  • 2026保姆级教程:PPT导出高清PDF无压缩方法,多款不压缩画质工具手把手教学 - 办公小帮手
  • i.MX 6 VPU API实战:嵌入式视频硬件编解码开发指南
  • iNaturalist竞赛伦理指南:数据使用限制与生物多样性保护的终极解析
  • 2026连云港黄金回收白名单:本地人亲测、无隐性消费的六家老店 - 商业信息快查
  • 入手冲动消费名表,及时回血收手,告别高额贬值内耗 - 逸程
  • 借力成都产区硬核实力,良品道卫浴领跑川派全卫高定性价比赛道 - 速递信息
  • 2026年重庆污水处理设备与纯水设备完全选型指南:源头厂家深度评测 - 优质企业观察收录
  • 2026 天津名包回收白名单,本地人实地亲测,五家无隐形消费门店 - 讯息早知道
  • 成都双流区疏通下水道 2026 本地下水道疏通公司真实评测最新综合排行榜 - 居顺联家政疏通
  • 什邡理发店 - 热点速览
  • 宁波迪奥包包戴妃、蒙田、Book Tote回收行情大爆料,速看! - 逸程