S32K3 FLEXIO模拟UART与LCD显示驱动实战 - 第3节
3.1 FLEXIO 外设简介
FLEXIO(Flexible Input/Output)是 NXP S32K3 系列微控制器中一个高度可配置的、基于硬件的串行通信外设。它本质上是一个“可编程状态机”,允许开发者通过软件配置来模拟多种标准或自定义的串行协议,而无需占用内核 CPU 资源进行位拆裂(Bit-Banging)。
在 S32K3 平台上,FLEXIO 的主要定位是作为现有通信外设(如 LPUART、LPSPI、LPI2C)的补充或替代方案,尤其适用于需要灵活时序、多通道或非标准协议的场合。
3.1.1 主要特性
- 可编程状态机: 每个 FLEXIO 模块包含多个独立的 32 位移位器(Shifter)和定时器(Timer),可通过配置实现任意串行协议。
- 多通道支持: 每个 FLEXIO 模块最多支持 8 个引脚(Pin),可同时模拟多个 UART、SPI、I2C 或自定义接口。
- 低延迟中断: 支持多种中断触发条件(如移位器完成、定时器溢出、引脚边沿检测),响应速度快。
- DMA 集成: 可与 eDMA 引擎联动,实现数据自动搬运,进一步降低 CPU 负载。
- 独立时钟域: 每个 FLEXIO 模块拥有独立的时钟源和分频器,可灵活调整波特率或位周期。
3.2 功能框图与核心组件
FLEXIO 模块的内部结构由几个关键组件构成,理解它们之间的数据流和控制关系是进行协议模拟的基础。下图展示了 FLEXIO 的核心架构。
3.2.1 核心组件详解
| 组件 | 数量 | 位宽 | 功能描述 |
|---|---|---|---|
| 移位器 (Shifter) | 4 个 | 32 位 | 负责数据的串行输入/输出。每个移位器可配置为发送、接收或匹配模式,是协议数据流的直接执行单元。 |
| 定时器 (Timer) | 4 个 | 16 位 | 提供位时钟、帧同步信号和超时控制。定时器可被外部引脚或内部移位器触发,决定数据采样的时刻。 |
| 引脚控制逻辑 | 1 组 | — | 将移位器和定时器的内部信号映射到外部物理引脚,支持输入、输出、双向和三态控制。 |
| 控制寄存器组 | — | — | 包含模块配置、中断使能、DMA 请求等全局控制寄存器,是软件与硬件交互的接口。 |
3.3 时钟分配与配置
FLEXIO 模块的时钟源独立于系统总线时钟,这为协议模拟提供了极大的灵活性。时钟配置直接影响通信的波特率精度和稳定性。
3.3.1 时钟树结构
在 S32K3 中,FLEXIO 的时钟通常来源于以下路径:
- 系统振荡器 (SOSC): 提供基础时钟源,频率通常为 8 MHz 或 40 MHz。
- PLL 锁相环: 将系统时钟倍频至更高频率(如 160 MHz),作为 FLEXIO 的输入时钟。
- FLEXIO 内部分频器: 通过
SHIFTCFG[INSRC]和SHIFTCTL[TIMER]选择定时器时钟源,再通过定时器的CTL[TIMOD]和CFG[TIMDEC]进行分频。
3.3.2 波特率计算示例
假设 FLEXIO 输入时钟频率为 80 MHz,需要模拟一个 115200 bps 的 UART。定时器配置为双倍数据率模式(即每个位周期包含 2 个定时器时钟周期),则定时器分频值计算如下:
// 目标位周期 = 1 / 115200 ≈ 8.68 µs
// 定时器时钟周期 = 1 / 80 MHz = 12.5 ns
// 每个位需要的定时器时钟数 = 8.68 µs / 12.5 ns ≈ 694.4
// 由于双倍数据率,实际定时器计数 = 694.4 / 2 ≈ 347.2
// 取整后设置 TIMDIV = 347 - 1 = 346
3.4 引脚分配与复用
S32K3 的引脚功能通过 SIUL2(System Integration Unit Lite 2)模块进行管理。FLEXIO 的引脚分配需要经过两个步骤:选择功能复用(MUX)和配置电气特性。
3.4.1 引脚功能选择
每个 FLEXIO 引脚(FLEXIO0 ~ FLEXIO7)对应一个特定的 GPIO 端口引脚。通过设置 SIUL2 的 MSCR(Multiplexed Signal Configuration Register)寄存器,可以将该引脚的功能切换到 FLEXIO 模式。
| FLEXIO 引脚 | 典型 GPIO 端口 | MSCR 复用值 | 功能描述 |
|---|---|---|---|
| FLEXIO0 | PTA0 | 7 | UART TX / SPI MOSI |
| FLEXIO1 | PTA1 | 7 | UART RX / SPI MISO |
| FLEXIO2 | PTA2 | 7 | UART RTS / SPI SCK |
| FLEXIO3 | PTA3 | 7 | UART CTS / SPI CS |
| FLEXIO4 | PTB0 | 7 | LCD RS / 通用 IO |
| FLEXIO5 | PTB1 | 7 | LCD E / 通用 IO |
| FLEXIO6 | PTB2 | 7 | LCD D4 / 通用 IO |
| FLEXIO7 | PTB3 | 7 | LCD D5 / 通用 IO |
3.4.2 引脚配置代码示例
以下代码展示了如何将 PTA0 配置为 FLEXIO0 功能,并设置为输出模式:
// 1. 使能 FLEXIO 模块时钟
PCC->PCCn[PCC_FLEXIO0_INDEX] |= PCC_PCCn_CGC_MASK;
// 2. 配置 SIUL2 MSCR 寄存器
// 假设 PTA0 的 MSCR 地址为 &SIUL2->MSCR[0]
SIUL2->MSCR[0] = (0x7 << 8) // 复用值 7 (FLEXIO)
| (1 << 6) // 输出使能
| (0 << 5) // 输入禁用
| (0 << 4) // 无内部上拉
| (0 << 3); // 标准驱动能力
// 3. 配置 FLEXIO 引脚方向为输出
FLEXIO0->PINCTL[0] = FLEXIO_PINCTL_PINMODE(1); // 1 = 输出
3.5 本章小结
本章深入介绍了 FLEXIO 模块的基础知识,包括其作为可编程状态机的核心定位、内部移位器与定时器的协同工作方式、独立的时钟分配路径以及灵活的引脚复用机制。掌握这些基础是后续实现 UART 协议模拟和 LCD 驱动开发的前提。在下一实战章节中,我们将基于这些知识,开始配置 FLEXIO 的移位器和定时器,生成标准的 UART 时序波形。