LPC210x SPI/SSP实战:从寄存器配置到时序调试全解析
2026/6/20 18:28:58 网站建设 项目流程

1. 项目概述:从手册到实战,拆解LPC210x的SPI核心

如果你正在用LXP2101/02/03这类经典的ARM7微控制器做项目,大概率绕不开SPI(Serial Peripheral Interface)这个外设。无论是驱动一块OLED屏幕、读取一个Flash芯片,还是和传感器通信,SPI都是那个既简单又高效的“老伙计”。手册(比如NXP的UM10161)里关于SPI的章节动辄几十页,寄存器描述表格一个接一个,乍一看让人头大。但说穿了,SPI的本质就是主从双方踩着同一个节拍(时钟SCK),通过两根数据线(MOSI和MISO)同时收发数据,再用一根片选线(SSEL)告诉从机“该你上场了”。

LPC210x系列提供了两个串行接口:SPI0和SPI1(后者实际是更强大的SSP控制器)。手册里那些密密麻麻的位描述,其实都是在回答几个核心问题:时钟怎么产生?数据怎么装进去、怎么读出来?怎么知道一次传输完成了?中断怎么用?本文不会照本宣科地翻译手册,而是结合我这些年调试SPI外设的经验,带你穿透寄存器表格,直抵配置精髓。我们会重点剖析SPI0的基础寄存器,并对比SSP(SPI1)的增强功能,让你不仅知道要填什么值,更明白为什么这么填,以及在实践中哪些坑需要提前避开。

2. SPI基础原理与LPC210x实现架构

2.1 SPI通信的本质:一个关于节奏的简单协议

SPI协议的精髓在于“同步”和“全双工”。你可以把它想象成两个人(主设备和从设备)面对面坐着,中间有一个节拍器(SCK时钟)。节拍器每响一下,双方就同时交换一张小纸条(一位数据)。主人手里有一叠要送出的纸条(通过MOSI线送出),同时也准备接收对方的纸条(通过MISO线接收)。而片选信号SSEL,就像是主人点名:“张三,现在开始跟你交换纸条”。其他从设备(李四、王五)虽然也连着线,但因为没被点名,就会把自己的MISO线置为高阻态,避免总线冲突。

这种设计带来了几个关键优势:首先,它没有像UART那样复杂的起始位、停止位和波特率同步问题,通信速率可以很高(在LPC210x上轻松达到几兆比特每秒)。其次,全双工意味着数据吞吐效率高,虽然很多时候我们只关心单向数据(比如只读传感器),但硬件上收发是同时进行的。最后,协议本身极其简单,硬件实现成本低,这也是它能在各种芯片上普及的原因。

2.2 LPC210x的SPI硬件蓝图:两个大脑,一套拳法

LPC210x提供了两套串行外设,它们的定位和能力有所不同:

  • SPI0:这是一个“经典”或“基础”的SPI控制器。它的功能相对固定,主要服务于标准的Motorola SPI协议。它的寄存器集较小,配置直观,适合对时序和模式要求标准的应用,比如连接简单的SPI Flash或ADC芯片。
  • SPI1 (SSP):这是一个“同步串行端口”,功能强大得多。它不仅完全兼容SPI0的功能,还支持TI的SSI(Synchronous Serial Interface)和National Semiconductor的Microwire协议。更重要的是,它内置了深度为8的发送和接收FIFO(先入先出缓冲区),支持4到16位可变数据帧长度,并且拥有更灵活的中断机制。对于需要高速、大数据量或兼容多种设备的应用,SSP是更优选择。

从手册提供的框图可以看出,无论是SPI0还是SSP,其核心硬件结构都包含几个关键部分:

  1. 时钟生成器:根据APB总线时钟(PCLK)和配置的分频系数,产生驱动数据传输的SCK时钟。这是通信速率的基础。
  2. 移位寄存器:这是数据吞吐的核心。发送时,并行数据从数据寄存器装入,在SCK驱动下一位一位地移出到MOSI线;接收时,从MISO线移入的数据一位一位地组装,最终并行存入数据寄存器。
  3. 控制逻辑:根据CPOL(时钟极性)和CPHA(时钟相位)的设置,精确控制数据在SCK的哪个边沿被采样(捕获),在哪个边沿被更新(输出)。这是SPI模式匹配的关键。
  4. 数据缓冲与接口:对于SPI0,主要是数据寄存器;对于SSP,则升级为FIFO。这部分负责与CPU内核交互,CPU写入要发送的数据,读取已接收的数据。
  5. 中断逻辑:当发送完成、接收就绪或发生错误(如溢出)时,通知CPU进行处理,避免轮询带来的效率损失。

理解了这个硬件蓝图,再看寄存器配置,就会明白每一个配置位都是在控制这个流水线上的某个开关或齿轮。

2.3 核心概念:CPOL与CPHA——定义通信的“舞蹈步伐”

这是SPI配置中最容易混淆,也最关键的部分。它决定了时钟线和数据线的时序关系。

  • CPOL (Clock Polarity,时钟极性):定义SCK线在空闲状态(即两次传输之间,SSEL无效时)的电平。
    • CPOL = 0:空闲时SCK为低电平。
    • CPOL = 1:空闲时SCK为高电平。
  • CPHA (Clock Phase,时钟相位):定义数据在SCK的哪个边沿被采样(捕获)。
    • CPHA = 0:数据在SCK的第一个边沿(即从空闲状态跳变到有效状态的第一个边沿)被采样。
    • CPHA = 1:数据在SCK的第二个边沿(即跳变回空闲状态的那个边沿)被采样。

这两者的组合构成了四种SPI模式,通常被称为Mode 0, 1, 2, 3:

  • Mode 0: CPOL=0, CPHA=0。空闲时钟低,数据在SCK上升沿采样。
  • Mode 1: CPOL=0, CPHA=1。空闲时钟低,数据在SCK下降沿采样。
  • Mode 2: CPOL=1, CPHA=0。空闲时钟高,数据在SCK下降沿采样。
  • Mode 3: CPOL=1, CPHA=1。空闲时钟高,数据在SCK上升沿采样。

实操心得:绝大多数SPI从设备(如Flash、传感器)的数据手册都会明确要求使用哪种模式。配置错误是导致通信失败的最常见原因之一。一个快速记忆方法是:Mode 0和Mode 3是数据在时钟边沿“同相”变化(即数据在时钟边沿稳定,在下一个边沿采样);而Mode 1和Mode 2是“反相”的。但最稳妥的办法永远是查阅从设备的数据手册时序图,并确保主从设备的CPOL和CPHA设置完全一致。

3. SPI0寄存器精讲与配置实战

我们首先深入SPI0,它的寄存器较少,是理解SPI基础操作的绝佳模型。SPI0的核心寄存器主要集中在数据交换、时钟控制和状态查询。

3.1 SPI数据寄存器(S0SPDR - 0xE0020008):数据的出入口

这是一个16位的双向数据寄存器,但实际使用的位数取决于传输的帧长度(通常为8位)。

  • 功能:这是CPU与SPI硬件移位寄存器之间的桥梁。当你需要发送数据时,将数据写入这个寄存器;当SPI接收到数据后,你可以从这个寄存器读取。
  • 关键行为(手册原文的实战解读)
    1. 启动传输:在主机模式下,向S0SPDR写入数据这个动作本身,就会启动一次SPI数据传输。硬件会自动将数据从S0SPDR加载到内部的发送移位寄存器,然后开始产生SCK时钟并移出数据。
    2. 写入阻塞:手册明确指出,从一次数据传输开始,直到状态寄存器中的SPIF位(传输完成标志)被置位且状态寄存器已被读取之前,对S0SPDR的写操作会被硬件阻塞。这意味着你不能在传输进行中盲目地连续写入数据,必须通过查询SPIF标志或使用中断来确保前一次传输已完成。
    3. 数据对齐:如果配置为传输少于16位的数据(比如8位),软件在写入时必须将数据右对齐在寄存器的低有效位。例如,发送一个8位数据0xA5,应写入S0SPDR = 0x00A5

配置示例:发送一个字节数据假设我们已初始化SPI0为主机模式,8位数据帧。发送数据的代码流程如下:

// 1. 等待上一次传输完成(通过轮询状态寄存器S0SPSR的SPIF位) while ((S0SPSR & (1 << 7)) == 0); // 等待SPIF位变为1 // 2. 可选:读取状态寄存器以清除SPIF标志(根据手册,读状态寄存器是解除写入阻塞的条件之一) volatile uint8_t dummy = S0SPSR; // 3. 将待发送数据写入数据寄存器,启动传输 S0SPDR = 0x55; // 发送数据0x55

3.2 SPI时钟计数器寄存器(S0SPCCR - 0xE002000C):掌控通信速率

这个8位寄存器直接决定了主机模式下SCK时钟的频率,是配置通信速率的核心。

  • 计算公式SPI0_SCK = PCLK / S0SPCCR
    • PCLK是APB外设总线时钟,由系统主时钟CCLK通过APBDIV寄存器分频得到。例如,如果CCLK=60MHzAPBDIV配置为分频4,则PCLK=15MHz
    • S0SPCCR就是你要写入这个寄存器的值。
  • 硬性约束
    1. 写入的值必须为偶数(Bit 0必须为0)。这是因为硬件需要产生占空比为50%的时钟。
    2. 写入的值必须大于或等于8。手册警告,违反此规则可能导致不可预测的行为。这通常是为了保证内部逻辑有足够的时间稳定。

配置示例:计算并设置SPI波特率假设我们需要SPI0的SCK频率为1MHz,且已知PCLK = 12MHz

  1. 计算分频系数:S0SPCCR = PCLK / Desired_SCK = 12MHz / 1MHz = 12
  2. 检查约束:12是偶数且大于等于8,符合要求。
  3. 写入寄存器:S0SPCCR = 12;

注意事项:这个寄存器仅在SPI0作为主机时有效。当SPI0配置为从机时,SCK时钟由外部主机提供,此寄存器的值无意义。此外,过高的SCK频率可能导致信号完整性问题,尤其是板子布线较长时。如果通信不稳定,尝试降低S0SPCCR的值(即降低SCK频率)是首要的排查步骤。

3.3 SPI状态与控制:完成标志与中断

虽然输入材料未详细列出SPI0的所有状态和控制寄存器,但基于SPI通用架构,通常会有以下关键标志位(在S0SPSR状态寄存器中):

  • SPIF (SPI Transfer Complete Flag):当一次数据传输完成(即移位寄存器中的所有位都已移出/移入)时,该位由硬件置1。这是判断一次SPI操作是否完成的主要标志。读取状态寄存器会自动清除该标志(或需要软件手动清除,具体看手册),这也是解除对S0SPDR写入阻塞的条件。
  • WCOL (Write Collision Flag):如果在一次传输尚未完成时(即SPIF为0时)尝试写入S0SPDR,该标志会被置1,并且这次写入会被忽略。这用于指示软件时序错误。
  • MODF (Mode Fault Flag):在多主机系统中,当检测到总线冲突时置位。

中断使用:通过SPI中断寄存器(S0SPINT)可以使能传输完成中断。当SPIFWCOL置位且中断使能时,会触发SPI中断。在中断服务程序中,你需要读取状态寄存器来判断中断原因,并处理数据或错误。

4. SSP(SPI1)高级功能与寄存器解析

SSP控制器是SPI0的超级增强版,它通过更丰富的寄存器提供了更强的灵活性和性能。我们重点看它与基础SPI0的区别和高级功能。

4.1 核心控制寄存器0(SSPCR0):定义通信框架

这个寄存器定义了数据传输的基本“框架协议”。

  • DSS[3:0] (Data Size Select):这是SSP相比SPI0的一大增强,支持4到16位可变长度数据帧。这非常有用,例如某些音频编解码器需要16位数据,而某些简单的数字电位器只需要8位或更少。配置时直接写入对应的二进制值(0x3对应4位,0xF对应16位)。切勿使用0000-0010之间的保留值
  • FRF[5:4] (Frame Format):选择通信协议。
    • 00: Motorola SPI模式(最常用)。
    • 01: TI同步串行接口(SSI)模式。
    • 10: National Semiconductor Microwire模式。
    • 11: 保留,勿用。
  • CPOL与CPHA:功能同SPI0,用于设置SPI的四种模式。
  • SCR[15:8] (Serial Clock Rate):这是SSP时钟分频的第二级因子。SSP的总分频公式为:Bit Clock = PCLK / (CPSDVSR * (SCR + 1))。其中CPSDVSR是另一个预分频寄存器(SSPCPSR)的值。SCR可以为0-255,提供了更精细的波特率调节能力。

4.2 核心控制寄存器1(SSPCR1):模式与使能

  • SSE (SSP Enable):SSP总开关。必须在配置完所有其他SSP寄存器(如SSPCR0, SSRCPSR)之后,最后才将此位置1来使能SSP。在修改除MS位以外的其他配置前,也需要先清除此位。
  • MS (Master/Slave Mode):选择主从模式。0为主机,1为从机。注意,此位只有在SSE=0(SSP禁用)时才能被修改。
  • SOD (Slave Output Disable):仅在从机模式下有效。如果置1,则禁止SSP从机驱动MISO线。这在多从机系统中,当某个从机未被选中时非常有用,可以确保其MISO输出为高阻态,避免总线冲突。

4.3 数据寄存器(SSPDR)与FIFO操作

SSPDR是一个16位的数据寄存器,但其背后连接着深度为8的发送和接收FIFO。这是SSP性能优于SPI0的关键。

  • 发送流程:当发送FIFO非满(TNF状态位为1)时,CPU可以连续向SSPDR写入最多8帧数据。硬件会自动按顺序将数据从发送FIFO取出并发送。这大大减轻了CPU的负担,允许进行批量数据传输而不必频繁等待和查询。
  • 接收流程:当接收FIFO非空(RNE状态位为1)时,CPU可以从SSPDR连续读取最多8帧已接收的数据。
  • 数据对齐:同SPI0,写入的数据必须根据DSS设置进行右对齐。读取时,高位无效位为0。

配置示例:利用FIFO发送多个数据

// 假设SSP已初始化为主机,8位数据帧 uint8_t tx_data[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; for(int i = 0; i < 8; i++) { // 等待发送FIFO有空间(非满) while((SSPSR & (1 << 1)) == 0); // 等待TNF位为1 SSPDR = tx_data[i]; // 写入数据,会自动进入发送FIFO } // 此时,8个数据可能还在陆续发送中,可以继续做其他事情,或者等待BSY位变0

4.4 时钟预分频寄存器(SSPCPSR)与波特率精确计算

SSPCPSR是SSP波特率公式中的第一级分频器(CPSDVSR)。手册特别强调,此寄存器必须正确初始化,否则SSP无法正常工作

  • 约束:必须写入一个2到254之间的偶数值(所以Bit 0总是0)。
  • 主从模式最小值不同
    • 主机模式:CPSDVSR最小为2。
    • 从机模式:CPSDVSR最小为12。这是因为从机需要更快的内部时钟来可靠地采样外部主机提供的SCK信号。

波特率计算实战: 目标:配置SSP为主机,SCK波特率为2MHz。已知PCLK = 48MHz

  1. 选择CPSDVSR值。为了得到整数分频,我们先试一个值,比如CPSDVSR = 4
  2. 计算所需的SCR值:根据公式Bit Clock = PCLK / (CPSDVSR * (SCR + 1))
    • 代入:2MHz = 48MHz / (4 * (SCR + 1))
    • 解得:SCR + 1 = 48 / (4 * 2) = 6
    • 所以SCR = 5
  3. 验证:48MHz / (4 * (5+1)) = 48MHz / 24 = 2MHz。符合要求。
  4. 配置代码:
    SSPCPSR = 4; // 预分频系数,必须是偶数且在2-254之间 SSPCR0 = (0x07 << 0) // DSS=0x07, 选择8位数据帧 | (0x00 << 4) // FRF=00, SPI模式 | (0x00 << 6) // CPOL=0 | (0x00 << 7) // CPHA=0 | (5 << 8); // SCR=5

4.5 中断系统详解:高效的数据处理

SSP提供了比SPI0更精细的中断控制,这是实现高效、低CPU占用率通信的关键。相关寄存器有四个:SSPIMSC(中断掩码设置/清除)、SSPRIS(原始中断状态)、SSPMIS(已屏蔽中断状态)、SSPICR(中断清除)。

  • 中断类型

    1. 接收超时中断(RTIM):当接收FIFO非空,且在32个位时间周期内既没有新数据收到,也没有数据被CPU读取,此中断触发。可用于处理数据流意外结束的情况。
    2. 接收FIFO半满中断(RXIM):当接收FIFO中的数据量达到或超过其深度的一半(即至少4个数据)时触发。这是最常用的接收中断方式,可以批量读取数据,减少中断次数。
    3. 发送FIFO半空中断(TXIM):当发送FIFO中的数据量减少到一半或以下(即空闲空间>=4)时触发。用于在发送过程中及时补充数据,维持数据流不断。
    4. 接收溢出中断(RORIM):当接收FIFO已满,但又一帧数据完全接收完毕时触发。此时新数据会覆盖旧数据,造成数据丢失,属于错误中断。
  • 中断使用流程

    1. 初始化时配置:在SSPCR1SSE位置1使能SSP前,先配置SSPIMSC寄存器,使能所需的中断(如RXIMTXIM)。
    2. 在NVIC中使能SSP中断:配置ARM内核的嵌套向量中断控制器(NVIC),使能SSP对应的中断通道。
    3. 编写中断服务程序(ISR)
      void SSP_IRQHandler(void) { uint32_t mis_status = SSPMIS; // 读取已使能并触发的中断状态 if (mis_status & (1 << 2)) { // 接收半满中断 while(SSPSR & (1 << 2)) { // 当接收FIFO非空时循环读取 uint16_t received_data = SSPDR; // ... 处理 received_data ... } } if (mis_status & (1 << 3)) { // 发送半空中断 // 检查发送FIFO是否有空间,并填充新的待发送数据 // while((SSPSR & (1 << 1)) && (has_more_data)) { // SSPDR = next_tx_data; // } } if (mis_status & (1 << 0)) { // 接收溢出中断(错误处理) // 1. 读取SSPICR的RORIC位写1清除中断标志 // 2. 可能需要清空接收FIFO并记录错误 SSPICR = (1 << 0); } // ... 其他中断处理 ... }
    4. 清除中断标志:对于RORIMRTIM中断,需要在ISR中向SSPICR寄存器的对应位写1来清除。对于RXIMTXIM,通过读写SSPDR(即操作FIFO)会自动清除。

5. 不同SPI模式下的时序图深度解读与配置要点

手册中的时序图是理解CPOL和CPHA如何影响通信的终极指南。我们结合图表,提炼出每种模式下的配置和操作要点。

5.1 Mode 0 (CPOL=0, CPHA=0) 与 Mode 2 (CPOL=1, CPHA=0)

这两种模式有一个共同关键点:数据在时钟的第一个边沿被采样。对于Mode 0,第一个边沿是SCK从低到高的上升沿;对于Mode 2,第一个边沿是SCK从高到低的下降沿。

操作要点(主机侧)

  1. 片选(SSEL)行为:在单次传输中,SSEL在传输开始前变低,在最后一位数据被采样后的一个SCK周期后变高。
  2. 连续传输的陷阱:在连续背靠背传输(即一次发送多个数据帧,中间不释放SSEL)时,SSEL必须在每帧之间有一个短暂的高电平脉冲。手册明确指出,这是因为当CPHA=0时,从机的片选引脚会“冻结”其内部移位寄存器的数据,如果不拉高SSEL,从机将无法更新下一帧要发送的数据。这是很多人在进行多字节连续读写时容易忽略的细节,会导致从第二字节开始通信失败。
  3. 配置代码提示:对于Mode 0,设置CPOL=0, CPHA=0;对于Mode 2,设置CPOL=1, CPHA=0。在连续传输代码中,需要在帧间手动控制SSEL引脚(如果使用硬件SSEL,则需确保控制器支持此特性,或改用软件模拟SSEL)。

5.2 Mode 1 (CPOL=0, CPHA=1) 与 Mode 3 (CPOL=1, CPHA=1)

这两种模式的共同点是:数据在时钟的第二个边沿被采样

操作要点

  1. 时序差异:数据在时钟的第二个边沿(即跳变回空闲状态的那个边沿)被捕获。这意味着数据线在时钟的第一个边沿就准备好(输出),并保持稳定直到被采样。
  2. 连续传输的优势:在连续背靠背传输时,SSEL可以始终保持低电平,无需在帧间拉高。这简化了连续传输的软件控制,提高了传输效率。
  3. 配置代码提示:对于Mode 1,设置CPOL=0, CPHA=1;对于Mode 3,设置CPOL=1, CPHA=1。这是许多SPI Flash芯片常用的模式(尤其是Mode 3)。

5.3 Microwire模式配置要点

Microwire是半双工协议,每次传输分为两个阶段:主机先发送一个8位命令字,然后从机回应4-16位数据。

  • 关键配置:在SSPCR0中,设置FRF=10选择Microwire模式,并根据从机回应数据的长度设置DSS(例如,如果回应16位数据,则DSS=0xF)。
  • 操作流程
    1. 主机将8位命令字写入发送FIFO。
    2. 主机拉低CS(片选)。
    3. 硬件自动发送8位命令字。在此期间,主机不接收数据。
    4. 命令发送完毕后,硬件自动等待一个SCK时钟周期(等待从机解码)。
    5. 从机在随后的SCK周期里,将回应数据位发送到主机的MISO线上。
    6. 主机接收完指定长度的数据后,拉高CS。
  • 时序要求:手册图13-52强调了在Microwire模式下,CS信号相对于SCK的建立时间(tSETUP)和保持时间(tHOLD)要求。如果SCK是自由运行的,主机必须确保满足这些时序,否则从机可能无法正确识别帧开始。

6. 实战配置流程、常见问题与调试技巧

6.1 LPC210x SPI/SSP初始化标准流程

无论使用SPI0还是SSP,一个健壮的初始化流程应遵循以下步骤:

  1. 步骤一:电源与时钟使能

    • 通过PCONP(外设功率控制寄存器)使能SPI0或SSP模块的时钟。
    • 确认PCLK的时钟频率(通过APBDIV寄存器配置),这是计算波特率的基础。
  2. 步骤二:引脚功能配置

    • 通过PINSELx寄存器,将对应的GPIO引脚功能选择为SPI/SSP功能(例如,P0.4SCK0,P0.5MISO0,P0.6MOSI0,P0.7SSEL0)。
    • 注意:如果使用软件控制片选(推荐,更灵活),则SSEL引脚可以配置为普通GPIO输出,并在代码中手动控制。
  3. 步骤三:寄存器配置(以SSP主机,Mode 0, 8位数据为例)

    // 1. 禁用SSP (SSE=0),在禁用状态下配置其他寄存器 SSPCR1 = 0x00; // 2. 配置时钟预分频器 (必须为2-254的偶数) SSPCPSR = 2; // 例如,预分频为2 // 3. 配置控制寄存器0 (数据长度、帧格式、CPOL/CPHA、SCR) // 假设PCLK=12MHz,目标SCK=3MHz。 // 计算:SCR = (PCLK / (CPSDVSR * BitClock)) - 1 = (12e6/(2*3e6))-1 = 1 SSPCR0 = (0x07 << 0) // DSS: 8位数据 (0x07 = 二进制0111) | (0x00 << 4) // FRF: SPI模式 | (0x00 << 6) // CPOL: 0 | (0x00 << 7) // CPHA: 0 (Mode 0) | (1 << 8); // SCR: 1 // 4. 配置控制寄存器1 (主从模式、是否使能) SSPCR1 = (0 << 2) // MS: 0=主机模式 | (0 << 3); // SOD: 0=从机输出不禁用(主机模式下此位无关) // 5. (可选)配置中断 SSPIMSC = (1 << 2); // 使能接收FIFO半满中断(RXIM) // 然后在NVIC中使能SSP中断 // 6. 最后,使能SSP模块 SSPCR1 |= (1 << 1); // SSE=1, 使能SSP
  4. 步骤四:编写数据收发函数

    • 查询方式:轮询SSPSR中的TNF(发送FIFO非满)和RNE(接收FIFO非空)标志位。
    • 中断方式:在中断服务程序中批量处理FIFO数据。

6.2 常见问题排查清单

当SPI通信失败时,可以按照以下清单逐项排查:

问题现象可能原因排查方法
完全无通信,SCK无波形1. 模块未使能 (PCONP寄存器)
2. 引脚功能未配置 (PINSELx寄存器)
3. SSP/SPI未使能 (SSESPCR位)
1. 检查PCONP对应位是否为1。
2. 用万用表或示波器检查引脚电压,或用GPIO功能测试引脚是否可控。
3. 确认配置流程最后使能了模块。
SCK有波形,但数据不对或无数据1.CPOL/CPHA模式不匹配(最常见)
2. 数据帧长度(DSS)不匹配
3. 波特率过高
4. 片选(SSEL)信号问题
1.用示波器同时抓取SCK和MOSI/MISO波形,对照从设备数据手册的时序图,检查采样边沿是否正确。
2. 确认主从双方配置的数据位数相同。
3. 尝试大幅降低波特率(增大分频系数)测试。
4. 检查SSEL信号是否在传输期间有效(低电平),时序是否符合要求(尤其是CPHA=0时的连续传输)。
只能发送/接收第一个字节,后续失败1. 传输完成标志未正确处理(查询方式)
2. FIFO溢出或下溢(中断方式)
3. CPHA=0模式下连续传输未正确处理SSEL
1. 在查询发送时,确保等待TNFBSY标志;在查询接收时,确保等待RNE标志。
2. 检查中断服务程序是否及时读取接收FIFO或填充发送FIFO。
3.对于CPHA=0,尝试在每帧之间拉高再拉低SSEL(或插入延时)
通信不稳定,偶尔出错1. 信号完整性问题(波特率过高、走线过长)
2. 电源噪声
3. 中断服务程序处理太慢,导致FIFO溢出
1. 降低波特率;检查PCB布线,SCK和数据线尽量短且平行,远离干扰源;可在信号线上串联小电阻(如22Ω-100Ω)。
2. 检查电源滤波,MCU和从设备电源加退耦电容。
3. 优化中断服务程序,或使用DMA(如果支持)。
从机模式不工作1. 从机模式未正确设置(MS=1)
2. 外部主机时钟(SCK)频率超出从机能力
3.SSPCPSR预分频值在从机模式下小于12
1. 确认MS位已置1,且SSE已使能。
2. 确认外部SCK频率满足从机要求(查LPC210x手册最大从机频率)。
3.确保在从机模式下,SSPCPSR >= 12

6.3 高级调试技巧:逻辑分析仪是你的最佳伙伴

对于SPI这种时序敏感的通信,一个哪怕是最基础的逻辑分析仪(配合Sigrok/PulseView等开源软件)也比单纯调试代码有效十倍。

  • 连接:将分析仪的通道连接到SCK、MOSI、MISO和SSEL线上。
  • 观察:设置正确的协议解码(SPI),并输入你配置的CPOL、CPHA参数。软件会自动将波形解析成十六进制或二进制数据。
  • 对比:将抓取到的波形与从设备数据手册中的时序图进行严格对比。重点关注:
    1. SCK空闲电平是否正确(CPOL)?
    2. 数据是在SCK的哪个边沿变化的?哪个边沿稳定的?(CPHA)
    3. SSEL信号的时序是否符合要求?
    4. 发送的数据内容是否正确?接收的数据是否与预期一致?

通过逻辑分析仪,你可以直观地看到“比特级”的通信过程,绝大多数配置错误和硬件问题都能无处遁形。这步投资对于嵌入式开发来说,回报率极高。

最后,关于SPI和SSP的选择,我的经验是:对于简单的、速率要求不高的点对点通信,SPI0足够用,代码更简洁。如果需要连接多种协议的设备、进行高速大数据量传输、或者希望利用FIFO和中断降低CPU负载,那么SSP是不二之选。理解寄存器每一位的含义,结合示波器/逻辑分析仪进行验证,你就能让LPC210x的SPI接口稳定可靠地工作起来。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询