系统级与 GPIO 引脚初始化

  • 系统时钟配置:调用 InitSysCtrl() 初始化 DSP 的系统时钟(如 PLL 配置),这决定了后续 McBSP 内部低速外设时钟(LSPCLK)的基准频率。

    • DisableDog();
    • InitPll(DSP28_PLLCR,DSP28_DIVSEL); // DSP2833x_Examples.h
    • InitPeripheralClocks();
  • GPIO 复用配置:调用 InitMcbspGpio(),将 DSP 的通用 GPIO 引脚复用为 McBSP 专用引脚(如 MDX、MDR、CLKX、FSX 等),并配置相应的上拉电阻和异步输入模式。

        void InitMcbspaGpio(void)
        {
        EALLOW;

          /* Configure McBSP-A pins using GPIO regs*/
          //
          GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 2; // GPIO20 is MDXA pin
          GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 2; // GPIO21 is MDRA pin
          GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 2; // GPIO22 is MCLKXA pin
          GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 2; // GPIO7 is MCLKRA pin (Comment as needed) 二选一 // GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 1; // GPIO58 is MCLKRA pin (Comment as needed)
          GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 2; // GPIO23 is MFSXA pin
          GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 2; // GPIO5 is MFSRA pin (Comment as needed) // GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 1; // GPIO59 is MFSRA pin (Comment as needed)

          /* Enable internal pull-up for the selected pins */
          // 不禁止(即开启)内部上拉电阻。开启上拉可以防止引脚在空闲或悬空状态下因外部干扰产生误触发,提高通信的稳定性

          GpioCtrlRegs.GPAPUD.bit.GPIO20 = 0;     // Enable pull-up on GPIO20 (MDXA)
          GpioCtrlRegs.GPAPUD.bit.GPIO21 = 0;     // Enable pull-up on GPIO21 (MDRA)
          GpioCtrlRegs.GPAPUD.bit.GPIO22 = 0;     // Enable pull-up on GPIO22 (MCLKXA)
          GpioCtrlRegs.GPAPUD.bit.GPIO7 = 0;      // Enable pull-up on GPIO7 (MCLKRA) (Comment as needed)
          // GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0;   // Enable pull-up on GPIO58 (MCLKRA) (Comment as needed)
          GpioCtrlRegs.GPAPUD.bit.GPIO23 = 0;     // Enable pull-up on GPIO23 (MFSXA)
          GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0;      // Enable pull-up on GPIO5 (MFSRA) (Comment as needed)
          // GpioCtrlRegs.GPBPUD.bit.GPIO59 = 0;   // Enable pull-up on GPIO59 (MFSRA) (Comment as needed)

          /* Set qualification for selected input pins to asynch only */
          // 配置 McBSP-A 模块相关输入引脚的“输入限定模式”(Input Qualification Mode)。
          // 在 C2000 DSP 中,为了防止外部引脚上的高频噪声引起误触发,GPIO 默认开启了一个“采样窗口滤波”(即与系统时钟同步并进行 3 次或 6 次采样)。但是,对于 McBSP 这种高速串行通信接口,这种滤波机制是致命的,因此必须将其配置为异步直通模式(Asynch only)。
          // 只要是被 McBSP 用作时钟或帧同步的输入引脚,都必须严格配置为 3(Asynch)

          GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 3;   // Asynch input GPIO21 (MDRA)
          GpioCtrlRegs.GPAQSEL2.bit.GPIO22 = 3;   // Asynch input GPIO22 (MCLKXA)
          GpioCtrlRegs.GPAQSEL1.bit.GPIO7 = 3;    // Asynch input GPIO7 (MCLKRA) (Comment as needed)
          //GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3; // Asynch input GPIO58(MCLKRA) (Comment as needed)
          GpioCtrlRegs.GPAQSEL2.bit.GPIO23 = 3;   // Asynch input GPIO23 (MFSXA)
          GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 3;    // Asynch input GPIO5 (MFSRA) (Comment as needed)
          //GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 3; // Asynch input GPIO59 (MFSRA) (Comment as needed)

        EDIS;
        }
  • 在修改GPIO控制寄存器之前,必须先执行 EALLOW; 指令来解除寄存器的写保护,修改完成后再执行 EDIS; 恢复保护,否则写入操作将被 DSP 忽略。

  • 在 TI C2000 系列 DSP(如 TMS320F28335)中,GPAMUX2 的全称是 GPIO A Port Multiplexer 2 Register(GPIO A 组引脚复用选择寄存器 2)。

  • 在 C2000 架构中,GPIO A 组包含了 32 个引脚(GPIO0 ~ GPIO31)。因为一个 32 位寄存器无法为每个引脚分配足够的位来配置多种功能,所以它被拆分成了两个寄存器,GPAMUX1:控制 GPIO0 ~ GPIO15 的功能复用,GPAMUX2:控制 GPIO16 ~ GPIO31 的功能复用。

  • 【电路笔记 TMS320F28335DSP】DSP GPIO 寄存器 GpioCtrlRegs+GpioDataRegs

  • GPAMUX2 是一个 32 位的寄存器,每两个位(Bits)控制一个 GPIO 引脚的功能选择。每个引脚有 4 种状态可选,00:配置为通用数字 I/O(普通 GPIO,由 GPADIR 决定输入还是输出)。01:复用为外设功能 1(例如 SCI-A 串口、ePWM 等)。10:复用为外设功能 2(例如 McBSP-A、SPI 等)。11:复用为外设功能 3(例如 CAN、ADC 触发等)。

配置CPOL/CPHA

示例

McbspaRegs.PCR.bit.CLKXP = 1;     // 发送时钟极性
McbspaRegs.PCR.bit.CLKRP = 0;     // 接收时钟极性
McbspaRegs.SPCR1.bit.CLKSTP = 2;  // 使能时钟停止模式(无延迟)
  • 表现:时钟空闲时为低电平,数据在时钟的上升沿被锁存(采样),在下降沿数据发生跳变。

使能时钟停止模式

  • 以下是 McBSP 模块中 CLKSTP 配置值(0~3)对应的 SPI 时序模式对照表:
CLKSTP 二进制 模式说明 时钟行为
0 00b 禁用时钟停止模式 时钟连续运行,不兼容 SPI 协议(用于常规 McBSP 模式)
1 01b 禁用时钟停止模式 时钟连续运行,不兼容 SPI 协议
2 10b 使能时钟停止模式(无延迟) 每次数据传输开始时,时钟立即开启,数据采样从第一个时钟边沿开始
3 11b 使能时钟停止模式(有延迟) 每次数据传输开始时,时钟延迟半个周期后开启,数据采样从第二个时钟边沿开始
  • 开启 SPI 兼容的前提:只有当 CLKSTP 被配置为 23 时,McBSP 才会进入时钟停止模式,从而兼容 SPI 协议。
  • 配合其他寄存器使用CLKSTP 仅决定了时钟的启动时机(是否有延迟)。要完整配置 SPI 的四种工作模式(CPOL 和 CPHA),还需要配合引脚控制寄存器(PCR)中的 CLKXP(发送时钟极性)和 CLKRP(接收时钟极性)来共同决定。
  • 例二:没有配置 CLKSTP 时钟停止模式,仅单独设置了 PCR.bit.CLKXP=0x1。因为它是从机模式,不需要像 SPI 主机那样通过时钟停止模式来模拟 SPI 时序,而是直接由 FPGA 的时钟边沿来锁存数据。

CPOL 和 CPHA

  • CPOL (Clock Polarity,时钟极性)
    决定了 SPI 总线空闲时(没有数据传输时),时钟线(SCLK)的电平状态。

    • CPOL = 0:空闲时,SCLK 保持低电平
    • CPOL = 1:空闲时,SCLK 保持高电平
    • 没有数据传输时(SPISTE为高),SPICLK 引脚上确实是没有时钟脉冲(波形)的
  • CPHA (Clock Phase,时钟相位)
    决定了数据是在时钟的第几个边沿被采样(读取)。

    • CPHA = 0:在第一个边沿(奇数边沿)采样数据。
    • CPHA = 1:在第二个边沿(偶数边沿)采样数据。

在这里插入图片描述
在这里插入图片描述

  • 在 C2000 前提是 CLKSTP 已经设置为 2 或 3,开启了时钟停止模式:
SPI 模式 CPOL (时钟极性) CPHA (时钟相位) 空闲时时钟电平 数据采样边沿 McBSP 寄存器配置 (PCR 寄存器)
Mode 0 0 0 低电平 上升沿采样 CLKXP = 1, CLKRP = 0
Mode 1 0 1 低电平 下降沿采样 CLKXP = 0, CLKRP = 1
Mode 2 1 0 高电平 下降沿采样 CLKXP = 0, CLKRP = 1
Mode 3 1 1 高电平 上升沿采样 CLKXP = 1, CLKRP = 0
  • (注:CLKXPCLKRP 的值在 Mode 0/3 以及 Mode 1/2 中是分别相同的,真正的区别在于 CLKSTP 配合它们产生的内部时序差异。通常 CLKSTP=2 不带延迟,CLKSTP=3 带半个周期的延迟)*

CLKXP 和 CLKRP 与 SPI 四种模式(0~3)的对应关系

  • 需要结合 CLKSTP(时钟停止模式位)、CLKXP(发送时钟极性位)和 CLKRP(接收时钟极性位)这三个寄存器位来共同决定。
SPI 模式 CPOL (空闲电平) CPHA (采样边沿) CLKSTP 配置 CLKXP 配置 CLKRP 配置 时序特征说明
Mode 0 0 (低电平) 0 (第1个边沿) 2 (无延迟) 0 0 时钟空闲为低电平;发送在 CLKX 上升沿,接收在 CLKR 下降沿
Mode 1 0 (低电平) 1 (第2个边沿) 3 (有延迟) 0 1 时钟空闲为低电平;发送在 CLKX 下降沿,接收在 CLKR 上升沿
Mode 2 1 (高电平) 0 (第1个边沿) 2 (无延迟) 1 0 时钟空闲为高电平;发送在 CLKX 下降沿,接收在 CLKR 上升沿
Mode 3 1 (高电平) 1 (第2个边沿) 3 (有延迟) 1 1 时钟空闲为高电平;发送在 CLKX 上升沿,接收在 CLKR 下降沿
  • CLKXP 决定了发送数据时的时钟极性(即空闲时 CLKX 是高电平还是低电平),同时也决定了数据是在上升沿还是下降沿发送。
  • CLKRP 决定了接收数据时的时钟极性,即数据是在上升沿还是下降沿被采样。对于 TMS320F28335 等 C2000 系列 DSP,CLKRP 是主机端必须配置的关键参数。当 McBSP 被配置为 SPI 主机时,CLKRP 与 CLKXP 共同决定了 SPI 的时钟极性(CPOL)和相位(CPHA)。
  • CLKSTP = 2(无延迟)时,对应 SPI 协议中在第一个时钟边沿进行采样的模式(即 CPHA = 0,如 Mode 0 和 Mode 2)。
  • CLKSTP = 3(有半个周期延迟)时,对应 SPI 协议中在第二个时钟边沿进行采样的模式(即 CPHA = 1,如 Mode 1 和 Mode 3)。

模式配置

例一:McBSP 配置为 SPI 主机模式(Master)

  • 适用场景:DSP 作为主机,主动向外设(如 ARM、ADC 等)发送或接收数据。*
void InitMcbspaAsSpiMaster(void)
{
    // 1. 全局复位:将发送、接收、采样率发生器等全部复位
    McbspaRegs.SPCR2.all = 0x0000; 
    McbspaRegs.SPCR1.all = 0x0000; 
    
    // 2. 配置引脚与时钟极性 (PCR)
    McbspaRegs.PCR.all = 0x0F08;       // FSXM=FSRM=1, CLKXM=CLKRM=1 (DSP提供时钟和帧同步)
    McbspaRegs.PCR.bit.CLKXP = 1;      // CPOL=0, CPHA=0 (SPI Mode 0, 上升沿采样)
    McbspaRegs.PCR.bit.CLKRP = 0;      
    McbspaRegs.SPCR1.bit.CLKSTP = 2;   // 开启时钟停止模式(模拟 SPI 的关键)

    // 3. 配置数据帧格式 (RCR & XCR)
    McbspaRegs.RCR1.bit.RWDLEN1 = 2;   // 接收字长:16-bit
    McbspaRegs.XCR1.bit.XWDLEN1 = 2;   // 发送字长:16-bit
    McbspaRegs.RCR2.bit.RDATDLY = 1;   // SPI 主模式下,接收数据延迟设为 1
    McbspaRegs.XCR2.bit.XDATDLY = 1;   // SPI 主模式下,发送数据延迟设为 1

    // 4. 配置波特率与采样率 (SRGR)
    McbspaRegs.SRGR2.bit.CLKSM = 1;    // 时钟源:LSPCLK (内部低速外设时钟)
    McbspaRegs.SRGR1.bit.CLKGDV = 15;  // 分频系数:SPI时钟 = LSPCLK / (15+1)
    McbspaRegs.SRGR2.bit.FPER = 31;    // 帧同步脉冲周期 = 32 个 CLKG 周期
    McbspaRegs.SRGR1.bit.FWID = 0;     // 帧同步脉冲宽度 = 1 个 CLKG 周期

    // 5. 使能采样率发生器并延时等待稳定
    McbspaRegs.SPCR2.bit.GRST = 1;     
    delay_loop();                      // 【关键】等待至少 2 个 SRG 时钟周期

    // 6. 释放发送器、接收器与帧同步发生器
    McbspaRegs.SPCR2.bit.XRST = 1;     // 释放发送器
    McbspaRegs.SPCR1.bit.RRST = 1;     // 释放接收器
    McbspaRegs.SPCR2.bit.FRST = 1;     // 释放帧同步逻辑
}

例二:McBSP 配置为 SPI 从机模式(Slave)

void InitMcbspaAsSpiSlave(void)
{
    // 1. 全局复位:将发送、接收、采样率发生器等全部复位
    McbspaRegs.SPCR2.all = 0x0000; 
    McbspaRegs.SPCR1.all = 0x0000; 
    McbspaRegs.MFFINT.all = 0x0;   // 清除所有中断标志

    // 2. 配置引脚与时钟极性 (PCR)
    McbspaRegs.PCR.bit.CLKXP = 1;  // 根据外部主机的时序要求配置极性 (CPOL/CPHA)
    McbspaRegs.PCR.bit.CLKRP = 0;  // 根据外部主机的时序要求配置极性
    
    // FSX 由外部主机提供(对应 SPI 的 SS/CS 片选信号)
    McbspaRegs.PCR.bit.FSXM = 0;   // 0: 外部输入
    McbspaRegs.PCR.bit.FSRM = 0;   // 0: 外部输入
    McbspaRegs.PCR.bit.CLKXM = 0;  // 0: CLKX 由外部主机提供
    McbspaRegs.PCR.bit.CLKRM = 0;  // 0: CLKR 由外部主机提供
    
    // 开启时钟停止模式(模拟 SPI 的关键)
    // 2: 无延迟启动 (对应 CPHA=0);3: 有半个周期延迟 (对应 CPHA=1)
    McbspaRegs.SPCR1.bit.CLKSTP = 2; 

    // 3. 配置数据帧格式 (RCR & XCR)
    McbspaRegs.RCR1.bit.RWDLEN1 = 2; // 接收字长:16-bit
    McbspaRegs.XCR1.bit.XWDLEN1 = 2; // 发送字长:16-bit
    
    // 作为 SPI 从机,数据延迟通常设为 0
    McbspaRegs.RCR2.bit.RDATDLY = 0; // 接收数据无延迟
    McbspaRegs.XCR2.bit.XDATDLY = 0; // 发送数据无延迟

    // 4. 配置采样率发生器 (SRGR)
    // 注意:作为从机,采样率发生器通常不需要主动分频,但需保持基本配置
    McbspaRegs.SRGR2.bit.CLKSM = 0;  // 禁用内部时钟源
    McbspaRegs.SRGR1.bit.CLKGDV = 1; // 外部时钟分频设为 1
    McbspaRegs.SRGR2.bit.FPER = 31;  // 帧同步脉冲周期
    McbspaRegs.SRGR1.bit.FWID = 0;   // 帧同步脉冲宽度

    // 5. 使能采样率发生器并延时等待稳定
    McbspaRegs.SPCR2.bit.GRST = 1;     
    delay_loop();                      // 【关键】等待至少 2 个 SRG 时钟周期

    // 6. 释放发送器、接收器与帧同步发生器
    McbspaRegs.SPCR2.bit.XRST = 1;     // 释放发送器
    McbspaRegs.SPCR1.bit.RRST = 1;     // 释放接收器
    McbspaRegs.SPCR2.bit.FRST = 1;     // 释放帧同步逻辑

    // 7. 使能接收中断(从机被动接收的常用方式)
    McbspaRegs.MFFINT.bit.RINT = 1;    // 使能 McBSP 接收中断
}

CG

  • 如果数据量很大,应配合使用 DMA 或者 McBSP 的 FIFO 功能(如果芯片支持),以减轻 CPU 负担。当前关注寄存器配置,未深入讨论数据吞吐优化。

更多推荐