1, 时钟中断。前后台程序
2, 实现延迟。
3,计数器counter
0~225分频
re load
change the counter value simutaniously
s32 usleep(u32 useconds)
{
XTime tEnd, tCur;
XTime_GetTime(&tCur);
tEnd = tCur + (((XTime) useconds) * COUNTS_PER_USECOND);
do
{
XTime_GetTime(&tCur);
} while (tCur < tEnd);
return 0;
}
实现思路就是先获取现在的时刻tCur,之后计算延迟了useconds之后的时刻tEnd,之后不断询问定时器当前时刻,随着时间流逝就会到达或者超过tEnd, 此时认为延迟完成,就可以退出了。这里XTime_GetTime读的是全局时钟,后面详细说。
static XScuGic GIC; //GIC
static XScuTimer Timer;//timer
此部分通常不变
使用
XScuGic_CfgInitialize(GIC, IntcConfig,
IntcConfig->CpuBaseAddress);
需要中间变量XScuGic_Config *IntcConfig; ,IntcConfig=XScuGic_LookupConfig(INTC_DEVICE_ID);
Xil_ExceptionRegisterHandler(5,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
(void *)IntcInstancePtr);
Xil_ExceptionEnable();
int Init_Intr_System(XScuGic * IntcInstancePtr) //一般不需要修改
{
int Status;
XScuGic_Config *IntcConfig;
/*
* Initialize the interrupt controller driver so that it is ready to
* use.
*/
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == IntcConfig) {
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
IntcConfig->CpuBaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Enable interrupts from the hardware */
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
(void *)IntcInstancePtr);
Xil_ExceptionEnable();
return XST_SUCCESS;
}
XScuGic_Connect(GicInstancePtr, TimerIntrId,
(Xil_ExceptionHandler)TimerIntrHandler,//set up the timer interrupt
(void *)TimerInstancePtr);
static void TimerIntrHandler(void *CallBackRef)
{
XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef;
XScuTimer_ClearInterruptStatus(TimerInstancePtr);
sec++;
printf("seconds is %d \n",sec);
}
XScuGic_Enable(GicInstancePtr, TimerIntrId);//enable the interrupt for the Timer at GIC
XScuGic_SetPriorityTriggerType(GicInstancePtr, TimerIntrId, 0XA0 , 3 ) ;
void Timer_Setup_Intr_System(XScuGic *GicInstancePtr,XScuTimer *TimerInstancePtr, u16 TimerIntrId)//29号
{
XScuGic_Connect(GicInstancePtr, TimerIntrId,
(Xil_ExceptionHandler)TimerIntrHandler,//set up the timer interrupt
(void *)TimerInstancePtr);
XScuGic_Enable(GicInstancePtr, TimerIntrId);//enable the interrupt for the Timer at GIC
XScuGic_SetPriorityTriggerType(GicInstancePtr, TimerIntrId, 0XA0 , 3 ) ;
}
中间cfg变量 XScuTimer_Config *TMRConfigPtr; //timer config
设置分频,加载计数值,自动重载,使能中断
XScuTimer_SetPrescaler(TimerPtr, PrescalerValue) ;
XScuTimer_LoadTimer(TimerPtr, Load_Value);
XScuTimer_EnableAutoReload(TimerPtr);
XScuTimer_EnableInterrupt(TimerPtr);//enable interrupt on the timer
int Timer_init(XScuTimer *TimerPtr, u8 PrescalerValue , u32 Load_Value,u32 DeviceId)
{
XScuTimer_Config *TMRConfigPtr; //timer config
TMRConfigPtr = XScuTimer_LookupConfig(DeviceId);
XScuTimer_CfgInitialize(TimerPtr, TMRConfigPtr,TMRConfigPtr->BaseAddr);
XScuTimer_SetPrescaler(TimerPtr, PrescalerValue) ;
XScuTimer_LoadTimer(TimerPtr, Load_Value);
XScuTimer_EnableAutoReload(TimerPtr);
XScuTimer_EnableInterrupt(TimerPtr);//enable interrupt on the timer
return 1;
}
XScuTimer_Start(TimerPtr);