ZYNQ-定时器中断使用

article/2025/9/24 18:51:39

学习内容

本文首先介绍了ZYNQ的定时器的相关内容,并学习使用ZYNQ芯片中的定时器进行操作测试。

开发环境

vivado 18.3&SDK,PYNQ-Z2开发板。

定时器简介

介绍

ZYNQ有两个Cortex-A9处理器,每个Cortex-A9处理器都有自己的专用32位计时器和32位看门狗计时器。 两个都处理器共享一个全局64位计时器。 这些计时器始终以1/2的CPU频率计时(CPU_3x2x)。
在系统层级,有一个24位看门狗定时器和两个16位三重定时器/计数器。系统看门狗定时器的时钟频率为CPU频率(CPU_1x)的1/4或1/6,时钟也可以由来自MIO引脚或PL的外部信号。两个三重计时器/计数器时钟频率为在CPU频率(CPU_1x)的1/4或1/6,可以用于计算来自MIO引脚或来自PL的脉冲宽度。

系统框图

下图为ZYNQ内部的定时器的系统框图。
在这里插入图片描述
在图中显示,定时器部分包括系统看门狗、CPU内部的看门狗定时器,CPU私有的定时器,全局定时器,三重定时器。其中所有的定时器都可以触发中断控制器进行中断控制的操作,看门狗定时器(无论是系统 的还是CPU内部的)都可以对系统进行一个复位操作。

CPU私有定时器和看门狗定时器

关于CPU私有定时器和看门狗定时器均具有以下功能:

  1. 32位计数器,在达到零时会产生中断
  2. 八位预分频器,可以更好地控制中断周期
  3. 可配置的单次或自动重装模式
  4. 计数器的可配置起始值
  5. 定时器和看门狗复位信号发送到PS复位子系统
  6. 所有私有计时器和看门狗计时器始终以CPU频率(CPU_3x2x)的1/2计时。

下图为CPU私有定时器和看门狗定时器寄存器表:
在这里插入图片描述
在这里插入图片描述

全局定时器(GT)

全局定时器是具有自动递增功能的64位递增计数器。 全局计时器在与专用计时器相同的地址空间中映射到内存中。 全局计时器仅在复位时以安全状态访问。 所有Cortex-A9处理器均可访问全局计时器。 每个Cortex-A9处理器都有一个64位比较器,用于在全局计时器达到比较器值时声明一个私有中断。全局定时器始终以CPU频率(CPU_3x2x)的1/2计时。
全局定时器(GT)寄存器功能表如下图:
在这里插入图片描述

系统看门狗定时器(SWDT)

除了两个CPU私有看门狗定时器之外,还有一个系统看门狗定时器(SWDT),可以在系统发生故障时,如PS PLL锁相失败,此时看门狗可以产生一个复位信号让程序重启,从而保证系统正常运行。 与CPU私有看门狗定时器不同的是,SWDT的时钟可以来自于外部设备或者PL端,用于提供一个复位信号输出到PL端口或者外部设备。

特征

SWDT的主要功能如下:

  1. 内部24位计数器。
  2. 可选时钟输入,时钟信号可以来自:1. 内部PS总线时钟(CPU_1x);2. 内部时钟(来自PL);3. 外部时钟(来自MIO)。
  3. 计时超时时,可以进行系统中断(PS)和系统重置(PS,PL,MIO)。
  4. 可编程超时时间:1. 超时范围32,760至68,719,476,736个时钟周期(在100 MHz时可配置范围为330 µs至687.2s)。
  5. 超时时,可编程的输出信号持续时间:系统中断脉冲(4、8、16或32个时钟周期(CPU_1x时钟))。

系统看门狗定时器寄存器功能表如图:
在这里插入图片描述

编程指南

系统看门狗定时器使能顺序如下:

  1. 使用slcr.WDT_CLK_SEL [SEL]位选择时钟输入源 :确保禁用SWDT(swdt.MODE [WDEN] = 0),并且将时钟输入源设置为选定的正在运行,然后继续此步骤。 更改时钟输入源时,启用SWDT会导致无法预测的行为。 时钟输入源更改为非运行时钟导致APB访问挂起。
  2. 设置超时时间(计数器控制寄存器) :swdt.CONTROL [CKEY]字段必须为0x248,才能写入此寄存器。
  3. 启用计数器; 使能输出脉冲 ; 设置输出脉冲长度(零模式寄存器):swdt.MODE [ZKEY]字段必须为0xABC,才能写入此寄存器。 确保IRQLN符合指定的最小值。
  4. 要使用其他设置运行SWDT,请首先禁用定时器(swdt.MODE [ZKEY]位)。 然后重复上述步骤。

三重计时器(TTC)

TTC包含三个独立的计时器/计数器。 PS端中有两个TTC模块,总共六个计时器/计数器。 可以使用 nic301_addr_region_ctrl_registers.security_apb [ttc1_apb]寄存器位将TTC 1控制器配置为安全或非安全模式。 TTC控制器中的三个计时器具有相同的安全状态。

特征

每个三重计时器/计数器都具有以下特征:

  1. 三个独立的16位预分频器和16位向上/向下计数器。
  2. 可选时钟输入,来自:1. 内部PS总线时钟(CPU_1x);2. 内部时钟(来自PL);3. 外部时钟(来自MIO)。
    •每个计数器有一个中断。
    •可以产生溢出中断,定时中断或计数中断,可编程初始值。
    •可以生成通过MIO到PL的波形输出(例如PWM)。

三重计时器/计数器寄存器功能表如图:
在这里插入图片描述
在这里插入图片描述

计数器编程启用顺序

  1. 选择时钟输入源,设置预分频值。(slcr.MIO_MUX_SEL寄存器,TTC时钟控制)在继续执行此操作之前,请确保已禁用TTC(ttc.Counter_Control_x [DIS] = 1)。
  2. 设置间隔值(间隔寄存器)。 此步仅适用于间隔模式。(可选不配置)
  3. 设置匹配值(匹配寄存器)。 如果要启用匹配,可以配置此操作。(可选不配置)
  4. **使能中断(中断使能寄存器)。**如果要启用中断,可以配置此操作。(可选不配置)
  5. 启用/禁用波形输出,启用/禁用匹配,设置计数方向,设置模式,使能计数器(TTC计数器控制寄存器)。 此步骤完成后将启动计数器。

计数器编程停止顺序

  1. 读回计数器控制寄存器的值。
  2. 将DIS位设置为1,同时保留其他位。
  3. 写回计数器控制寄存器。

计数器编程重启顺序

  1. 读回计数器控制寄存器的值。
  2. 将RST位设置为1,同时保留其他位。
  3. 写回计数器控制寄存器。

事件计时器启用序列

  1. 选择外部脉冲源(slcr.MIO_MUX_SEL寄存器)。选定外部待测脉冲。
  2. 设置溢出处理,选择外部脉冲电平,启用事件计时器(事件控制计时器寄存器)。 此步骤开始测量外部所选电平(高或低)的宽度脉冲。
  3. 使能中断(中断使能寄存器)。 如果要启用中断,可以配置此操作。(可选不配置)
  4. 读取测量的宽度(事件寄存器)。

中断清除和应答序列

  1. 读取中断寄存器:读取时清除中断寄存器中的所有位。

系统框图

本次工程系统框图如下图所示。
在这里插入图片描述
调用UART、TIMER、GPIO资源进行开发设计,UART串口引脚直接连接到MIO,GPIO引脚连接到PL端的EMIO引脚,由ARM核进行配置定时器中断操作,实现定时中断进行流水灯操作。

硬件平台搭建

新建工程,创建 block design。添加ZYNQ7 ip,根据本次工程需要对IP进行配置。勾选本次工程使用的资源。
在这里插入图片描述
硬件系统构建完成如下:

在这里插入图片描述
然后我们进行generate output product 然后生成HDL封装。这里用到了UART和GPIO,所以需要进行管脚分配。这里使用的是PYNQZ2开发板,该板卡可直接引用以下约束文件:

#LEDs
set_property -dict { PACKAGE_PIN R14   IOSTANDARD LVCMOS33 } [get_ports { EMIO_LED_tri_io[0] }]; #IO_L6N_T0_VREF_34 Sch=led[0]
set_property -dict { PACKAGE_PIN P14   IOSTANDARD LVCMOS33 } [get_ports { EMIO_LED_tri_io[1] }]; #IO_L6P_T0_34 Sch=led[1]
set_property -dict { PACKAGE_PIN N16   IOSTANDARD LVCMOS33 } [get_ports { EMIO_LED_tri_io[2] }]; #IO_L21N_T3_DQS_AD14N_35 Sch=led[2]
set_property -dict { PACKAGE_PIN M14   IOSTANDARD LVCMOS33 } [get_ports { EMIO_LED_tri_io[3] }]; #IO_L23P_T3_35 Sch=led[3]

完成约束后,进行综合和布局布线,生成bit流,然后点击导出硬件资源(包含bit流文件),接着launch SDK。

SDK软件部分

打开SDK后,新建application project。
在system.mss中可以打开相关参考文档辅助设计。
在这里插入图片描述
可以选择timer中断的例程进行参考设计,导入uart_intr_example例程模板,
在这里插入图片描述
在main.c中输入以下代码:

#include <stdio.h>
#include "xparameters.h"
#include "xscutimer.h"
#include "xscugic.h"
#include "xgpiops.h"
#include "xil_exception.h"
#include "xil_printf.h"
//声明定义
#define GPIO_ID             XPAR_PS7_GPIO_0_DEVICE_ID
#define TIMER_ID            XPAR_PS7_SCUTIMER_0_DEVICE_ID
#define INTR_DEVICE_ID      XPAR_SCUGIC_SINGLE_DEVICE_ID
#define TIMER_IRPT_INTR		XPAR_SCUTIMER_INTR#define LOAD_VALUE 0X9AF8D9F//0.5s流水 系统时钟650M  定时器时钟325M 周期3ns#define LED0 54
#define LED1 55
#define LED2 56
#define LED3 57//声明示例结构体
XGpioPs GpioPs;
XScuTimer Timer;
XScuGic ScuGic;//函数定义
void Emio_init();
void Timer_init();
void Timer_intr_init(XScuGic *intr, XScuTimer *time);
void Timer_IntrHandler(void *CallBackRef);
int main(){//EMIO初始化Emio_init();//初始化定时器Timer_init();//初始化中断Timer_intr_init(&ScuGic,&Timer);//启动定时器XScuTimer_Start(&Timer);while(1);return 0;
}void Emio_init(){XGpioPs_Config *XGpioPs_Cfg;XGpioPs_Cfg = XGpioPs_LookupConfig(GPIO_ID);XGpioPs_CfgInitialize(&GpioPs,XGpioPs_Cfg,XGpioPs_Cfg->BaseAddr);XGpioPs_SetDirectionPin(&GpioPs,LED0,0x01);XGpioPs_SetOutputEnablePin(&GpioPs,LED0,0x01);XGpioPs_SetDirectionPin(&GpioPs,LED1,0x01);XGpioPs_SetOutputEnablePin(&GpioPs,LED1,0x01);XGpioPs_SetDirectionPin(&GpioPs,LED2,0x01);XGpioPs_SetOutputEnablePin(&GpioPs,LED2,0x01);XGpioPs_SetDirectionPin(&GpioPs,LED3,0x01);XGpioPs_SetOutputEnablePin(&GpioPs,LED3,0x01);
}void Timer_init(){int Status;XScuTimer_Config *ConfigPtr;//初始化定时器ConfigPtr = XScuTimer_LookupConfig(TIMER_ID);XScuTimer_CfgInitialize(&Timer, ConfigPtr,ConfigPtr->BaseAddr);//定时器自检测Status = XScuTimer_SelfTest(&Timer);if (Status != XST_SUCCESS) {printf("timer selftest failed!\n");}printf("timer selftest success!\n");//装载初值XScuTimer_LoadTimer(&Timer, LOAD_VALUE);//使能自动装载模式XScuTimer_EnableAutoReload(&Timer);
}void Timer_intr_init(XScuGic *intr, XScuTimer *time){XScuGic_Config *IntcConfig;//初始化定时器中断IntcConfig = XScuGic_LookupConfig(INTR_DEVICE_ID);XScuGic_CfgInitialize(intr,IntcConfig,IntcConfig->CpuBaseAddress);//初始化中断异常函数Xil_ExceptionInit();Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,intr);Xil_ExceptionEnable();//设置中断服务函数XScuGic_Connect(intr, TIMER_IRPT_INTR,(Xil_ExceptionHandler)Timer_IntrHandler,(void *)time);//使能中断控制器XScuGic_Enable(intr, TIMER_IRPT_INTR);//使能定时器XScuTimer_EnableInterrupt(time);}
//中断处理函数
void Timer_IntrHandler(void *CallBackRef){static char led_status=0x01;XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef;if(XScuTimer_IsExpired(TimerInstancePtr)){led_status = led_status<<1;if(led_status == 0X10)led_status =0x01;XGpioPs_WritePin(&GpioPs,LED0,led_status);XGpioPs_WritePin(&GpioPs,LED1,led_status>>1);XGpioPs_WritePin(&GpioPs,LED2,led_status>>2);XGpioPs_WritePin(&GpioPs,LED3,led_status>>3);XScuTimer_ClearInterruptStatus(TimerInstancePtr);}
}

部分代码讲解

在主函数中引用了Emio_init();Timer_init();Timer_intr_init(&ScuGic,&Timer);
分别完成初始化GPIO操作,初始化定时器,初始化中断定时器等操作。最后用XScuTimer_Start(&Timer);启动定时器。

对于定时器初始化设置主要要对计数模式进行设置,对初始值进行装载配置
也就是调用下面的函数:

	//装载初值XScuTimer_LoadTimer(&Timer, LOAD_VALUE);//使能自动装载模式XScuTimer_EnableAutoReload(&Timer);

这里LOAD_VALUE表示需要计时或者计数的次数,因为这里的代码实现的是led的0.5s定时中断,系统CPU时钟为650M,所以定时器的时钟频率为325M,也就是周期为3.07ns,计算0.5s下的计数次数得到这里需要装载的初值。(也即为0X9AF8D9F)

Reference

  1. UG585
  2. 正点原子ZYNQ开发视频

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

相关文章

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&#xff1a;立即数:MOV R0, #0xF…

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

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

ZYNQ-XADC使用

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

ZYNQ SDK开发调试踩坑指南

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

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

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

ZYNQ入门

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

ZYNQ架构

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

zynqmp soc 移植vxWorks 7

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

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

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

ZYNQ之高速AD/DA验证实验

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

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

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

初识ZYNQ结构

本文介绍了zynq的结构&#xff0c;简述了PS中的APU。 处理器系统 所有的 Zynq 芯片都有相同的基本架构。作为处理器系统的基础&#xff0c;所有的芯片都包含了一颗双核 ARM Cortex-A9 处理器。这是一颗 “ 硬 ” 处理器 —— 它是芯片上专用而且优化过的硅片元件。 作为比较…

zynq中断

在zynq中选择中断信号后&#xff1a; 只能看到一个[0:0]的向量&#xff0c;完全无法对应中断号&#xff1a; 且属性栏目没有配置选项&#xff0c;一般可以看到有些连接图如下&#xff1a; 如果看成最低位的话就是61,那么其它中断号怎么使用呢&#xff1a;查到的资料如下&#x…

ZYNQ基础知识

1.ZYNQ介绍 全称为Zynq-7000 All Programmable Soc 1.Zynq是赛灵思&#xff08;Xilinx&#xff09;推出的新一代全可编程片上系统&#xff0c;将处理器的软件可编程性和FPGA的硬件可编程性完美结合。具有较强的系统性能、灵活性与可扩展性。 2.旨在为视频监控、汽车驾驶员辅助…

一、ZYNQ简介

1 ZYNQ简介 &#xff08;1&#xff09;ZYNQ简介 ​ ZYNQ全称Zynq-7000 All Programmable SoC&#xff0c;是赛灵思公司&#xff08;Xilinx&#xff09;推出的新一代全可编程片上系统&#xff08;&#xff08;APSoC&#xff09;&#xff08;全可编程指的是硬件和软件都可以编程…

ZYNQ简介

目录 1.ZYNQ简介 2.片上系统&#xff0c;板上系统&#xff0c;可编程片上系统&#xff0c;全可编程上系统 &#xff08;1&#xff09;板上系统 &#xff08;2&#xff09;片上系统&#xff08;SOC&#xff09; &#xff08;3&#xff09;可编程片上系统&#xff08;SOPC&a…

【ZYNQ】从入门到秃头01 初识ZYNQ(PS和PL之间连接)

文章目录 从嵌入式Linux到ZYNQZYNQ简介PL简介常用的可编程逻辑器件&#xff1a;PL结构 PS简介AXIAXI4 StreamAXI4 ZYNQ芯片开发流程的简介学习ZYNQ要具备哪些技能 从嵌入式Linux到ZYNQ 之前的学习领域一直是ARM&#xff0c;从STM32到NXP iMX6&#xff0c; 从裸机开发到Linux操…

css-输入框和文本域样式调整

输入框去掉选中后的边框变化效果 选中后边框变化&#xff1a; 去掉变化效果方法&#xff1a;添加css属性- - - outline: none; 文本域去掉右下角拖拽图样 默认文本域右下角有个拖拽的图样&#xff0c;将鼠标移动到右下角可以进行拖拽实现放大缩小&#xff1a; 代码示例&#x…

HTML5-列表框、文本域和文件域

<!--下拉框&#xff0c;列表框selected 默认选择--><p>国家&#xff1a;<select name"列表名称" ><option value"china">中国</option><option value"us">美国</option><option value"eth&qu…