资料ID:PG079
文档查找软件:DocNav,在安装vivado时可以选择一并安装
Vivado中的timer框图如下图
这里的定时器有四种模式,分别如下
Generate Mode
Capture Mode
Pulse Width Modulation Mode
Cascade Mode
由于所做项目中仅仅使用Generate Mode,所以着重介绍这一种模式。
Generate Mode
在Generate Mode中,load Register中的数值将会装载到conuter中。当使能counter时,它的值开始递增或者递减,这取决于control/status Register中的某位的值,之后会具体介绍该寄存器中的每一位的值的作用。若计数器为递增计数器,当其值为FFFFFFFF时,计数器会停止或者自动的将load Register中的值装载到计数器中,这个也是由control/status Register中的某一位决定的。
如果使能定时器的中断,则在定时器到达timeout value时,中断信号将会被设置为1。可以清除中断信号通过向control/status Register中的某一位写入1。这就表示该IP核产生的中断信号不会自动清除,需要在中断处理程序中手动清除。
在Generate Mode中,一个定时器产生中断的原因是the counter rolling over(这里指的是由FFFFFFFF变为00000000,或者由00000000变为FFFFFFFF)。
Register Space
AXI Timer这个IP核中包含两个定时器,这两个定时器具有相同的Register Space,所以只需介绍Timer 0对应的Register Space。
Timer 0对应的Register有3个,地址偏移分别为0h、04h、08h,偏移地址是相对于Timer的基地址,即baseaddress。这个基地址在进行硬件平台设计时会自动分配。接下来具体介绍这些Register。
TLR0
当counter被配置少于32位时,装载寄存器的值就是TLR0。装载寄存器的位定义表如下所示。
TCR0
当计数器的宽度少于32位时,计数值就是TCR0的值。TCR0的位定义表如下。
TCSR0
Control/Status寄存器包含了对定时器模块0的控制和状态位。
该寄存器中有意义的比特位从0至11,具体意义如下。
第0位:值为0时,定时器模式为Generate Mode;值为1时,定时器模式为Capture Mode。
第1位:值为0时,定时器为递增计数器;值为1时,定时器为递减计数器。
第4位:当一个定时器是Generate Mode,该位决定了一个计数器是否重新装载生成值并且继续运行或者保持在终止值。值为0时,保持在终止值;值为1时,重新装载生成值。
第5位:值为0时,不装载TLR0中的值到TCR0中;值为1时,装载TLR0中的值到TCR0中。注意:当该值为1时,装载过程会一直保持,所以在开始计数前要将该位的值置为0。
第6位:值为0时,不使能中断信号;值为1时,使能中断信号。
第7位:值为0时,计数器停止;值为1时,计数器运行。
第8位:当读取该位时,若值为0,表示没有中断发生;若值为1,表示中断已经发生。当向该位写数据时,若写0,则对该位没有任何改变;若写1,则会将该位变为0。这意味着Vivado中的Timer产生的中断信号需要手动清除。
第11位:值为0时,不使能Cascade Mode;值为1时,使能Cascade Mode。
示例程序:每隔固定时间打印hello world
#include "xil_printf.h"
#define TBAddress 0x41c00000 //timer Baseaddress
#define TCSR0 0x0 //register TCSR0 address offset
#define TLR0 0x4 //register TLR0 address offset
#define TCR0 0x8 //register TCR0 address offset
#define INTERRUPT (*(volatile int *)(TBAddress + TCSR0) & 0x00000100)
int main()
{
/**********initialize timer*******************/
*(volatile int *)(TBAddress + TLR0) = 0x3B9ACA00;
*(volatile int *)(TBAddress + TCSR0) &= 0xfffffffe;//set timer to Generate Mode
*(volatile int *)(TBAddress + TCSR0) |= 0x00000002;//set counter to down counter
*(volatile int *)(TBAddress + TCSR0) |= 0x00000010;//automatically load
*(volatile int *)(TBAddress + TCSR0) |= 0x00000020;//load
*(volatile int *)(TBAddress + TCSR0) |= 0x00000040;//enable interrupt
*(volatile int *)(TBAddress + TCSR0) |= 0x00000100;
/*********************************************/
/*********print "hello word" per 10 second*******/
*(volatile int *)(TBAddress + TCSR0) &= 0xffffffdf;
*(volatile int *)(TBAddress + TCSR0) |= 0x00000080;//start
while(1)
{
if(INTERRUPT)
{
print("hello world\r\n");
*(volatile int *)(TBAddress + TCSR0) |= 0x00000100;//clear interrupt
}
}
/************************************************/
}
为了更加清晰地显示定时器的驱动过程,上述代码对TCSR0寄存器中的各个位进行了设置。以上代码使用的是递减计数器,定时器时钟频率为100MHz。利用中断信号来判断时间是否到达。