定时/计数器是硬件系统运行状态的忠实记录者,它不受CPU直接干预,自己独立运行,可以完成计时、定时、中断、实时时钟等功能。常用功能:
(1)定时产生中断信号
(2)用作产生延时函数delay()
(3)作计数器,用于检测程序执行时间(这个很好用)。
硬件平台:ZYNQ7z202clg400-2的创龙核心板
官方参考文档:《UG585 - Zynq-7000 SoC Technical Reference Manual (ver1.12.2)-技术参考手册.pdf》,见附录。
首先,zynq 7000 soc芯片具有2个ARM核。每个Cortex-a9处理器都有自己的专用32位定时器和32位看门狗定时器.两个处
理器共享一个全局64位定时器。
时钟:这些定时器的时钟频率固定为CPU时钟频率(Cpu_6x2x)的1/2,即CPU_3x2x时钟。
同时,在系统级别上,有一个24位的看门狗定时器和两个16位的三重定时器/计数器(TTC)。
时钟:系统看门狗计时器的时钟频率为CPU频率的1/4或1/6(即Cpu_1x时钟),或是来自MIO引脚或PL的外部时钟。两个三重定时
器/计数器(TTC)的时钟为CPU频率的1/4或1/6(即Cpu_1x时钟),或是来自MIO引脚或PL的外部时钟。如下图:
全局定时器在Cortex-A9 MPCore技术要求文档中有完整的文档,第4.3和4.4节(参见附录A,附加资源)。全局计时器是一个64位
递增的定时器。全局计时器与私有定时器映射在同一个地址空间中的内存,仅在安全状态下在重置时被访问。所有Cortex-A9处
理器都可以访问全局定时器。每个Cortex-a9核都有一个64位的本地比较器,用于在全局计时器达到比较器值时产生私有中断。
GTC总是以CPU频率的1/2为时钟,即为(Cpu_3x2x)。
根究前一章节,可以知道CPU频率(Cpu_6x2x)设置为666.666M,则Cpu_3x2x为333.333MHz。
关于每个寄存器的详细功能介绍,请阅读UG585
相依介绍如下:
——>Global_Timer_Counter_Register0(全局定时器计数器低32位),地址0xF8F00200,复位值0,可读写。
——>Global_Timer_Counter_Register1(全局定时器计数器高32位),地址0xF8F00204,复位值0,可读写。
——>Global_Timer_Control_Register(全局定时器控制寄存器),地址0xF8F00208,复位值0,可读写;
其中[15:8]位即从低位数起的第二个字节为Prescaler(步距),该字节可用来延迟定时间隔,其计算公式为:(步距值+1)*(加载值+1)*(计数时钟周期);
第3位为触发模式位为0则为单次触发,为1则为自动递增模式,该模式下每次计数器达到比较器的数值则比较器会自动加上递增寄存器的数值,这样就可以周期性的产生下一次中断。
第2位为中断允许位,默认为0即不触发中断,为1时在中断状态寄存器置位时会触发中断;
第1位为比较允许位,默认为0即不比较,为1时每当计数器数值达到比较器数值则会置位事件标志位;
第0位为定时器使能位,默认为0,即不计数,定时器停止,这时可以读写计数值;为1时计数器在计数时钟下开始自动计数,定时器运行,不能写入计数值(只能读出)。
——>Global_Timer_Interrupt_Status_Register(中断状态寄存器),地址0xF8F0020C,复位值0,可读写;
其中第0位为事件标志位,当计数器达到比较器数值时该位置1,需要手动清零,向该位写一个1就能清零(看清楚是写1不是写0)。
——>Comparator_Value_Register0(比较器低32位),地址0xF8F00210,复位值0,可读写;
——>Comparator_Value_Register1(比较器高32位),地址0xF8F00214,复位值0,可读写;
——>Auto_increment_Register(自动递增寄存器),地址0xF8F00218,复位值0,可读写;
在自动递增模式下,每当计数器数值达到比较器数值,则比较器会自动加上自动递增寄存器的值以便产生下一次中断。
一共7个寄存器.
以下列举的注意事项均是参考寄存器说明而来。
(3.1)使能定时器,步骤如下:
I:清除使能bit,即Global_Timer_Control_Register的bit[0]=0
II:写低32bit,即Global_Timer_Counter_Register0
III:写高32bit,即Global_Timer_Counter_Register1
IV:设置timer模式,即设置Global_Timer_Control_Register,是否使能
IV:使能timer,即Global_Timer_Control_Register的bit[0]=1
(3.2)读计数器的当前值,步骤如下:
I:读高32bit,即Global_Timer_Counter_Register1
II:读低32bit,即Global_Timer_Counter_Register0
III:再读一次高32bit,如果此次读取的值与 I 中的不同,则跳转到 II;
IV:数据读取成功
(3.3)如果想使用定时器的定时中断功能,则注意:使用自动增量模式而不是单次触发模式
官方说明:https://china.xilinx.com/support/answers/47545.html
在这里推荐2个很好的连接,他们使用GT做了很好的案例说明:
第一个:https://blog.csdn.net/kkk584520/article/details/10034679
第二个:https://zhuanlan.zhihu.com/p/31061401
cpu专用计时器和看门狗计时器的完整文档需要参看: Cortex-A9 MPCore Technical Requirements Document, sections 4.1 and 4.2,链接:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360e/BABIFIHD.html
定时器和看门狗块都有以下特性:
所有的私有定时器和看门狗总是以CPU频率的1/2为时钟,即为(Cpu_3x2x)。
根究前一章节,可以知道CPU频率(Cpu_6x2x)设置为666.666M,则Cpu_3x2x为333.333MHz。
私有定时器的寄存器和全局定时器的寄存器功能类似,这里略过介绍。
《UG585 - Zynq-7000 SoC Technical Reference Manual (ver1.12.2)-技术参考手册.pdf》下载链接:
https://download.csdn.net/download/ye1223/10811782
’