前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ZYNQ从放弃到入门(五)- 专用定时器

ZYNQ从放弃到入门(五)- 专用定时器

作者头像
碎碎思
发布2022-06-06 08:09:41
1.1K0
发布2022-06-06 08:09:41
举报
文章被收录于专栏:OpenFPGA

ZYNQ从放弃到入门(五)- 专用定时器

与大多数 Zynq 外设一样,专用定时器(Private Timer,这里翻译成专用定时器,也可翻译成私有定时器)具有许多预定义的函数和宏,可帮助工程师有效地使用资源。这些包含在#include "xscutimer.h"

参考:

❝UG585 CH8 Timer

每个A9处理器都有私有的32位定时器和32位看门狗定时器。两个处理器共享一个64位定时器。这些定时器的时钟始终是的CPU频率的1/2(CPU_3x2x)。

xscutimer.h 中包含以下函数(宏):

  • 初始化定时器
  • 运行计时器自检
  • 启动和停止计时器
  • 管理定时器(重启、检查是否过期、加载定时器、启用/禁用自动加载)
  • 设置预分频器
  • 获取预分频器值
  • 设置、启用、禁用、清除和管理定时器中断

定时器本身通过 Zynq All Programmable SoC 中的四个寄存器进行控制:

  • Private Timer Load Register——用于自动重载模式。该寄存器包含启用自动重载时要重载到专用定时器计数器寄存器中的值。
  • Private Timer Counter Register——这个寄存器是实际的计数器本身。当该寄存器中的值达到零时,设置中断事件标志(启用时)。
  • Private Timer Control Register ——该控制寄存器启用或禁用定时器、自动重载模式和中断生成。它还包含定时器预分频器。
  • Private Timer Interrupt Status Register——该寄存器包含专用定时器中断状态事件标志

设置定时器所需的定时器设备 ID 和定时器中断 ID 包含在 XParameters.h 中。这篇博文中的示例使用了我们之前开发的按钮中断。在此示例中,将加载计时器并在按下按钮时开始运行。(注意:定时器不会在自动重载模式下运行)。当预设的定时器倒计时值达到零时,定时器将产生中断。产生的中断通过 STDOUT 触发消息输出,然后将清除中断以等待下一次按下按钮。

此示例将相同的值加载到计数器中。因此,在文件顶部声明了定时器计数值的声明

代码语言:javascript
复制
#define TIMER_LOAD_VALUE 0xFFFFFFFF

下一步是配置和初始化私有定时器,执行自检,并将定时器计数值加载到定时器中:

代码语言:javascript
复制
//定时器初始化     
TMRConfigPtr = XScuTimer_LookupConfig(TIMER_DEVICE_ID);      
XScuTimer_CfgInitialize(&Timer, TMRConfigPtr,TMRConfigPtr-> BaseAddr );      
XScuTimer_SelfTest(&Timer); 
//加载定时器    
XScuTimer_LoadTimer(&Timer, TIMER_LOAD_VALUE);

我们还需要更新中断设置子程序,将定时器中断连接到 GIC(通用中断控制器)并启用定时器中断:

代码语言:javascript
复制
//设置定时器中断      
XScuGic_Connect(GicInstancePtr, TimerIntrId,                                   
              ( Xil_ExceptionHandler )TimerIntrHandler,                                     
              ( void *) TimerInstancePtr); 
//为 GIC 处的定时器启用中断      
XScuGic_Enable(GicInstancePtr, TimerIntrId);   
//启用定时器中断      
XScuTimer_EnableInterrupt(TimerInstancePtr); 

其中 TimerIntrHandler 是中断发生时要调用的函数的名称。

接下来,必须在 GIC 上和定时器本身内启用定时器中断。定时器中断服务程序非常简单。它只是清除挂起的中断并通过 STDOUT 写出一条消息:

代码语言:javascript
复制
static void TimerIntrHandler ( void *CallBackRef) 
{       
XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef;       
XScuTimer_ClearInterruptStatus(TimerInstancePtr); 
printf ("****Timer Event!!!!!!!!!!!!!****\n\r"); 

最后一步是修改GPIO中断服务程序,在每次按下按钮时启动定时器:

代码语言:javascript
复制
//加载定时器
XScuTimer_LoadTimer       (&Timer, TIMER_LOAD_VALUE);
//启动定时器
XScuTimer_Start(&Timer); 

为此,我们首先将定时器值加载到定时器中,然后调用定时器启动函数,然后再次清除按钮中断并恢复处理.下面是这个程序的输出现在的样子:

源文件:

❝https://gitee.com/openfpga/zynq-chronicles/blob/master/main_part15.c

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-04-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenFPGA 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ZYNQ从放弃到入门(五)- 专用定时器
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档