3、TC3xx SPI模块架构:解析内部结构
好,咱们今天来聊聊TC3xx的SPI模块内部长什么样。说实话,我第一次看这个模块的框图时,也觉得有点眼花。但别怕,拆开来看,其实就几个核心部件。
3.1 整体架构概览
TC3xx的SPI模块,官方叫法QSPI(Queued SPI)。为什么加个Q?因为它带了个队列缓冲区。我个人习惯叫它“带脑子”的SPI。
整个模块分成三大块:
- 控制逻辑单元:负责配置、中断、DMA触发
- 数据通路:FIFO、移位寄存器、波特率发生器
- 引脚控制:SCK、MOSI、MISO、CS的映射和极性
你想想看,这三块配合起来,才能完成一次SPI传输。缺一个都不行。
3.2 FIFO深度与配置
FIFO是SPI模块的“缓存池”。TC3xx的QSPI模块,每个通道都有独立的FIFO。我记得早期英飞凌的MCU,FIFO深度只有4级。到了TC3xx,直接翻倍到8级。
| 参数 | TC2xx | TC3xx |
|---|---|---|
| 发送FIFO深度 | 4 | 8 |
| 接收FIFO深度 | 4 | 8 |
| 数据宽度 | 8/16位 | 8/16/32位 |
为什么要加大FIFO?说白了,就是为了减少CPU干预。你一次把8个字节丢进FIFO,模块自己慢慢发,CPU可以干别的活。我在项目中遇到过,用4级FIFO时,高速传输经常丢数据。换成8级后,稳得很。
关键点:FIFO深度不是越大越好。8级是TC3xx的硬件上限,你配置时别超过这个数。
3.3 控制寄存器详解
控制寄存器是SPI模块的“方向盘”。TC3xx的QSPI有以下几个核心控制寄存器:
- CON(控制寄存器):主从模式、波特率、时钟极性/相位
- ECON(扩展控制寄存器):数据宽度、CS控制、循环模式
- GLOBALCON(全局控制寄存器):模块使能、DMA使能、中断使能
嗯,这里要注意。ECON寄存器是TC3xx新增的。老工程师可能习惯只配CON,但如果你要用32位数据宽度,必须配ECON。
我的习惯:每次初始化SPI,我都会先清空所有控制寄存器,再逐个配置。避免上电残留值搞事情。
3.4 状态寄存器与中断
状态寄存器告诉你SPI模块“现在在干嘛”。常用的状态位有:
- BUSY:模块正在传输
- TXFIFO_EMPTY:发送FIFO空了
- RXFIFO_FULL:接收FIFO满了
- ERROR:传输错误(溢出、帧错误等)
我曾经踩过一个坑。读状态寄存器时,没注意BUSY位就写数据。结果数据没发出去,程序还卡死了。后来我加了个while循环等BUSY变低,问题解决。
// 等待SPI空闲
while (QSPI0->STATUS.B.BUSY) {
// 超时处理,防止死等
if (timeout-- == 0) {
break;
}
}
// 写数据到FIFO
QSPI0->TXFIFO.U = data;
警告:千万不要在BUSY位为1时写TXFIFO。数据会丢失,而且可能触发溢出错误。
3.5 波特率发生器
波特率发生器决定了SPI的传输速度。TC3xx的波特率计算公式很简单:
SPI时钟 = 模块时钟 / (2 * (BR + 1))
其中BR是波特率分频值,范围0~255。举个例子:模块时钟100MHz,BR设为49,那么SPI时钟就是1MHz。
我个人习惯,低速外设(比如温度传感器)用1MHz以下。高速外设(比如LCD屏)可以跑到10MHz以上。但要注意,TC3xx的SPI最高支持50MHz,别超了。
3.6 引脚映射与CS控制
TC3xx的SPI引脚可以映射到多个GPIO口。每个QSPI模块有4个CS引脚,支持多从机。
| 引脚 | 功能 | 可选映射 |
|---|---|---|
| SCK | 时钟 | P10.0, P11.0, P12.0 |
| MOSI | 主出从入 | P10.1, P11.1, P12.1 |
| MISO | 主入从出 | P10.2, P11.2, P12.2 |
| CS0~CS3 | 片选 | P10.3~P10.6等 |
为什么要有多个映射?说白了,就是为了PCB布线方便。你想想看,如果所有SPI引脚都挤在一个端口,布线得多痛苦。
避坑指南:我曾经把CS引脚映射到不支持输出的GPIO上,结果片选死活拉不低。后来查手册才发现,那个GPIO只能输入。所以,配引脚前一定看下数据手册的GPIO功能表。
3.7 小结
TC3xx的SPI模块,核心就是FIFO、控制寄存器、状态寄存器这三板斧。FIFO管数据缓存,控制寄存器管配置,状态寄存器管监控。把这三点吃透了,SPI驱动开发就成功了一半。
下一章,咱们聊聊SPI的初始化流程和实际代码怎么写。到时候我会拿一个实际项目中的例子,手把手带你配一遍。