S32K3 FLEXIO模拟UART与LCD显示驱动实战 - 第3节

3.1 FLEXIO 外设简介

FLEXIO(Flexible Input/Output)是 NXP S32K3 系列微控制器中一个高度可配置的、基于硬件的串行通信外设。它本质上是一个“可编程状态机”,允许开发者通过软件配置来模拟多种标准或自定义的串行协议,而无需占用内核 CPU 资源进行位拆裂(Bit-Banging)。

在 S32K3 平台上,FLEXIO 的主要定位是作为现有通信外设(如 LPUART、LPSPI、LPI2C)的补充或替代方案,尤其适用于需要灵活时序、多通道或非标准协议的场合。

核心价值: FLEXIO 通过硬件状态机实现协议时序,既保留了软件模拟的灵活性,又获得了接近硬件外设的实时性能,是嵌入式系统设计中“软硬结合”的典型代表。

3.1.1 主要特性

  • 可编程状态机: 每个 FLEXIO 模块包含多个独立的 32 位移位器(Shifter)和定时器(Timer),可通过配置实现任意串行协议。
  • 多通道支持: 每个 FLEXIO 模块最多支持 8 个引脚(Pin),可同时模拟多个 UART、SPI、I2C 或自定义接口。
  • 低延迟中断: 支持多种中断触发条件(如移位器完成、定时器溢出、引脚边沿检测),响应速度快。
  • DMA 集成: 可与 eDMA 引擎联动,实现数据自动搬运,进一步降低 CPU 负载。
  • 独立时钟域: 每个 FLEXIO 模块拥有独立的时钟源和分频器,可灵活调整波特率或位周期。

3.2 功能框图与核心组件

FLEXIO 模块的内部结构由几个关键组件构成,理解它们之间的数据流和控制关系是进行协议模拟的基础。下图展示了 FLEXIO 的核心架构。

FLEXIO 模块功能框图 FLEXIO 模块功能框图 IP Bus 接口 控制寄存器组 移位器组 Shifter 0 Shifter 1 Shifter 2 Shifter 3 (每个 32-bit) 定时器组 Timer 0 Timer 1 Timer 2 Timer 3 (16-bit 计数器) 引脚控制逻辑 (Pin Control) 外部引脚 (FLEXIO0 ~ FLEXIO7) 数据流方向 寄存器配置 → 移位器/定时器 → 引脚控制 → 外部

3.2.1 核心组件详解

组件 数量 位宽 功能描述
移位器 (Shifter) 4 个 32 位 负责数据的串行输入/输出。每个移位器可配置为发送、接收或匹配模式,是协议数据流的直接执行单元。
定时器 (Timer) 4 个 16 位 提供位时钟、帧同步信号和超时控制。定时器可被外部引脚或内部移位器触发,决定数据采样的时刻。
引脚控制逻辑 1 组 — 将移位器和定时器的内部信号映射到外部物理引脚,支持输入、输出、双向和三态控制。
控制寄存器组 — — 包含模块配置、中断使能、DMA 请求等全局控制寄存器,是软件与硬件交互的接口。
实战提示: 在模拟 UART 时,通常使用 1 个移位器作为发送器,1 个移位器作为接收器,并搭配 1 个定时器产生波特率时钟。剩余的移位器和定时器可用于实现其他功能,如 LCD 数据/命令控制。

3.3 时钟分配与配置

FLEXIO 模块的时钟源独立于系统总线时钟,这为协议模拟提供了极大的灵活性。时钟配置直接影响通信的波特率精度和稳定性。

3.3.1 时钟树结构

在 S32K3 中,FLEXIO 的时钟通常来源于以下路径:

  1. 系统振荡器 (SOSC): 提供基础时钟源,频率通常为 8 MHz 或 40 MHz。
  2. PLL 锁相环: 将系统时钟倍频至更高频率(如 160 MHz),作为 FLEXIO 的输入时钟。
  3. FLEXIO 内部分频器: 通过 SHIFTCFG[INSRC] 和 SHIFTCTL[TIMER] 选择定时器时钟源,再通过定时器的 CTL[TIMOD] 和 CFG[TIMDEC] 进行分频。
FLEXIO 时钟分配路径 FLEXIO 时钟分配路径 SOSC 8/40 MHz PLL ~160 MHz 系统总线时钟 80/160 MHz FLEXIO 模块 时钟选择关键点 1. FLEXIO 时钟源可选择 PLL 输出或系统总线时钟,通过 PCC 模块配置。 2. 内部定时器分频器决定最终位时钟频率,公式:F_bit = F_flexio / (2 × (TIMDIV + 1))。

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
精度警告: 取整操作会导致波特率误差。当误差超过 ±2% 时,可能引起 UART 通信帧错误。建议在配置后使用示波器或逻辑分析仪验证实际位宽。

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 = 输出
布局建议: 在 PCB 设计时,尽量将 FLEXIO 的 UART 引脚(TX/RX)与 LCD 控制引脚(RS/E/D4-D7)分开布局,避免数字信号串扰影响 LCD 显示稳定性。

3.5 本章小结

本章深入介绍了 FLEXIO 模块的基础知识,包括其作为可编程状态机的核心定位、内部移位器与定时器的协同工作方式、独立的时钟分配路径以及灵活的引脚复用机制。掌握这些基础是后续实现 UART 协议模拟和 LCD 驱动开发的前提。在下一实战章节中,我们将基于这些知识,开始配置 FLEXIO 的移位器和定时器,生成标准的 UART 时序波形。