当前位置:   article > 正文

【ZYNQ】ZYNQ7000 全局定时器及其驱动示例_zynq-7000sdk定时器使用

zynq-7000sdk定时器使用

定时器简介

ZYNQ 嵌入式系统中,定时器的资源是非常丰富的,每个 Cortex-A9 处理器都有各自独立的 32 位私有定时器和 32 位看门狗定时器,这两个 CPU 同时共享一个 64 位的全局定时器(GT)。

系统框图

全局定时器(GTC)

全局定时器是一个具有自动递增功能的 64 位递增计数器。全局定时器将内存映射到与专用定时器相同的地址空间中。全局定时器仅在安全状态下的重置时被访问。所有 Cortex-A9 处理器都可以访问这个全局定时器。每个 Cortex-A9 处理器都有一个 64 位的比较器,当全局计时器达到比较器值时,该比较器被用来产生一个私有中断。

时钟
  • GTC 的时钟始终为 CPU 频率(CPU_3x2x)的 1/2。
寄存器表

在这里插入图片描述

在这里插入图片描述

驱动示例

  • gtc.c
/**
 * Copyright (c) 2022-2023,HelloAlpha
 * 
 * Change Logs:
 * Date           Author       Notes
 */
#include "gtc.h"

#include "stdio.h"

void GtStart(void)
{
    /* 启动全局定时器 */
    GT_WR_REG(GT_CTRL_REG, AUTO_INC_BIT | IRQ_ENABLE_BIT 
                | COMP_ENABLE_BIT | TMR_ENABLE_BIT);
}

int GtIntrInit(XScuGic *GtInstancePtr, 
                uint64_t Value, void(* CallBack)(void *))
{
    int Status;

    /* 停止全局定时器 */
    GT_WR_REG(GT_CTRL_REG, 0);
    /* 清空计数器低 32 位 */
    GT_WR_REG(GT_CNT_REG0, 0);
    /* 清空计数器高 32 位 */
    GT_WR_REG(GT_CNT_REG1, 0);
    /* 清除中断标志位 */
    GT_WR_REG(GT_INTR_STAT_REG, 1);
    /* 加载比较器低 32 位 */
    GT_WR_REG(COMP_VAL_REG0, (uint32_t)Value);
    /* 加载比较器高 32 位 */
    GT_WR_REG(COMP_VAL_REG1, 0);
    /* 加载递增寄存器数值 */
    GT_WR_REG(AUTO_INC_REG, (uint32_t)(Value >> 32));
    /* 绑定全局定时器中断服务函数 */
    Status = XScuGic_Connect(GtInstancePtr, GT_INTR,
        (Xil_ExceptionHandler)CallBack, 0);
    if (Status != XST_SUCCESS)
    {
        return Status;
    }
    /* 将 27 号全局定时器中断映射到 CPU1 */
    XScuGic_InterruptMaptoCpu(GtInstancePtr, 1, GT_INTR);
    /* 打开全局定时器中断(27号) */
    XScuGic_Enable(GtInstancePtr, GT_INTR);
    return Status;
}

/* 清零计数器 */
void gt_tic(void)
{
    *((volatile int*)(GT_CTRL_REG)) = 0x00;
    *((volatile int*)(GT_CNT_REG0)) = 0x00000000;
    *((volatile int*)(GT_CNT_REG1)) = 0x00000000;
    *((volatile int*)(GT_CTRL_REG)) = 0x01;
}

/** 读取计数器 输出当前时间 单位:ms
 *  可配合 gt_tic 作如下使用:
 *  {
 *      gt_tic();
 *      function_to_get_running_time();
 *      gt_toc();
 *  }
 */
double gt_toc(void)
{
    *((volatile int*)(GT_CTRL_REG)) = 0x00;
    long long cnt = *((volatile int*)(GT_CNT_REG1));
    double elapsed_time = cnt << 32;
    cnt = *((volatile int*)(GT_CNT_REG0));
    elapsed_time += cnt;
    elapsed_time /= CLK_3x2x;
    elapsed_time *= 1000;
    printf("Elapsed time is %f ms.\r\n",elapsed_time);
    return elapsed_time;
}

/* 获取当前时间(单位:秒 second) */
float get_time_s(void)
{
    XTime tCur = 0;
    XTime_GetTime(&tCur);
    return (tCur / (float) COUNTS_PER_SECOND);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • gtc.h
/**
 * Copyright (c) 2022-2023,HelloAlpha
 * 
 * Change Logs:
 * Date           Author       Notes
 */
#ifndef __GTC_H__
#define __GTC_H__

#include "xtime_l.h"
#include "xscugic.h"
#include "xil_io.h"

/* 定时器寄存器 */
#define GT_BASEADDR     GLOBAL_TMR_BASEADDR
#define GT_CNT_REG0     GT_BASEADDR + GTIMER_COUNTER_LOWER_OFFSET
#define GT_CNT_REG1     GT_BASEADDR + GTIMER_COUNTER_UPPER_OFFSET
#define GT_CTRL_REG     GT_BASEADDR + GTIMER_CONTROL_OFFSET
/* 中断寄存器 */
#define GT_INTR         XPAR_GLOBAL_TMR_INTR
/* 中断状态寄存器 */
#define GT_INTR_STAT_REG    GT_BASEADDR + 0x0CU
/* 比较器 */
#define COMP_VAL_REG0       GT_BASEADDR + 0x10U
#define COMP_VAL_REG1       GT_BASEADDR + 0x14U
/* 自动递增寄存器 */
#define AUTO_INC_REG        GT_BASEADDR + 0x18U

#define AUTO_INC_BIT        0x08
#define IRQ_ENABLE_BIT      0x04
#define COMP_ENABLE_BIT     0x02
#define TMR_ENABLE_BIT      0x01

#define CLK_3x2x    333333333

#define GT_WR_REG   Xil_Out32

void GtStart(void);
int GtIntrInit(XScuGic *GtInstancePtr, 
                uint64_t Value, void(* CallBack)(void *));
void gt_tic(void);
double gt_toc(void);
float get_time_s(void);

#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

测试平台:黑金 AX7Z035

芯片型号:XC7Z035-2FFG676

参考来源:UG585

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/666832
推荐阅读
相关标签
  

闽ICP备14008679号