1 简介
ZYNQ中每个 Cortex-A9 处理器都有各自独立的 32 位私有定时器和 32 位看门狗定时器,这两个 CPU 同时共享一个 64 位的全局定时器(GT)。这三个定时器的中断均属于PPI。这些定时器总是以 1/2 的 CPU 频率计时。
除此之外,PS 中 还有一个 24 位的系统看门狗定时器(SWDT)和两个 16位的TTC(Triple Timer Counters)。系统看门狗定时器可以在系统发生灾难性的故障时(如 PS 中的 PLL 工作异常)发出信号,使得系统程序重新启动,保证了系统 安全可靠的运行。这三个定时器的中断属于SPI。系统看门狗定时器的时钟频率为 CPU 频率的 1/4 或 1/6,或者 可以由来自 MIO 引脚或 PL 的外部信号计时。两个三重定时器/计数器的时钟频率始终为 CPU 频率的 1/4 或 1/6,用于计算来自 MIO 引脚或 PL 的信号脉冲宽度。
其中私有定时器(CPU Private Timer)最为常用,私有定时器的时钟频率为 CPU 时钟频率的一半,如 ARM 的工作时钟频率为 666.666Mhz,则私有定时 器的时钟频率为 333.333Mhz。私有定时器的特性如下:
- 32 位计数器,当计数器递减至 0 后产生中断;
- 8 位预分频计数器,可以更好的控制中断周期;
- 可以配置单次定时或者自动重载模式;
- 通过配置起始计数值来设置定时时间。
2 驱动
私有定时器初始化。
int Timer_Init(u32 TimerLoadValue){
int status;
XScuTimer_Config *TimerCfgPtr;
TimerCfgPtr = XScuTimer_LookupConfig(XPAR_XSCUTIMER_0_DEVICE_ID);
if(TimerCfgPtr==NULL)
return XST_FAILURE;
status = XScuTimer_CfgInitialize(&Timer, TimerCfgPtr,
TimerCfgPtr->BaseAddr);
if (status != XST_SUCCESS)
return XST_FAILURE;
XScuTimer_LoadTimer(&Timer, TimerLoadValue); // 加载计数周期
XScuTimer_EnableAutoReload(&Timer); // 设置自动装载模式
return XST_SUCCESS;
}
中断初始化。
void Timer_Intr_Init(XScuTimer * TimerPtr,uint16_t IntrId, Xil_InterruptHandler Handler){
Set_ScuGic_Link(IntrId, 0xA8, HIGH_Level_Sensitive,
(Xil_ExceptionHandler)Handler, (void *)TimerPtr);
XScuTimer_EnableInterrupt(TimerPtr); //使能定时器中断
}
void Set_ScuGic_Link(uint16_t IntrId, uint8_t Priority, uint8_t Trigger,
Xil_InterruptHandler Handler, void *CallBackRef)
{
XScuGic_SetPriorityTriggerType(&ScuGicInt, IntrId, Priority, Trigger);
XScuGic_Connect(&ScuGicInt, IntrId,
(Xil_ExceptionHandler)Handler,CallBackRef);
XScuGic_Enable(&ScuGicInt, IntrId);
}
最后在主程序中启动定时器计时。
XScuTimer_Start(&Timer); //启动定时器