【ZYNQ】ZYNQ7000 私有定时器及其驱动应用示例

article/2025/9/24 16:46:49

定时器简介

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

系统框图

私有定时器

特点

  • 32 位计数器,当计数器递减至 0 时产生中断
  • 8 位预分频计数器,可以更好的控制中断周期
  • 可以配置单次定时或者自动重载模式
  • 通过配置起始计数值来设置定时时间

时钟

  • 私有定时器时钟为 CPU 频率(CPU_3x2x)的一半,如 ARM 的工作时钟频率为 666.666Mhz,则私有定时器的时钟频率为 333.333Mhz。

寄存器表

在这里插入图片描述

驱动示例

  • timer.c
/*** Copyright (c) 2022-2023,HelloAlpha* * Change Logs:* Date           Author       Notes*/
#include "timer.h"int TimerInit(XScuTimer *TimerInstancePtr, uint16_t TimerDeviceId, uint32_t TimerLoadValue)
{int Status;XScuTimer_Config *ConfigPtr;ConfigPtr = XScuTimer_LookupConfig(TimerDeviceId);Status = XScuTimer_CfgInitialize(TimerInstancePtr, ConfigPtr,ConfigPtr->BaseAddr);if (Status != XST_SUCCESS) {return XST_FAILURE;}Status = XScuTimer_SelfTest(TimerInstancePtr);if (Status != XST_SUCCESS) {return XST_FAILURE;}XScuTimer_EnableAutoReload(TimerInstancePtr);XScuTimer_LoadTimer(TimerInstancePtr, TimerLoadValue);return Status;
}int TimerIntrInit(XScuGic *IntcInstancePtr, XScuTimer *TimerInstancePtr, uint32_t TimerIntrId, void(* CallBack)(void *))
{int Status;XScuGic_Config *IntcConfig;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;}Xil_ExceptionInit();Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,IntcInstancePtr);Xil_ExceptionEnable();Status = XScuGic_Connect(IntcInstancePtr, TimerIntrId,(Xil_ExceptionHandler)CallBack, (void *)TimerInstancePtr);if (Status != XST_SUCCESS) {return Status;}XScuGic_Enable(IntcInstancePtr, TimerIntrId);XScuTimer_EnableInterrupt(TimerInstancePtr);return XST_SUCCESS;
}
  • timer.h
/*** Copyright (c) 2022-2023,HelloAlpha* * Change Logs:* Date           Author       Notes*/
#ifndef __TIMER_H__
#define __TIMER_H__#include "xscutimer.h"
#include "xscugic.h"/* CPU时钟频率 */
#ifndef CPU_CLK_FREQ_HZ
#define CPU_CLK_FREQ_HZ     XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ
#endif/* 私有定时器的时钟频率 = CPU时钟频率/2 = 333MHz */
#define TIMER_HZ            CPU_CLK_FREQ_HZ/2#ifndef INTC_DEVICE_ID
#define INTC_DEVICE_ID      XPAR_SCUGIC_SINGLE_DEVICE_ID
#endif#define TIMER_DEVICE_ID     XPAR_XSCUTIMER_0_DEVICE_ID
#define TIMER_IRPT_INTR     XPAR_SCUTIMER_INTR/** Function declaration*/
int TimerInit(XScuTimer *TimerInstancePtr, uint16_t TimerDeviceId, uint32_t TimerLoadValue);
int TimerIntrInit(XScuGic *IntcInstancePtr, XScuTimer *TimerInstancePtr, uint32_t TimerIntrId, void(* CallBack)(void *));#endif

应用示例

  • app_timer.c
/*** Copyright (c) 2022-2023,HelloAlpha* * Change Logs:* Date           Author       Notes*/
#include "app_timer.h"#define USING_ULOG
#include "ulog.h"extern XScuGic IntcInstPtr;/*** @brief 定时器中断处理,中断时间 50ms*/
void TimerIntrHandler(void *CallBackRef)
{XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef;struct timer_flag *_timer_flag = &g_timer_flag;static uint16_t count = 0;/* 标志位触发 */
//	XScuTimer_IsExpired(TimerInstancePtr);ULOG("--- timer handle --- \r\n");count++;if(count == 101){count = 0;}ULOG("count: %d\r\n", count);_timer_flag->timer_flag_50ms = 1;if(count % 10 == 0){_timer_flag->timer_flag_500ms = 1;ULOG("--- 500 MS --- \r\n");}if(count % 20 == 0){_timer_flag->timer_flag_1s = 1;ULOG("---  1 S --- \r\n");}XScuTimer_ClearInterruptStatus(TimerInstancePtr);/* 关闭自动重装载值 关闭中断 */// XScuTimer_DisableAutoReload(TimerInstancePtr);
}int app_timer_init(void)
{int Status;Status = TimerInit(&Timer, TIMER_DEVICE_ID, TIMER_LOAD_VALUE);if (Status != XST_SUCCESS) {return XST_FAILURE;}Status = TimerIntrInit(&IntcInstPtr, &Timer, TIMER_IRPT_INTR, TimerIntrHandler);if (Status != XST_SUCCESS) {return XST_FAILURE;}XScuTimer_Start(&Timer);return Status;
}
  • app_timer.h
/*** Copyright (c) 2022-2023,HelloAlpha* * Change Logs:* Date           Author       Notes*/
#ifndef __APP_TIMER_H__
#define __APP_TIMER_H__#include "timer.h"/* CPU时钟频率 */
#ifndef CPU_CLK_FREQ_HZ
#define CPU_CLK_FREQ_HZ 	XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ
#endif/* 私有定时器的时钟频率 = CPU时钟频率/2 = 333MHz */
#define TIMER_HZ 			CPU_CLK_FREQ_HZ/2/** 精确计算 装载值 = 定时时间(单位:秒)* 333333333* 0.5s 166,666,666.5 0x9EF21AA* 0.1s  333,333,33.3 0x1FCA055* 0.05s 16,666,666,65 0xFE502A*/
#define TIMER_LOAD_VALUE 0xFE502AXScuTimer Timer;struct timer_flag
{char timer_flag_50ms;char timer_flag_500ms;char timer_flag_1s;
};typedef struct timer_flag timer_flag_t;timer_flag_t g_timer_flag;int app_timer_init(void);#endif

测试平台:黑金 AC7Z035B

芯片型号:XC7Z035-2FFG676

参考来源:UG585


http://chatgpt.dhexx.cn/article/d85W7Sc1.shtml

相关文章

ZYNQ开发系列——使用AXI4LITE接口进行PS和PL交互

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 ZYNQ开发系列——使用AXI4LITE接口进行PS和PL交互 前言PS端AXI接口AXI4LITE slave模块的设计后记前言 前面我们讲到使用AXI4LITE来作为总线接口来实现PS和PL的交互。同时我们为了支持《从零开始研发GPS接收…

Xilinx ZYNQ简介

ZYNQ 是赛灵思公司(Xilinx)推出的新一代全可编程片上系统(APSoC),它将处理器的软件可编程性与 FPGA 的硬件可编程性进行完美整合,以提供无与伦比的系统性能、灵活性与可扩展性。与传统 SoC解决方案不同的是…

ZYNQ ARM核之SCU

Snoop Control Unit,窥探控制单元,详情见UG585。SCU主要是解决ARM的L1和L2的缓存协调(因为两个processor的缓存是共用的)和AXI总线的ACP存取的,也就是DMA等高速中断需求的外设。 SCU 块将两个 Cortex-A9 处理器连接到内存子系统,并包含智能管…

ZYNQ开发系列——PS开发之HelloWorld

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 ZYNQ开发系列——PS开发之HelloWorld 前言外设接口SDK建立工程相关操作记录前言 俗话说一日不见,如隔三秋。两年没搞PS的开发,居然连HelloWorld怎么出来都不记得了,可见知识记录的重要性,知识真的是有保…

ZYNQ开发系列——PS响应PL中断请求

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 ZYNQ开发系列——PS响应PL中断请求 前言中断的设置PS部分代码前言 PS和PL的交互中,还有一个中断没有讲到,在《从零开始研发GPS接收机连载》中,将会有两个中断,一个中断是505us中断,一个中断是10ms中断…

ZYNQ PS简介

ZYNQ 实际上是一个以处理器为核心的系统,PL 只是它的一个外设。Zynq-7000 系列的亮点在于它包含了完整的 ARM 处理器系统,且处理器系统中集成了内存控制器和大量的外设,使 Cortex-A9 处理器可以完全独立于可编程逻辑单元。而且实际上在 ZYNQ …

Zynq-7000 AMP运行模式下的软件切换及多版本固化运行

Zynq平台AMP运行模式下的软件切换及多版本固化运行 1. Zynq双裸核AMP运行环境构建 1 1.1 Zynq架构概要 1 1.2 Zynq启动与配置 2 1.2.1 启动流程概述 3 1.2.2 PS硬件启动阶段 3 1.2.3 PS软件启动阶段 4 1.2.4 启动文件构成 4 1.2.5 启动模式 4 1.2.6 BootROM的执行 5 1.2.7 FSB…

ZYNQ-定时器中断使用

学习内容 本文首先介绍了ZYNQ的定时器的相关内容,并学习使用ZYNQ芯片中的定时器进行操作测试。 开发环境 vivado 18.3&SDK,PYNQ-Z2开发板。 定时器简介 介绍 ZYNQ有两个Cortex-A9处理器,每个Cortex-A9处理器都有自己的专用32位计时…

zynq-1

https://www.youtube.com/watch?vVs0h0kue7p4&listPL4D6H9w4Ihdp0YRExoQXfbVMRL1GgEPCm

zynq7000 中断原理分析及IO中断解析

Zynq 7000 中断分析 文章目录 Zynq 7000 中断分析GIC及中断机理Crotex-A9常用汇编指令Zynq中断控制 GPIO中断控制单IP双通道单IP多位双IP中断源 GIC及中断机理 Crotex-A9常用汇编指令 类型指令描述备注内部数据传输指令MOV R0 R1R1 2 R0#0xFF:立即数:MOV R0, #0xF…

ZYNQ之FPGA 片内RAM读写测试实验

文章目录 前言一、添加RAM IP核二、编写测试程序三、添加ILA四、分配管脚五、Simulator仿真六、硬件调试总结 前言 本实验的主要内容是介绍如何使用 FPGA内部的RAM以及程序对该RAM数据的读写操作。Vivado软件中提供了RAM的IP核 , 我们只需通过IP核例化一个RAM,根据…

ZYNQ-XADC使用

学习内容 本文首先介绍了ZYNQ的XADC的相关内容,并学习使用ZYNQ芯片中的XADC测量芯片内部的温度电压等参数,然后进行串口打印输出。 开发环境 vivado 18.3&SDK,PYNQ-Z2开发板。 XADC介绍 简介 Xilinx模拟信号转换模块,称…

ZYNQ SDK开发调试踩坑指南

关注星标公众号,及时获取更多技术分享~ 作者 | 冰茶奥利奥 微信公众号 | 嵌入式电子创客街 目录 坑1:裸机Ps串口收数问题 坑2:多个中断不能同时使用问题 坑3:block design中DDR3的选择 坑4:新板子能够检测到芯片&…

万变不离其宗之ZYNQ启动介绍

1、概述 ZYNQ 的详细介绍参考 XILINX 官方文档 UG585,在了解了 ZYNQ 的基本架构组成和丰富的资源后,下一步便是分析他的启动流程,以便更好的认识 ZYNQ 并开始开发工作; 关于 ZYNQ 启动方面的描述,这里我觉得涉及到几个…

ZYNQ入门

目录 一、ZYNQ简介 二、vivado工程 ①创建工程 ②添加设计文件 ③生产顶层HDL模块 ④生成 Bitstream 文件并导 三、vitis工程 ①启动vitis ②创建工程 ③编译与下载 一、ZYNQ简介 ZYNQ 是赛灵思公司(Xilinx)推出的新一代全可编程片上系统&#x…

ZYNQ架构

ZYNQ 首先,我们来了解传统的SOC架构,一般使用 ARM 作为主控,通过 ARM 的外设并行 RAM 类总线外挂 FPGA ,使用 FPGA 来做高速的数据采集或者运算,因为FPGA 有灵活性好,资源丰富,可反复编程&#…

zynqmp soc 移植vxWorks 7

1.使用worksbench4创建vsb工程; 2.使用worksbench4创建vip工程; 3.修改设备树文件,根据硬件电路选择对应的UART; 4.tftp引导启动;

ZYNQ开发系列——ZYNQ系统的搭建

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 ZYNQ开发系列——ZYNQ系统的搭建 DDR设置FLASH设置UART设置网口设置当我们有一个要用ZYNQ做的项目时,首先当然是把其最小系统搭建起来。这个最小系统可以交付给开发PS的同事开发裸机程序/RTOS实时操作系统/…

ZYNQ之高速AD/DA验证实验

文章目录 前言一、ADDA模块介绍二、添加ROM IP核三、添加ILA IP核四、编写测试程序五、管脚分配六、连接开发板测试总结 前言 本实验是高速AD/DA验证实验,将使用高速DA芯片实现数模转换,产生正弦波模拟电压信号,并通过高速AD芯片将模拟信号转…

ZYNQ - 嵌入式Linux开发 -10- ZYNQ启动流程分析

FSBL启动准备工作 在静态情况下,Boot.BIN启动文件存放在SD卡或QSPI等存储介质中,然后Boot.BIN文件中已经包含了FSBL代码,也就是说FSBL代码已经集成在了Boot.BIN文件中,所以FSBL代码也是存放在Boot .BIN文件中。 如果要启动FSBL代…