第十三章 ZYNQ-MIZ701 TIMER定时器中断
上篇文章实现了了PS接受来自PL的中断,本片文章将在ZYNQ的纯PS里实现私有定时器中断。每隔一秒中断一次,在中断函数里计数加1,通过串口打印输出。
本文所使用的开发板是Miz701 PC 开发环境版本:Vivado 2015.4 Xilinx SDK 2015.4
13.0本章难度系数★★☆☆☆☆☆
13.1中断原理
中断对于保证任务的实时性非常必要,在ZYNQ里集成了中断控制器GIC(Generic Interrupt Controller).GIC可以接受I/O外设中断IOP和PL中断,将这些中断发给CPU。
中断体系结构框图图下: 
13.1.1软件中断(SGI)
SGI通过写ICDSGIR寄存器产生SGI.
13.1.2共享中断SPI
通过PS和PL内各种I/O和存储器控制器产生。
13.1.3私有中断(PPI)
包含:全局定时器,私有看门狗定时器,私有定时器以及来自PL的FIQ/IRQ。本文主要介绍PPI,其它的请参考官方手册ug585_Zynq_7000_TRM.pdf。
ZYNQ每个CPU链接5个私有外设中断,所有中断的触发类型都是固定不变的。并且来自PL的快速中断信号FIQ和中断信号IRQ反向,然后送到中断控制器因此尽管在ICDICFR1寄存器内反应的他们是低电平触发,但是PS-PL接口中为高电平触发。如图所示: 
13.1.4私有定时器
zynq中每个ARM core都有自己的私有定时器,私有定时器的工作频率为CPU的一半,比如Miz701的ARM工作频率为650MHZ,则私有定时器的频率为325MHz.
私有定时器的特性如下:
(1)32位计数器,达到零时产生一个中断
(2)8位预分频计数器,可以更好的控制中断周期
(3)可配置一次性或者自动重加载模式
(4)定时器时间可以通过下式计算:
定时时间 = [(预分频器的值 + 1) (加载值 + 1)]/定时器频率
13.2 搭建硬件工程
Step1:新建一个名为为Miz701_sys的工程

Step2:选择RTL Project 勾选Do not specify source at this time

Step3:选择xc7z010clg400-1作为开发器件。

Step4:单击Finish

13.3使用IP Integrator创建硬件系统
Step1:单击Create Block Design
Step2:输入system

Step3:单击下图中
添加IP按钮

Step4:搜素单词z选择ZYNQ7 Processing System,然后双击

Step5:添加进来了ZYNQ CPU IP,然后单击双击对其进行配置。

Step6:修改输入频率为50MHZ,PL端频率为100MHZ。

Step7:修改内存类型为MT41K256M16 RE-125。

Step8:在Mio configuration选项中,勾选添加UART1接口,单击OK完成配置。

Step9:单击Run Block Automation进行智能布线。

Step10:直接单击OK

Step11:在你点击了OK后,你会发现DDR以及FICED_IO自动的延伸出来。

Step12:连线的作用就是把PS的时钟可以接入PL部分,当然这里我们暂时用不到PL部分的资源。在Block文件中,我们进行连线,将鼠标放在引脚处,鼠标变成铅笔后迚行拖拽,连线如下图所示:

Step13: 右击 system.bd, 单击Generate Output Products

Step14:支部操作会产生执行、仿真、综合的文件

Step15:右击system.bd 选择 Create HDL Wrapper 这步的作用是产生顶层的HDL文件

Step16:选择Leave Let Vivado manager wrapper and auto-update 然后单击OK
Step17:执行->产生bit文件
13.4导出SOC硬件到SDK
Step1:File->Export->Export Hardware

Step2:勾选Include bitstream 直接单击OK

Step3:File->Launch SDK加载到SDK

Step4:单击OK

13.5 建立软件工程
建立一个TIMER_INTC空的工程,并且添加main.c 添加如下代码
|
#include <stdio.h> #include "xadcps.h" #include "xil_types.h" #include "Xscugic.h" #include "Xil_exception.h" #include "xscutimer.h" //timer info #define TIMER_DEVICE_ID XPAR_XSCUTIMER_0_DEVICE_ID #define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID #define TIMER_IRPT_INTR XPAR_SCUTIMER_INTR //#define TIMER_LOAD_VALUE 0x0FFFFFFF #define TIMER_LOAD_VALUE 0x13D92D3F //static XAdcPs XADCMonInst; //XADC static XScuGic Intc; //GIC static XScuTimer Timer;//timer static void SetupInterruptSystem(XScuGic *GicInstancePtr, XScuTimer *TimerInstancePtr, u16 TimerIntrId); static void TimerIntrHandler(void *CallBackRef); int main() { XScuTimer_Config *TMRConfigPtr; //timer config printf("------------START-------------\n"); // init_platform(); // //私有定时器初始化 TMRConfigPtr = XScuTimer_LookupConfig(TIMER_DEVICE_ID); XScuTimer_CfgInitialize(&Timer, TMRConfigPtr,TMRConfigPtr->BaseAddr); XScuTimer_SelfTest(&Timer); //加载计数周期,私有定时器的时钟为CPU的一般,为333MHZ,如果计数1S,加载值为1sx(333x1000x1000)(1/s)-1=0x13D92D3F XScuTimer_LoadTimer(&Timer, TIMER_LOAD_VALUE); //自动装载 XScuTimer_EnableAutoReload(&Timer); //启动定时器 XScuTimer_Start(&Timer); //set up the interrupts SetupInterruptSystem(&Intc,&Timer,TIMER_IRPT_INTR); while(1){ } return 0; } void SetupInterruptSystem(XScuGic *GicInstancePtr, XScuTimer *TimerInstancePtr, u16 TimerIntrId) { XScuGic_Config *IntcConfig; //GIC config Xil_ExceptionInit(); //initialise the GIC IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID); XScuGic_CfgInitialize(GicInstancePtr, IntcConfig, IntcConfig->CpuBaseAddress); //connect to the hardware Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, GicInstancePtr); //set up the timer interrupt XScuGic_Connect(GicInstancePtr, TimerIntrId, (Xil_ExceptionHandler)TimerIntrHandler, (void *)TimerInstancePtr); //enable the interrupt for the Timer at GIC XScuGic_Enable(GicInstancePtr, TimerIntrId); //enable interrupt on the timer XScuTimer_EnableInterrupt(TimerInstancePtr); // Enable interrupts in the Processor. Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ); } static void TimerIntrHandler(void *CallBackRef) { static int sec = 0; //计数 XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef; XScuTimer_ClearInterruptStatus(TimerInstancePtr); sec++; printf(" %d Second\n\r",sec); //每秒打印输出一次 } |
13.6测试结果
可以看到串口终端每秒输出一次,并且值加1递增。
13.7本章小结
中断对于实时系统是非常重要的,可以说是是实时性的保障吧。本章简要介绍了ZYNQ的中断原理和中断类型,详细介绍了私有定时器,建立了完整的工程进行测试。
官网论坛:www.osrc.cn
源码链接:http://pan.baidu.com/s/1skC582T 密码:eyhp
第十三章 ZYNQ-MIZ701 TIMER定时器中断的更多相关文章
- 灵动微电子ARM Cortex M0 MM32F0010 Timer定时器中断定时功能的配置
灵动微电子ARM Cortex M0 MM32F0010 Timer定时器中断定时功能的配置 目录: 1.Timer1高级定时器Timer3通用定时器Timer14基本定时器简介 2.Timer1高级 ...
- 第十四章 ZYNQ TIMER定时器中断
上篇文章实现了了PS接受来自PL的中断,本片文章将在ZYNQ的纯PS里实现私有定时器中断.每隔一秒中断一次,在中断函数里计数加1,通过串口打印输出. 本文所使用的开发板是Miz702 PC 开发环 ...
- 79.ZYNQ内部私有定时器中断
上篇文章实现了了PS接受来自PL的中断,本片文章将在ZYNQ的纯PS里实现私有定时器中断.每个一秒中断一次,在中断函数里计数加1,通过串口打印输出. *本文所使用的开发板是Miz702(兼容zedbo ...
- ZYNQ入门实例——定时器中断与程序固化
一.前言 APU系统中CPU以串行执行代码的方式完成操作,软件方式很难做到精准计时,因此调用内部定时器硬件完成计时是更好的选择.本文以定时器中断方式控制LED周期性闪烁为例学习私有定时器的使用.同时学 ...
- 【TCP/IP详解 卷一:协议】第二十三章 TCP的保活定时器
本章介绍保活定时器. 在 TCP 的三握四挥 章节中,我们介绍了 处在 TIME_WAIT 的 2MSL定时器:在 TCP的超时与重传 章节中,我们介绍了 重传定时器:在上一章节中,我们介绍了 防止死 ...
- S02_CH08_ ZYNQ 定时器中断实验
S02_CH08_ ZYNQ 定时器中断实验 上一章实现了PS接受来自PL的中断,本章将在ZYNQ的纯PS里实现私有定时器中断.每隔一秒中断一次,在中断函数里计数加1,通过串口打印输出. 8.1中断原 ...
- STM32学习笔记——定时器中断(向原子哥学习)
定时器中断 STM32 的定时器功能十分强大,有 TIME1 和 TIME8 等高级定时器,也有 TIME2~TIME5 等通用定时器,还有 TIME6 和TIME7 等基本定时器.在本章中,我们将利 ...
- JZ2440 裸机驱动 第10章 系统时钟和定时器
本章目标 了解S3C2410/S3C2440的时钟体系结构 掌握通过设置MPLL改变系统时钟的方法 掌握在不同的频率下设置存储控制器的方法 掌握PWM定时器的用法 ...
- 4-MSP430定时器_定时器中断
一开始没写好就上传了,,,,,,,,这次来个全的 自己学MSP430是为了写一篇关于PID的文章,需要430在proteus上做仿真,一则认为在自动控制算法上PID真的很经典,PLC设备上大多是模块式 ...
随机推荐
- javascript--特权方法
在Javascript--闭包一节中我们讲解了闭包的作用域和作用域链的特性.了解到在外部一般是不可能访问到内部作用域中的变量的,然而通过闭包我们可以定义特权方法访问私有变量.下面先介绍块级作用域再介绍 ...
- linux java -jar
常见命令1 nohup java -jar /xxx/xxx/xxx.jar >/dev/>& & 分析各个指令代表什么意思: >,重写文件,如果文件里面有内容会覆盖 ...
- windows下安装mongodb数据库以及使用数据库
首先下载mongodb, 链接: https://pan.baidu.com/s/1KyvF7bAqGM8K-ir-hFNhPw 密码: vlc9 双击进行安装 勾选我接受并单击next 选择cust ...
- VScode优化记录
主题: One Dark Pro VS Code 官网页面 这是为 VS Code准备的 One Dark 主题,他是 Atom 标志性的主题.需要我说更多吗?我喜欢这个主题. Mon ...
- java中json的使用和解析
1.创建json对象 1.1 创建JSONObject对象 使用map初始化json @Test public void test1() { Map<String, Object> map ...
- Facebook币Libra学习-1.核心概念
Libra区块链是一个基于Libra协议的加密认证的分布式数据库.本文将简略介绍Libra协议的核心概念.其详细说明请参阅Libra技术白皮书. Libra区块链由分布式的Validator节点网络维 ...
- kotlin陪伴对象
在kotlin中并没有静态类成员的概念,但并不等于实现类似于静态类成员的功能,陪伴对象可以解决这个问题 fun main(arg: Array<String>) { val create ...
- ServletConfig对象的使用
作用: * 获取Servlet的配置信息 * 获取ServletContext对象 *主要是用于加载servlet的初始化参数.在一个web应用可以存在多个ServletConfig对象(一个Serv ...
- C++ STL partial_sort_copy greater
#include <iostream>#include <deque>#include <algorithm>#include <vector>#inc ...
- mysql一条语句实现插入或更新的操作
,),(,) ON DUPLICATE KEY UPDATE c=VALUES(c); 或者 INSERT INTO table (id,a,b,c) select id,a,b,c from xxx ...