与大多数 Zynq 外设一样,专用定时器(Private Timer,这里翻译成专用定时器,也可翻译成私有定时器)具有许多预定义的函数和宏,可帮助工程师有效地使用资源。这些包含在#include "xscutimer.h"
参考:
❝UG585 CH8 Timer
每个A9处理器都有私有的32位定时器和32位看门狗定时器。两个处理器共享一个64位定时器。这些定时器的时钟始终是的CPU频率的1/2(CPU_3x2x)。
xscutimer.h 中包含以下函数(宏):
定时器本身通过 Zynq All Programmable SoC 中的四个寄存器进行控制:
设置定时器所需的定时器设备 ID 和定时器中断 ID 包含在 XParameters.h 中。这篇博文中的示例使用了我们之前开发的按钮中断。在此示例中,将加载计时器并在按下按钮时开始运行。(注意:定时器不会在自动重载模式下运行)。当预设的定时器倒计时值达到零时,定时器将产生中断。产生的中断通过 STDOUT 触发消息输出,然后将清除中断以等待下一次按下按钮。
此示例将相同的值加载到计数器中。因此,在文件顶部声明了定时器计数值的声明
#define TIMER_LOAD_VALUE 0xFFFFFFFF
下一步是配置和初始化私有定时器,执行自检,并将定时器计数值加载到定时器中:
//定时器初始化
TMRConfigPtr = XScuTimer_LookupConfig(TIMER_DEVICE_ID);
XScuTimer_CfgInitialize(&Timer, TMRConfigPtr,TMRConfigPtr-> BaseAddr );
XScuTimer_SelfTest(&Timer);
//加载定时器
XScuTimer_LoadTimer(&Timer, TIMER_LOAD_VALUE);
我们还需要更新中断设置子程序,将定时器中断连接到 GIC(通用中断控制器)并启用定时器中断:
//设置定时器中断
XScuGic_Connect(GicInstancePtr, TimerIntrId,
( Xil_ExceptionHandler )TimerIntrHandler,
( void *) TimerInstancePtr);
//为 GIC 处的定时器启用中断
XScuGic_Enable(GicInstancePtr, TimerIntrId);
//启用定时器中断
XScuTimer_EnableInterrupt(TimerInstancePtr);
其中 TimerIntrHandler 是中断发生时要调用的函数的名称。
接下来,必须在 GIC 上和定时器本身内启用定时器中断。定时器中断服务程序非常简单。它只是清除挂起的中断并通过 STDOUT 写出一条消息:
static void TimerIntrHandler ( void *CallBackRef)
{
XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef;
XScuTimer_ClearInterruptStatus(TimerInstancePtr);
printf ("****Timer Event!!!!!!!!!!!!!****\n\r");
最后一步是修改GPIO中断服务程序,在每次按下按钮时启动定时器:
//加载定时器
XScuTimer_LoadTimer (&Timer, TIMER_LOAD_VALUE);
//启动定时器
XScuTimer_Start(&Timer);
为此,我们首先将定时器值加载到定时器中,然后调用定时器启动函数,然后再次清除按钮中断并恢复处理.下面是这个程序的输出现在的样子:
源文件:
❝https://gitee.com/openfpga/zynq-chronicles/blob/master/main_part15.c