详解TI DSP McBSP时钟停止模式下的SPI协议配置与实战
1. McBSP时钟停止模式下的SPI协议配置与应用详解
在嵌入式系统开发中,尤其是基于德州仪器(TI)TMS320F2837xD这类高性能DSP的工控、电机驱动或数字电源应用里,与外设的通信是基本功。SPI(Serial Peripheral Interface)协议因其简单、高速、全双工的特性,成为了连接Flash、ADC、DAC、传感器和显示屏的首选。但很多工程师在初次接触TI DSP的McBSP(多通道缓冲串行端口)模块,并试图将其配置为SPI接口时,往往会感到困惑——手册里寄存器位一大堆,时序图看起来复杂,稍有不慎通信就失败了。我自己在早期的项目中也踩过不少坑,比如时钟相位配反导致数据错位,或者帧同步信号配置不当造成通信断续。
实际上,McBSP是一个功能极为强大的串行通信外设,其设计初衷是为了兼容多种工业标准协议,如SPI、I2S、AC97等。它的“时钟停止模式”(Clock Stop Mode)正是为了无缝对接标准SPI协议而设计的硬件状态机。理解了这个模式的运作机制,你就能像使用普通SPI外设一样驾驭McBSP,同时还能利用其缓冲深度和DMA支持来提升系统效率。本文将结合TMS320F2837xD的参考手册,深入拆解如何将McBSP配置为SPI主设备或从设备,重点剖析时钟停止模式的四种时序变体,并分享从寄存器配置到代码实现的完整实操经验与避坑指南。
2. SPI协议核心与McBSP的硬件映射
2.1 SPI协议的精髓:主从、时钟与数据流
SPI协议的本质是一种同步、全双工、主从式的串行通信接口。它的硬件连接通常包含四根线:
- SPICLK (SCK): 串行时钟,由主设备产生,是所有数据交换的节拍器。
- SPISIMO (MOSI): 主设备输出、从设备输入数据线。
- SPISOMI (MISO): 主设备输入、从设备输出数据线。
- SPISTE (CS/SS): 从设备使能信号(通常低电平有效),由主设备控制,用于选择目标从设备。
通信完全由主设备发起并控制时钟。数据在时钟边沿进行采样和移位,具体在哪个边沿采样(上升沿或下降沿),以及时钟的稳态电平(空闲时为高或低),构成了SPI的四种模式(CPOL与CPHA的组合)。这是所有SPI通信的基石,也是后续配置McBSP时所有决策的出发点。
2.2 McBSP如何“变身”为SPI接口
McBSP本身是一个通用的同步串行端口,拥有独立的发送时钟(CLKX)、接收时钟(CLKR)、发送帧同步(FSX)和接收帧同步(FSR)等信号。为了模拟SPI协议,需要进行关键的信号映射和模式使能:
信号映射:
- CLKX引脚映射为 SPI 的SPICLK。
- FSX引脚映射为 SPI 的SPISTE(从设备片选)。
- DX引脚映射为SPISIMO(当McBSP为主设备)或SPISOMI(当McBSP为从设备)。
- DR引脚映射为SPISOMI(当McBSP为主设备)或SPISIMO(当McBSP为从设备)。
内部连接:在时钟停止模式下,McBSP内部会将接收时钟(MCLKR)和接收帧同步(FSR)分别与发送时钟(CLKX)和发送帧同步(FSX)连接起来。这意味着,对于SPI操作,你只需要关心CLKX和FSX这两个信号,CLKR和FSR在硬件层面被内部接管了,这简化了外部电路连接和软件配置。
核心使能:这一切功能切换的“总开关”,就是时钟停止模式。通过设置SPCR1寄存器中的CLKSTP位域,可以启用该模式,并选择具体的时钟行为。
注意:这种硬件层面的映射和内部连接,是McBSP高效支持SPI的关键。它并非软件模拟,而是硬件状态机直接按照SPI的时序工作,因此能获得更高的通信可靠性和更低的CPU开销。
2.3 时钟停止模式下的关键约束
一旦启用时钟停止模式,McBSP的某些配置就被固定下来,必须遵循,否则SPI通信无法正常工作:
- 单相位帧:必须配置为单相位帧(XPHASE = 0, RPHASE = 0)。SPI协议本质上是一次传输一帧数据,帧内只有一个“相位”或数据段。
- 单字帧长:每帧的长度必须设置为1个串行字(XFRLEN1 = 0, RFRLEN1 = 0)。这对应SPI每次传输一个数据包(8位、16位等)。即使你需要连续发送多个数据,在SPI模式下也是由多个独立的“单字帧”传输完成的。
- 收发字长一致:发送字长(XWDLEN1)和接收字长(RWDLEN1)必须设置为相同的值。因为SPI是全双工,收发同时进行,且共享同一个时钟,字长必须对齐。
3. 时钟停止模式的四种时序配置详解
这是配置中最容易出错,也最需要理解透彻的部分。SPI的四种模式(CPOL, CPHA)与McBSP的CLKSTP、CLKXP、CLKRP三个寄存器位的组合一一对应。
3.1 配置位与SPI模式的对应关系
首先,我们要建立寄存器位与SPI标准参数的心理映射:
- CLKXP (Clock Polarity): 控制CLKX引脚上的时钟极性。
CLKXP = 0: CLKX空闲时为低电平(对应CPOL=0)。CLKXP = 1: CLKX空闲时为高电平(对应CPOL=1)。
- CLKRP (Clock Receive Polarity): 控制接收数据采样的时钟边沿相对于MCLKR引脚的极性。这一点需要特别注意,由于内部连接(MCLKR连到CLKX),它实际决定了采样边沿相对于CLKX的关系。
CLKRP = 0: 在MCLKR的下降沿采样数据(对于CLKX,当CLKXP=0时,下降沿对应上升沿;需要结合CLKXP看)。CLKRP = 1: 在MCLKR的上升沿采样数据。
- CLKSTP (Clock Stop): 启用时钟停止模式并选择延迟。
CLKSTP = 10b: 无延迟模式。CLKSTP = 11b: 有延迟模式(半个时钟周期的延迟)。
它们组合起来,定义了四种标准的SPI模式:
| SPI 模式 | CPOL | CPHA | 对应 McBSP 配置 (CLKSTP, CLKXP, CLKRP) | 描述 |
|---|---|---|---|---|
| Mode 0 | 0 | 0 | (10b, 0, 0) | 时钟空闲低,数据在时钟第一个边沿(上升沿)采样。 |
| Mode 1 | 0 | 1 | (11b, 0, 1) | 时钟空闲低,数据在时钟第二个边沿(下降沿)采样。 |
| Mode 2 | 1 | 0 | (10b, 1, 0) | 时钟空闲高,数据在时钟第一个边沿(下降沿)采样。 |
| Mode 3 | 1 | 1 | (11b, 1, 1) | 时钟空闲高,数据在时钟第二个边沿(上升沿)采样。 |
3.2 时序图深度解析与“延迟”的含义
手册中的四张时序图(对应四种配置)是理解的钥匙。我们以最常用的Mode 0 (CLKSTP=10b, CLKXP=0, CLKRP=0)为例进行拆解:
- FSX/SPISTE: 作为片选信号,在整个数据包传输期间保持有效(低电平)。传输结束后回到无效状态(高电平)。即使连续传输多个数据包,FSX也会在每个包之间跳变,这会导致包间至少有2个位周期的空闲时间,这是McBSP SPI模式的一个特点,在规划高速连续传输时需要考量。
- CLKX/SPICLK: 当FSX有效后,时钟开始产生。由于
CLKXP=0,时钟初始为低。在无延迟模式(CLKSTP=10b)下,第一个时钟边沿(上升沿)立即开始。 - 数据采样与驱动:
- 主设备发送(SIMO): 数据在时钟边沿被从设备采样。对于Mode 0,是在上升沿采样。因此,主设备必须在时钟上升沿之前就准备好稳定的数据。McBSP在作为主设备时,会在时钟上升沿驱动数据到DX引脚。
- 从设备发送(SOMI): 从设备同样在时钟上升沿驱动其输出数据到SOMI线,主设备在时钟下降沿(或根据配置)采样该数据。但注意,对于
CLKRP=0的配置,接收数据是在MCLKR的下降沿采样。由于内部连接,MCLKR就是CLKX。所以,对于Mode 0,主设备是在CLKX的下降沿采样从设备发来的数据。
“延迟”模式 (CLKSTP=11b) 的作用:它引入了半个时钟周期的延迟。在时序图上表现为,第一个数据位(B0)在FSX有效后,要等待半个时钟周期,才会出现在第一个有效的时钟边沿上。这对应了SPI的CPHA=1模式,即数据在时钟的第二个边沿采样。这种模式为从设备提供了更多的数据建立时间,兼容性更好。
实操心得:绝大多数SPI从设备(如Flash、ADC)都支持Mode 0和Mode 3。在不确定从设备模式时,优先尝试Mode 0。配置时,务必根据从设备数据手册的时序图,确定其CPOL和CPHA,然后对照上表设置McBSP的三个关键位。一个常见的错误是混淆了CLKRP的含义,误以为它直接对应CPHA。记住,CLKSTP位决定了是否有“半个周期延迟”,它和CLKXP、CLKRP共同决定了最终的SPI模式。
4. McBSP配置为SPI主设备的完整流程
将McBSP配置为SPI主设备,意味着由DSP来生成时钟(SPICLK)和片选信号(SPISTE)。以下是基于手册流程的详细步骤和代码级解析。
4.1 配置步骤与寄存器详解
复位收发器和采样率发生器这是任何外设配置的安全起点,确保模块处于已知状态。
// 假设使用McBSP-A (McbspaRegs) McbspaRegs.SPCR2.bit.XRST = 0; // 复位发送器 McbspaRegs.SPCR1.bit.RRST = 0; // 复位接收器 McbspaRegs.SPCR2.bit.GRST = 0; // 复位采样率发生器 DELAY_US(10); // 短暂延时,确保复位稳定编程SPI相关寄存器这是核心配置阶段,需要仔细设置多个寄存器。我们以配置为SPI Mode 0 主设备,8位数据,内部产生时钟和帧同步为例。
// 1. 引脚功能复用配置 (以GPIO28/29/30/31为例,具体查芯片手册) // GPIO28 -> MDXA (SPISIMO), GPIO29 -> MDRA (SPISOMI) // GPIO30 -> MCLKXA (SPICLK), GPIO31 -> MFSXA (SPISTE) GpioCtrlRegs.GPBMUX2.bit.GPIO28 = 1; // 配置为McBSP-A DX GpioCtrlRegs.GPBMUX2.bit.GPIO29 = 1; // 配置为McBSP-A DR GpioCtrlRegs.GPBMUX2.bit.GPIO30 = 1; // 配置为McBSP-A CLKX GpioCtrlRegs.GPBMUX2.bit.GPIO31 = 1; // 配置为McBSP-A FSX // 2. 配置引脚控制寄存器(PCR) McbspaRegs.PCR.bit.CLKXM = 1; // CLKX 由内部采样率发生器驱动(输出,主模式) McbspaRegs.PCR.bit.FSXM = 1; // FSX 由内部产生(输出,主模式) McbspaRegs.PCR.bit.FSXP = 1; // FSX 低电平有效(SPI片选常用) McbspaRegs.PCR.bit.CLKXP = 0; // 时钟极性:空闲低 (CPOL=0) McbspaRegs.PCR.bit.CLKRP = 0; // 接收时钟极性:下降沿采样(与CLKXP=0组合为Mode 0) // 3. 配置发送控制寄存器(XCR)和接收控制寄存器(RCR) McbspaRegs.XCR2.bit.XPHASE = 0; // 单相位帧(SPI必须) McbspaRegs.RCR2.bit.RPHASE = 0; // 单相位帧(SPI必须) McbspaRegs.XCR1.bit.XFRLEN1 = 0; // 发送帧长:1个字 McbspaRegs.RCR1.bit.RFRLEN1 = 0; // 接收帧长:1个字 McbspaRegs.XCR1.bit.XWDLEN1 = 0b000; // 发送字长:8位 (000=8bit, 010=16bit) McbspaRegs.RCR1.bit.RWDLEN1 = 0b000; // 接收字长:8位,必须与发送字长相同 // 4. 配置数据延迟 (Critical!) McbspaRegs.XCR2.bit.XDATDLY = 0b01; // 发送数据延迟1位 (SPI主模式必须为01) McbspaRegs.RCR2.bit.RDATDLY = 0b01; // 接收数据延迟1位 (SPI主模式必须为01) // 5. 启用时钟停止模式 McbspaRegs.SPCR1.bit.CLKSTP = 0b10; // 使能时钟停止模式,无延迟 (对应Mode 0) // 6. 配置采样率发生器(SRGR) - 决定SPI时钟频率 McbspaRegs.SRGR2.bit.CLKSM = 1; // 时钟源选择:CPU时钟 McbspaRegs.SRGR1.bit.CLKGDV = 49; // 时钟分频值。SPI时钟频率 = CPU时钟 / (CLKGDV + 1) // 例如,CPU时钟150MHz,CLKGDV=49,则SPICLK = 150MHz / 50 = 3MHz McbspaRegs.SPCR2.bit.FRST = 1; // 使能帧同步生成(对于SPI主模式,通常需要) McbspaRegs.SPCR2.bit.FSGM = 0; // FSX由DXR->XSR拷贝触发(SPI典型配置)使能采样率发生器在配置好所有参数后,释放采样率发生器的复位。
McbspaRegs.SPCR2.bit.GRST = 1; // 使能采样率发生器 DELAY_US(10); // 等待至少两个CLKG周期稳定,通常用几个微秒延时即可使能发送器和接收器最后,释放收发器的复位,模块开始工作。
McbspaRegs.SPCR2.bit.XRST = 1; // 使能发送器 McbspaRegs.SPCR1.bit.RRST = 1; // 使能接收器 DELAY_US(10); // 等待逻辑稳定
4.2 主设备配置的关键要点与陷阱
- 时钟频率计算:SPI时钟
SPICLK = CPUCLK / (CLKGDV + 1)。CLKGDV是8位寄存器,范围1-255。确保计算出的时钟频率不超过从设备支持的最大SCK频率。 - 数据延迟(X/RDATDLY)必须为1:这是硬性规定。
XDATDLY=01b确保了FSX信号(片选)在数据位开始前一个时钟周期就变为有效,满足了SPI从设备对片选建立时间的要求。设置为0或2在时钟停止模式下是未定义的。 - FSGM位的作用:在SPI主模式下,通常设置
FSGM=0,这样每次向DXR写入数据并启动传输时,FSX引脚会自动产生一个有效的帧同步脉冲(即片选信号)。这非常符合SPI的操作习惯。 - 连续传输的间隙:如前所述,即使你连续写入多个数据,McBSP也会在每个字传输结束后将FSX拉高,导致包间至少有2个位周期的空闲。如果从设备要求片选在连续传输期间保持有效,你需要使用GPIO手动控制一个片选引脚,而不是使用McBSP的FSX功能。
5. McBSP配置为SPI从设备的完整流程
当DSP作为从设备时,时钟(SPICLK)和片选(SPISTE)由外部主设备提供。配置上有几个关键区别。
5.1 从设备配置的差异点
时钟和帧同步源设置为输入:
McbspaRegs.PCR.bit.CLKXM = 0; // CLKX 配置为输入(由外部主设备驱动) McbspaRegs.PCR.bit.FSXM = 0; // FSX 配置为输入(由外部主设备驱动) McbspaRegs.PCR.bit.FSXP = 1; // 假设外部片选低有效 // CLKXP和CLKRP根据主设备的SPI模式设置,必须与主设备匹配!数据延迟必须为0:
McbspaRegs.XCR2.bit.XDATDLY = 0b00; // SPI从模式必须为00 McbspaRegs.RCR2.bit.RDATDLY = 0b00; // SPI从模式必须为00采样率发生器仍需使能:即使时钟来自外部,采样率发生器也必须被使能以同步内部逻辑。其分频值通常设置为1(
CLKGDV = 1),使其运行在最高速率(CPU时钟/2),以便可靠地捕捉外部异步信号。McbspaRegs.SRGR1.bit.CLKGDV = 1; // 分频值设为1 McbspaRegs.SPCR2.bit.GRST = 1; // 使能采样率发生器FSX(片选)信号行为:与一些简单的SPI从设备不同,McBSP要求FSX信号在每次数据传输前都必须有一个有效的边沿跳变。它不能一直被拉低。这意味着外部主设备必须在每个数据包传输前都操作一次片选信号。
5.2 从设备数据收发流程
作为从设备,数据的收发完全由外部主设备的时钟和片选控制。
- 发送数据:在外部主设备发起传输(拉低FSX并产生时钟)之前,你需要将待发送的数据写入发送数据寄存器
DXR。当��设备时钟到来时,McBSP会自动将数据从DXR移位到XSR,并通过DX引脚(此时作为SOMI)发送出去。 - 接收数据:当主设备时钟到来时,数据通过DR引脚(此时作为SIMO)移入接收移位寄存器
RSR,当一个完整的字接收完成后,数据会被拷贝到接收缓冲寄存器RBR,然后最终到达数据接收寄存器DRR,并可能产生接收中断(RINT)或DMA事件。 - 关键代码片段:
// 1. 等待发送寄存器就绪(或使用中断/DMA) while(McbspaRegs.SPCR2.bit.XRDY != 1); // 等待XRDY标志 // 2. 写入要发送的数据 McbspaRegs.DXR1.all = data_to_send; // 接收端通常使用中断或DMA // 在中断服务程序或DMA完成回调中读取数据 received_data = McbspaRegs.DRR1.all;
6. 常见问题排查与实战经验
即使按照手册配置,在实际调试中也可能遇到问题。以下是一些常见故障现象和排查思路。
6.1 通信完全无反应
- 检查引脚复用:这是最容易被忽略的一步。确认GPIO MUX寄存器已正确配置为McBSP功能,而非普通的GPIO输入/输出。
- 检查电源和时钟:确认DSP内核和外设时钟已使能。检查
PCLKCR寄存器中对应McBSP的时钟使能位。 - 确认复位状态:确保配置流程正确。必须在模块和采样率发生器复位(
XRST=RRST=GRST=0)的情况下进行寄存器配置,然后先释放GRST,再释放XRST和RRST。顺序错误可能导致模块行为异常。 - 测量物理信号:使用示波器或逻辑分析仪测量CLKX、FSX、DX、DR引脚。这是最直接的诊断方法。
- 如果配置为主设备,上电初始化后,向DXR写一个数据,应该能看到FSX和CLKX上有脉冲。
- 如果配置为从设备,用主设备发起一次通信,看DSP的CLKX和FSX引脚是否有信号输入。
6.2 数据错位或采样错误
- 首要怀疑:SPI模式不匹配:这是最常见的原因。用示波器同时抓取主从设备的CLK和MOSI信号,对照数据手册,检查时钟极性(CPOL)和相位(CPHA)是否完全一致。重点检查McBSP的
CLKSTP、CLKXP、CLKRP三位组合。 - 检查数据延迟
XDATDLY/RDATDLY:- 主模式必须为
01b。 - 从模式必须为
00b。 这个配置错误会导致数据相对于时钟边沿的位置不对,造成采样错一位。
- 主模式必须为
- 检查字长
XWDLEN1/RWDLEN1:确保发送和接收字长设置相同,且与实际传输的数据位数匹配。如果设置为16位(010b),但你只发送了8位数据,可能会读到错误数据。
6.3 只能发送一次或无法连续传输
- FSX(片选)行为:回忆McBSP的特性——即使在连续传输下,FSX也会在每个字传输结束后无效。如果你的从设备要求片选在连续传输期间保持有效,此行为会导致通信失败。解决方案:放弃使用McBSP的FSX引脚作为片选,改用另一个GPIO手动控制片选信号。配置McBSP时,设置
FSXM=0并将FSX引脚拉高或悬空(或复用为其他功能),在软件流程中,在传输序列开始前拉低GPIO片选,序列结束后拉高。 - DXR覆盖问题:在发送过程中,如果过早地向
DXR写入下一个数据,可能会破坏正在进行的移位操作。可靠的做法是等待XRDY标志置位(表示DXR已空,可以写入新数据)后再写入。对于高速连续传输,强烈建议使用DMA。
6.4 使用DMA提升效率
对于大数据量传输,使用DMA服务McBSP是标准做法。配置流程需要额外注意顺序:
- 先完成McBSP的基本配置(到使能采样率发生器
GRST=1之前)。 - 配置DMA控制器,设置源/目标地址为McBSP的数据寄存器
DRR/DXR,配置传输计数和触发源(McBSP的接收/发送事件)。 - 先使能DMA通道,然后再使能McBSP的发送器和接收器(
XRST=1,RRST=1)。这个顺序很重要,可以避免使能McBSP后数据立即开始传输而DMA还未准备好的情况。 - 如果需要,最后使能帧同步生成(
FRST=1)。
6.5 调试技巧:数字回环模式
McBSP提供了一个强大的内置调试功能——数字回环模式(Digital Loopback Mode)。通过设置SPCR1.bit.DLB = 1,模块内部会将发送端(DX, FSX, CLKX)直接连接到接收端(DR, FSR, CLKR)。这样,你发送出去的数据会被自己立刻接收回来。
这个功能有什么用?
- 验证配置:在不连接外部设备的情况下,快速验证McBSP的SPI配置、时钟、数据延迟等是否正确。如果你能自发自收成功,说明McBSP本身的配置基本无误。
- 隔离硬件问题:如果自发自收正常,但连接外部设备失败,问题很可能出在外部电路、电平转换或从设备配置上。
- 测试DMA和中断:可以用于测试数据流和中断/DMA服务程序是否正常工作。
使用回环模式时,只需像正常主模式一样配置和操作McBSP即可,数据会内部环回。调试完成后,别忘了将DLB位清零。
配置McBSP的SPI模式,尤其是深入理解时钟停止模式下的四种时序,是掌握TMS320F2837xD系列DSP高级通信功能的重要一环。它不再是简单的“配个寄存器就能用”,而是需要你清晰地理解SPI协议的精髓,并知道McBSP的硬件状态机如何通过CLKSTP、CLKXP、CLKRP这三个关键位来模拟这些时序。从复位序列到数据延迟,从主从模式差异到DMA集成,每一个细节都关乎通信的成败。我个人的经验是,在项目初期,务必用逻辑分析仪抓取时序,将实测波形与数据手册的时序图以及从设备的要求进行严格比对,这是排除配置问题最快最准的方法。一旦打通,这套基于McBSP的SPI方案凭借其硬件加速和DMA支持,能为你的嵌入式系统提供非常稳定高效的数据通道。