TMS320F28335 SPI实战:从寄存器配置到FIFO收发完整指南
在嵌入式开发中,SPI通信因其高速、全双工的特性成为外设连接的首选方案之一。但对于初次接触TMS320F28335的开发者来说,面对密密麻麻的寄存器手册和官方示例代码,往往感到无从下手。本文将从一个可立即运行的完整工程出发,手把手带你实现SPI的自发自收功能,并通过串口打印调试信息,同时穿插实际开发中的经验技巧。
1. 工程环境搭建与硬件准备
在开始SPI配置前,需要确保开发环境就绪。推荐使用CCS(Code Composer Studio)作为开发工具,版本建议v6以上以兼容C2000系列芯片。硬件方面,除TMS320F28335开发板外,还需准备:
- USB转串口模块(用于调试信息输出)
- 杜邦线若干
- 示波器(可选,用于信号观测)
开发环境配置要点:
# 安装C2000编译器套件 ti-cgt-c2000_18.12.5.LTS_win32.exe # 安装最新ControlSUITE库 controlSUITE_setup_3.4.9.exe注意:安装路径避免包含中文或空格,否则可能导致编译异常
2. SPI核心寄存器深度解析
TMS320F28335的SPI模块包含8个关键寄存器,每个寄存器位都有特定功能。不同于简单罗列寄存器定义,我们重点分析实际工程中最常配置的位域:
2.1 SPICCR(配置控制寄存器)
| 位域 | 名称 | 功能说明 | 典型值 |
|---|---|---|---|
| 15-8 | 保留 | 必须写0 | 0x00 |
| 7 | SPISWRESET | 软件复位 | 0-复位,1-运行 |
| 6 | CLKPOLARITY | 时钟极性 | 0-上升沿发送 |
| 5-4 | 保留 | 必须写0 | 0 |
| 3-0 | SPICHAR | 数据长度 | 0xF-16位 |
// 典型初始化序列 SpiaRegs.SPICCR.all = 0x000F; // 复位状态,16位数据 // ...其他配置 SpiaRegs.SPICCR.all |= 0x0080; // 释放复位2.2 SPIBRR(波特率设置)
波特率计算需考虑LSPCLK频率(默认37.5MHz):
- 当BRR=3~127时:波特率 = LSPCLK/(BRR+1)
- 当BRR=0~2时:波特率 = LSPCLK/4
常见问题:
- 实际波特率偏差大 ⇒ 检查LSPCLK分频配置
- 通信不稳定 ⇒ 降低波特率或检查时钟源
3. FIFO模式实战配置
启用FIFO可大幅提升数据传输效率,相关寄存器配置如下:
3.1 SPIFFTX(发送FIFO控制)
SpiaRegs.SPIFFTX.all = 0xE040; // 二进制分解:1110 0000 0100 0000 // 位15:FIFO使能 // 位14:FIFO复位清除 // 位13:发送FIFO复位 // 位8:发送中断标志清除3.2 SPIFFRX(接收FIFO控制)
SpiaRegs.SPIFFRX.all = 0x204F; // 二进制分解:0010 0000 0100 1111 // 位13:接收FIFO复位 // 位8:接收中断标志清除 // 位7-0:FIFO深度阈值提示:FIFO深度建议初始设置为16级,后续根据实际数据量调整
4. 完整工程代码剖析
工程包含三个关键文件:main.c(主循环)、spi.c(驱动实现)、spi.h(接口定义)。以下是核心实现:
4.1 SPI初始化函数
void SPIA_Init(void) { EALLOW; SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1; // 使能SPI时钟 EDIS; InitSpiaGpio(); // GPIO复用配置 // FIFO配置 SpiaRegs.SPIFFTX.all = 0xE040; SpiaRegs.SPIFFRX.all = 0x204F; SpiaRegs.SPIFFCT.all = 0x00; // 无传输延迟 // SPI基础配置 SpiaRegs.SPICCR.all = 0x000F; // 复位状态 SpiaRegs.SPICTL.all = 0x0006; // 主模式,使能发送 SpiaRegs.SPIBRR = 0x007F; // 波特率≈293kHz SpiaRegs.SPICCR.all = 0x009F; // 释放复位,16位数据 SpiaRegs.SPIPRI.bit.FREE = 1; // 自由运行模式 }4.2 数据收发函数
Uint16 SPIA_SendReciveData(Uint16 dat) { SpiaRegs.SPITXBUF = dat; // 写入发送缓冲区 // 等待接收完成 while(SpiaRegs.SPIFFRX.bit.RXFFST != 1); return SpiaRegs.SPIRXBUF; // 返回接收数据 }5. 调试技巧与性能优化
在实际开发中,以下几个技巧能显著提高开发效率:
示波器诊断法:
- 测量SPICLK信号 - 确认频率与预期一致
- 观察MOSI/MISO波形 - 验证数据对齐方式
- 检查CS信号(如使用) - 确保片选时序正确
常见问题排查表:
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 无数据收发 | SPI未使能 | 检查SPICCR.7位 |
| 接收数据全0 | 未启用自测模式 | 设置SPICCR.7=1 |
| 数据错位 | 相位配置错误 | 调整SPICTL.3位 |
| 波特率不符 | LSPCLK分频错误 | 检查PLL配置 |
性能优化建议:
- 启用DMA传输替代查询方式
- 合理设置FIFO阈值减少中断频率
- 使用硬件NSS信号(若外设支持)
6. 扩展应用:多设备SPI组网
当需要连接多个SPI设备时,可采用以下两种方案:
方案一:硬件CS控制
// GPIO初始化 GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 0; // 配置GPIO5为普通IO GpioCtrlRegs.GPADIR.bit.GPIO5 = 1; // 输出模式 // 设备选择函数 void select_device(int dev_id) { switch(dev_id) { case 1: GpioDataRegs.GPASET.bit.GPIO5 = 1; break; case 2: GpioDataRegs.GPACLEAR.bit.GPIO5 = 1; break; } DELAY_US(10); // 保持时间 }方案二:软件模拟SPI
- 优点:引脚分配灵活
- 缺点:速度受限
- 实现方式:通过GPIO模拟时钟和数据线时序
在实际项目中,SPI通信的稳定性往往取决于细节处理。例如,某次调试发现每第256个数据包会丢失,最终查明是FIFO计数器溢出导致。这类经验只能通过实际项目积累,这也是为什么建议开发者从完整工程入手,而非单纯研究寄存器手册。