DW_apb_timers 的寄存器设计清晰明了,主要包括 定时器私有寄存器 和 全局共享寄存器 两大类。理解这些寄存器的功能和编程注意事项,是正确配置和使用该 IP 核的基础。
📝 寄存器概览
下表汇总了 DW_apb_timers 的核心寄存器及其地址偏移。其中,N 代表定时器序号(从 0 开始),基地址 Base + 0xN * 0x14 是每个定时器私有寄存器区域的起始地址。
| 类别 | 寄存器名称 (Register Name) | 偏移地址 (Offset) | 操作 | 描述 (Description) |
|---|---|---|---|---|
| 定时器 N 私有寄存器 | TimerNLoadCount |
Base + 0x00 |
读/写 | 加载计数寄存器,用于设定定时器的初始计数值。 |
TimerNCurrentValue |
Base + 0x04 |
读/写 | 当前计数值寄存器,反映定时器当前的实时计数值。 | |
TimerNControlReg |
Base + 0x08 |
读/写 | 控制寄存器,用于配置定时器的使能、模式等。 | |
TimerNEOI |
Base + 0x0C |
只读 | 中断结束寄存器,读取该寄存器可清除当前定时器的中断状态。 | |
TimerNIntStatus |
Base + 0x10 |
只读 | 中断状态寄存器,读取该寄存器可查询当前定时器未经掩码的中断状态。 | |
| 全局共享寄存器 | TimersIntStatus |
0xA0 |
只读 | 全局中断状态寄存器,用于查询所有定时器经过掩码后的中断状态。 |
TimersEOI |
0xA4 |
只读 | 全局中断结束寄存器,读取可一次性清除所有定时器的中断状态。 | |
TimersRawIntStatus |
0xA8 |
只读 | 原始中断状态寄存器,反映所有定时器未经掩码的原始中断状态。 | |
TimersCompVersion |
0xAC |
只读 | 组件版本寄存器,用于读取该 IP 核的版本号。 |
注意 :部分资料中提到的
APBTMRS_REG_SIZE 0x14表示每个定时器的寄存器空间占用大小为 0x14 字节(即 20 字节),这意味着Timer(N+1)LoadCount的地址偏移是Base + 0x14。
📖 寄存器详解
1. 加载计数寄存器 (TimerNLoadCount)
-
作用:设定定时器的初始计数值。定时器将从该值开始递减计数。
-
加载时机:
-
定时器从禁用 (
TimerNControlReg[0] = 0) 变为启用 (TimerNControlReg[0] = 1) 时。 -
定时器计数递减到 0 时,根据工作模式加载不同值:
-
自由运行模式 (
free running):加载该定时器宽度下所能表示的最大值。 -
用户自定义模式 (
user mode) :重新加载TimerNLoadCount寄存器的值。
-
-
2. 当前计数值寄存器 (TimerNCurrentValue)
-
作用:读取此寄存器可获得定时器当前的实时计数值。
-
重要特性:对该寄存器的写操作会立即更新计数器的当前值。
3. 控制寄存器 (TimerNControlReg)
这是配置定时器行为的关键寄存器,其各个位的功能如下:
| 位 (Bit) | 名称 | 描述 (Description) |
|---|---|---|
bit 0 |
ENABLE |
定时器使能位 。 0:禁用定时器;1:启用定时器。 |
bit 1 |
MODE |
工作模式选择位 。 0:自由运行模式 (free running);1:用户自定义模式 (periodic)。 |
bit 2 |
INT_MASK |
中断使能位 。 0:禁用中断;1:使能中断。 |
bit 3 |
EXTIN_CLK |
外部输入时钟使能 。 1:使用外部输入信号作为定时器时钟源。 |
bit 4 |
EXTIN_EN |
外部输入使能信号使能 。 1:使用外部输入信号作为定时器的使能信号。 |
4. 中断结束寄存器 (TimerNEOI)
-
作用:读取此寄存器是清除当前定时器中断的标准方法。
-
重要特性:该寄存器是只读的,读取操作本身即触发中断清除。
5. 中断状态寄存器 (TimerNIntStatus)
-
作用 :查询当前定时器的原始中断状态 ,不受控制寄存器中
INT_MASK位的影响。 -
重要特性:读取该寄存器不会清除中断状态。
6. 全局共享寄存器
-
TimersIntStatus:所有定时器经过掩码后的中断状态的"或"结果。若所有定时器的中断都被掩码,则此寄存器可能为 0。 -
TimersEOI:一次性清除所有定时器的中断状态,等同于对所有TimerNEOI寄存器执行了读取操作。 -
TimersRawIntStatus:所有定时器未经掩码的原始中断状态的"或"结果。
⚠️ 关键编程注意事项
为了确保系统的稳定性和可靠性,在使用这些寄存器时,有几个关键的注意事项需要牢记:
-
中断清除 :推荐通过读取
TimerNEOI寄存器来清除中断,而非写入操作。这是因为在高速 APB 总线中,使用写操作清除中断可能存在时序风险,导致中断清除不可靠。 -
处理保留位 :在修改任何包含保留位的寄存器时,务必执行 "读-修改-写" (Read-Modify-Write, RMW) 操作,以避免意外更改保留位的状态,从而防止未定义行为。
-
跨时钟域访问 :
timer_N_clk可与pclk异步。如果它们是异步的,读取TimerNCurrentValue寄存器可能会返回未定义的值,需要谨慎处理。 -
原子操作 :当定时器位宽大于 APB 数据总线宽度时,读写操作可能需要拆分为多次总线访问。此时应启用一致性电路 ,并按 LSB 到 MSB 的顺序进行编程,以保证数据的一致性。
💎 总结
DW_apb_timers 的寄存器结构紧凑且功能明确,核心就是围绕 计数(Load/Current) 、控制(Control) 和 中断(Status/EOI) 三个维度来操作定时器。理解这些寄存器及其交互方式,并严格遵循中断清除、保留位处理和跨时钟域操作的规范,是成功应用这个 IP 核的关键。