Full picture
17

定时器控制器

17.1 概述

定时器控制器提供了一个简单而灵活的 16 位定时器,由主 50 MHz 系统时钟驱动。它可以向上或向下计数到零,支持单次或自动重载模式,用于测量时间间隔或生成周期性事件。

一个可编程的 16 位时钟分频器可降低基础时钟频率,以适应较慢的组件或所需的时间间隔。定时器可以通过其寄存器进行启动、停止、重置和配置。

与其他控制器一样,DMA 控制器可以映射到设备组中,I/O 端口起始地址为 0xA0,其设备索引为 6

17.2 操作

定时器通过递增或递减 16 位累加器向零计数,具体取决于配置的方向:

  • 当定时器启用时(CTRL 寄存器中设置了 ENABLE 位),累加器在每个由时钟分频器定义的时钟周期内更新一次(见下文)。
  • 如果向上计数(CTRL 寄存器中 DIR = 0),累加器每 tick 增加 1,直到回绕并达到零。
  • 如果向下计数(CTRL 寄存器中 DIR = 1),累加器每 tick 减少 1,直到达到零。
  • 当累加器达到零时:
    • 如果 AUTO_RELOAD 启用,累加器立即重置为重载值并继续计数,从而产生周期性定时器。
    • 如果 AUTO_RELOAD 禁用,定时器通过清除 ENABLE 位停止,相当于执行单次定时器。

您可以随时通过写入 RESET 位来重置定时器,此时重载值会立即加载到累加器中。

读取和写入当前计数值通过 CNT_LOCNT_HI 两个寄存器完成,通过先锁存低字节来提供一致的 16 位快照。

这种灵活的行为使得定时器控制器可用于精确定时、事件生成或周期性中断(通过轮询或后续扩展中断支持)。

⚠️ 所有 16 位值(时钟分频器、重载值和计数器)必须先写入最低有效字节(LSB),再写入最高有效字节(MSB)。这是因为控制器在第一次写入时锁存 LSB,只有在写入 MSB 后才应用完整的 16 位值。

17.3 时钟分频器

定时器控制器由主 50 MHz 系统时钟驱动。然而,许多定时应用需要更慢的时间间隔。为此,一个 16 位时钟分频器降低了有效的定时器 tick 频率。该时钟分频器可通过写入 DIV_LODIV_HI 寄存器来设置。

分频器作为一个简单的计数器,每 $\text{clk_divider} + 1$ 个系统时钟周期生成一个"tick"。这意味着定时器累加器每间隔以下时间更新一次:

$T_{tick} = \frac{\text{clk_divider} + 1}{f_{clk}}$

其中:

  • $T_{tick}$ 是定时器 tick 周期(秒)
  • $\text{clk_divider}$ 是用户编程的 16 位分频器值
  • $f_{clk} = 50\text{MHz}$ 是系统时钟频率

例如,如果 clk_divider = 4999,定时器每间隔以下时间更新:

$T_{tick} = \frac{4999 + 1}{50,000,000} = \frac{5000}{50,000,000} = 0.0001\,\text{s} = 100\,\mu s$

这允许您配置每个定时器 tick 的时间间隔,范围从 20 ns(最快,分频器 = 0)到约 1.31 ms(最大分频器 = 65535)。

17.4 寄存器总览

Name Description Base-relative address Access
CTRL 通用定时器控制寄存器。控制使能、方向、复位和自动重载行为。 0x00 varies
DIV_LO 时钟分频器的低8位。必须在写入HIGH寄存器之前写入以锁存完整值。 0x01 WO
DIV_HI 时钟分频器的高8位。写入此寄存器应用完整的16位值。 0x02 WO
REL_LO 重载值的低8位。必须在写入HIGH寄存器之前写入以锁存完整值。 0x03 WO
REL_HI 重载值的高8位。写入此寄存器应用完整的16位值。 0x04 WO
CNT_LO 当前计数器值的低8位。必须在HIGH寄存器之前读取或写入。 0x05 RW
CNT_HI 计数器值的高8位。仅在访问CNT_LO后读取/写入。 0x06 RW

17.5 寄存器

CTRL (0x00)
通用定时器控制寄存器。控制使能、方向、复位和自动重载行为。
ENABLE
AUTO_RELOAD
DIR
(reserved)
RESET
7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 0
Reset
ENABLE
写入1启动定时器。若未启用自动重载,计数器到达0时自动清零。 (RW)
AUTO_RELOAD
启用计数器到达0时(含)的自动重载。 (RW)
DIR
定时器方向,`0` = 向上计数,`1` = 向下计数。 (RW)
RESET
写入1将定时器计数器复位到当前重载值。 (WO)
DIV_LO (0x01)
时钟分频器的低8位。必须在写入HIGH寄存器之前写入以锁存完整值。
DIV_LSB
7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 0
Reset
DIV_LSB
时钟分频器的低字节。后续写入DIV_HI时锁存。 (WO)
DIV_HI (0x02)
时钟分频器的高8位。写入此寄存器应用完整的16位值。
DIV_MSB
7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 0
Reset
DIV_MSB
时钟分频器的高字节。写入此值应用从DIV_LO锁存的值。 (WO)
REL_LO (0x03)
重载值的低8位。必须在写入HIGH寄存器之前写入以锁存完整值。
REL_LSB
7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 0
Reset
REL_LSB
重载值的低字节。后续写入REL_HI时锁存。 (WO)
REL_HI (0x04)
重载值的高8位。写入此寄存器应用完整的16位值。
REL_MSB
7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 0
Reset
REL_MSB
重载值的高字节。写入此值应用从REL_LO锁存的值。 (WO)
CNT_LO (0x05)
当前计数器值的低8位。必须在HIGH寄存器之前读取或写入。
CNT_LSB
7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 0
Reset
CNT_LSB
计数器值的低字节。锁存值供后续访问CNT_HI使用。 (RW)
CNT_HI (0x06)
计数器值的高8位。仅在访问CNT_LO后读取/写入。
CNT_MSB
7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 0
Reset
CNT_MSB
计数器值的高字节。必须在CNT_LO之后访问以实现一致的16位访问。 (RW)
EN | 中文Beta