4. FLEXIO 定时器与移位器:工作原理与配置寄存器详解
FLEXIO 的核心执行单元由 定时器(Timer) 和 移位器(Shifter) 组成。定时器负责产生位时钟、帧同步信号以及控制移位操作的时序;移位器则负责数据的串行发送与接收。理解这两个模块的协同工作原理,是使用 FLEXIO 模拟 UART、SPI、I2C 等协议的基础。
核心概念: 在 FLEXIO 中,定时器是“指挥官”,决定何时移位;移位器是“士兵”,负责数据的进出。一个典型的通信协议(如 UART)通常需要 1 个定时器 + 2 个移位器(一个发送,一个接收)。
4.1 移位器(Shifter)工作原理
移位器本质上是一个可配置的移位寄存器,支持 8、16、24、32 位数据宽度。它可以从 FLEXIO 引脚(SHIFTBUF 与引脚直连)或软件缓冲区(SHIFTBUFBIS/SHIFTBUFBYS)加载数据,并在定时器的触发下逐位移出或移入。
4.1.1 移位器关键配置寄存器
| 寄存器名称 | 偏移地址 | 位域 | 功能描述 |
|---|---|---|---|
| SHIFTCFG[0..3] | 0x00C + n*4 | INSRC, PWIDTH, SSTOP, SSTART | 配置移位器输入源、数据宽度、停止/起始位逻辑 |
| SHIFTCTL[0..3] | 0x020 + n*4 | TIMSEL, PINCFG, PIPPOL, PINPOL, SMOD | 选择关联定时器、引脚配置、引脚极性、工作模式 |
| SHIFTBUF[0..3] | 0x100 + n*4 | SHIFTBUF[31:0] | 主数据缓冲区,CPU/DMA 读写接口 |
| SHIFTBUFBIS[0..3] | 0x120 + n*4 | SHIFTBUFBIS[31:0] | 按位交换缓冲区(Bit Swapped) |
| SHIFTBUFBYS[0..3] | 0x140 + n*4 | SHIFTBUFBYS[31:0] | 按字节交换缓冲区(Byte Swapped) |
实战要点:
- SMOD(移位器模式): 配置为
0b001(发送)或0b010(接收)。UART 全双工需要两个移位器分别配置为发送和接收。 - PWIDTH(数据宽度): UART 通常配置为 8 位数据(
PWIDTH = 7,因为宽度 = PWIDTH + 1)。 - INSRC(输入源): 接收模式下必须选择引脚输入;发送模式下选择定时器输出或引脚输入(用于环回测试)。
4.2 定时器(Timer)工作原理
定时器是 FLEXIO 的时序核心。它内部包含一个 16 位计数器,可以配置为多种模式,用于产生移位时钟、帧同步信号或 PWM 波形。定时器的工作模式决定了它如何计数、何时复位以及如何与移位器交互。
4.2.1 定时器工作模式(TIMOD)
定时器的工作模式决定了其计数行为与输出波形。对于 UART 模拟,最常用的是 双 8 位计数器模式(TIMOD=0b001) 和 单 16 位计数器模式(TIMOD=0b000)。
| TIMOD[2:0] | 模式名称 | 计数器宽度 | 典型应用 |
|---|---|---|---|
0b000 |
单 16 位计数器模式 | 16 位 | 产生固定频率的移位时钟(如 SPI 时钟) |
0b001 |
双 8 位计数器模式 | 高 8 位 + 低 8 位 | UART 波特率生成(低 8 位控制位周期,高 8 位控制停止位/帧间隔) |
0b010 |
单 16 位计数器模式(带触发复位) | 16 位 | 需要外部信号同步的时钟生成 |
0b100 |
PWM 输出模式 | 16 位 | 产生占空比可调的 PWM 波形 |
4.2.2 定时器关键配置寄存器
| 寄存器名称 | 偏移地址 | 位域 | 功能描述 |
|---|---|---|---|
| TIMCFG[0..3] | 0x040 + n*4 | TIMRST, TIMDIS, TIMENA, TIMOUT, TIMDEC, TIMOD | 配置定时器复位源、禁用源、使能源、输出极性、递减源、工作模式 |
| TIMCTL[0..3] | 0x060 + n*4 | TIMERSEL, PINCFG, PINPOL, PINSEL | 选择定时器触发源、引脚配置、引脚极性、引脚选择 |
| TIMCMP[0..3] | 0x080 + n*4 | TIMCMP[15:0] | 定时器比较值,决定计数周期 |
UART 波特率配置陷阱:
- 在双 8 位模式下,
TIMCMP[7:0]控制数据位的长度(波特率分频),TIMCMP[15:8]控制停止位/帧间隔的长度。 - 波特率计算公式:
波特率 = FLEXIO_CLK / ( (TIMCMP[7:0] + 1) * 2 )。例如,FLEXIO_CLK = 48 MHz,需要 115200 波特率,则TIMCMP[7:0] = 48e6 / (115200 * 2) - 1 ≈ 207。 - 停止位长度:
停止位时间 = (TIMCMP[15:8] + 1) * 位时间。通常配置为 1 位停止位,即TIMCMP[15:8] = 0。
4.3 定时器与移位器的协同工作
定时器和移位器通过内部硬件信号线直接连接,无需 CPU 干预。定时器每产生一个移位时钟脉冲,就会触发关联的移位器执行一次移位操作。这种硬件握手机制保证了高速数据传输的确定性。
4.3.1 配置步骤总结
- 使能 FLEXIO 模块时钟:在 PCC 寄存器中配置 FLEXIO 时钟源和分频。
- 配置引脚功能:将 FLEXIO 引脚设置为 ALT9 功能,并配置为输出(发送)或输入(接收)。
- 配置移位器(发送):
SHIFTCTL.SMOD = 0b001(发送模式)SHIFTCTL.PINCFG = 0b00(引脚输出)SHIFTCFG.PWIDTH = 7(8 位数据)SHIFTCFG.INSRC = 0(发送模式选择定时器输出)
- 配置移位器(接收):
SHIFTCTL.SMOD = 0b010(接收模式)SHIFTCTL.PINCFG = 0b01(引脚输入)SHIFTCFG.PWIDTH = 7(8 位数据)SHIFTCFG.INSRC = 1(接收模式选择引脚输入)
- 配置定时器:
TIMCFG.TIMOD = 0b001(双 8 位模式)TIMCMP = (stop_bits << 8) | baud_rate_div(设置波特率和停止位)TIMCTL.TIMERSEL选择触发源(通常选择引脚或软件触发)
- 使能 FLEXIO 模块:设置
FLEXIO_CTRL.FLEXEN = 1。 - 启动发送:向
SHIFTBUF写入待发送数据,定时器自动开始工作。
代码示例:定时器与移位器初始化(伪代码)
// 假设使用 FLEXIO0,定时器 0,移位器 0(发送),移位器 1(接收)
// 波特率 115200,FLEXIO_CLK = 48 MHz
// 1. 使能时钟
PCC->PCCn[PCC_FLEXIO0_INDEX] |= PCC_PCCn_CGC_MASK;
// 2. 配置移位器 0(发送)
FLEXIO0->SHIFTCFG[0] = FLEXIO_SHIFTCFG_PWIDTH(7); // 8 位数据
FLEXIO0->SHIFTCTL[0] = FLEXIO_SHIFTCTL_SMOD(1) // 发送模式
| FLEXIO_SHIFTCTL_PINCFG(0) // 引脚输出
| FLEXIO_SHIFTCTL_TIMSEL(0); // 关联定时器 0
// 3. 配置移位器 1(接收)
FLEXIO0->SHIFTCFG[1] = FLEXIO_SHIFTCFG_PWIDTH(7) // 8 位数据
| FLEXIO_SHIFTCFG_INSRC(1); // 引脚输入
FLEXIO0->SHIFTCTL[1] = FLEXIO_SHIFTCTL_SMOD(2) // 接收模式
| FLEXIO_SHIFTCTL_PINCFG(1) // 引脚输入
| FLEXIO_SHIFTCTL_TIMSEL(0); // 关联定时器 0
// 4. 配置定时器 0(双 8 位模式)
uint16_t baud_div = (48000000 / (115200 * 2)) - 1; // ≈ 207
uint16_t stop_len = 0; // 1 位停止位
FLEXIO0->TIMCMP[0] = (stop_len << 8) | baud_div;
FLEXIO0->TIMCFG[0] = FLEXIO_TIMCFG_TIMOD(1) // 双 8 位模式
| FLEXIO_TIMCFG_TIMRST(0) // 定时器复位源:从不复位
| FLEXIO_TIMCFG_TIMDIS(2) // 禁用源:比较器匹配时禁用
| FLEXIO_TIMCFG_TIMENA(2); // 使能源:触发引脚上升沿
FLEXIO0->TIMCTL[0] = FLEXIO_TIMCTL_PINCFG(3) // 引脚双向输出
| FLEXIO_TIMCTL_PINSEL(3); // 使用 FLEXIO0_D3 作为定时器输出
// 5. 使能 FLEXIO
FLEXIO0->CTRL |= FLEXIO_CTRL_FLEXEN_MASK;
4.4 本章小结
- 移位器 负责数据的串行化与反串行化,通过
SHIFTCFG和SHIFTCTL配置数据宽度、模式与引脚。 - 定时器 负责产生移位时钟与帧同步,通过
TIMCFG、TIMCTL和TIMCMP配置工作模式、波特率与停止位。 - 双 8 位模式 是模拟 UART 的关键,低 8 位控制位周期,高 8 位控制帧间隔。
- 定时器与移位器通过内部硬件信号线直接耦合,无需 CPU 逐位干预,可实现高达数 Mbps 的通信速率。