【电路笔记 TMS320F28335DSP】McBSP的主要配置流程(兼容SPI):GPIO 引脚初始化 + 配置CPOL/CPHA + SPI 四种模式
文章目录
系统级与 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被配置为2或3时,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 |
- (注:
CLKXP和CLKRP的值在 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 负担。当前关注寄存器配置,未深入讨论数据吞吐优化。
更多推荐
所有评论(0)