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

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

Step3:由于Miz702兼容zedboard 因此选择zedboard开发包

Step4:单击Finish

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

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

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

Step5:添加进来了ZYNQ CPU IP,然后单击Run Block Automation

Step6:直接单击OK

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

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

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

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

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

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

Step2:勾选Include bitstream 直接单击OK

Step3:File->Launch SDK加载到SDK

Step4:单击OK

14.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); //每秒打印输出一次 } |
14.6测试结果
可以看到串口终端每秒输出一次,并且值加1递增。
14.7本章小结
中断对于实时系统是非常重要的,可以说是是实时性的保障吧。本章简要介绍了ZYNQ的中断原理和中断类型,详细介绍了私有定时器,建立了完整的工程进行测试。
官网论坛:www.osrc.cn
视频链接:http://www.osrc.cn/forum.php?mod=viewthread&tid=1104
源码链接:http://pan.baidu.com/s/1bAstrC 密码:wv3i
第十四章 ZYNQ TIMER定时器中断的更多相关文章
- 第十三章 ZYNQ-MIZ701 TIMER定时器中断
上篇文章实现了了PS接受来自PL的中断,本片文章将在ZYNQ的纯PS里实现私有定时器中断.每隔一秒中断一次,在中断函数里计数加1,通过串口打印输出. 本文所使用的开发板是Miz701 PC 开发环 ...
- 《Linux命令行与shell脚本编程大全》 第十四章 学习笔记
第十四章:呈现数据 理解输入与输出 标准文件描述符 文件描述符 缩写 描述 0 STDIN 标准输入 1 STDOUT 标准输出 2 STDERR 标准错误 1.STDIN 代表标准输入.对于终端界面 ...
- perl 第十四章 Perl5的包和模块
第十四章 Perl5的包和模块 by flamephoenix 一.require函数 1.require函数和子程序库 2.用require指定Perl版本二.包 1.包的定义 2.在包间切 ...
- Gradle 1.12 翻译——第十四章. 教程 - 杂七杂八
有关其它已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或訪问:http://gradledoc.qiniudn.com ...
- C和指针 (pointers on C)——第十四章:预处理器
第十四章 预处理器 我跳过了先进的指针主题的章节. 太多的技巧,太学科不适合今天的我.但我真的读,读懂.假设谁读了私下能够交流一下.有的小技巧还是非常有意思. 预处理器这一章的内容.大家肯定都用过.什 ...
- CSS3秘笈复习:十三章&十四章&十五章&十六章&十七章
第十三章 1.在使用浮动时,源代码的顺序非常重要.浮动元素的HTML必须处在要包围它的元素的HTML之前. 2.清楚浮动: (1).在外围div的底部添加一个清除元素:clear属性可以防止元素包围浮 ...
- JavaScript高级程序设计:第十四章
第十四章 一.表单的基础知识 在HTML中,表单是由<form>元素来表示的,而在javascript中,表单对应的则是HTMLFormElement类型.HTMLFormElement继 ...
- C#语言和SQL Server第十三 十四章笔记
十三章 使用ADO.NET访问数据库 十四章使用ADO.NET查询和操作数据库 十三章: ...
- Gradle 1.12用户指南翻译——第二十四章. Groovy 插件
其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...
随机推荐
- Robot Framework(十五) 扩展RobotFramework框架——远程库接口
4.2远程库接口 远程库接口提供了在运行Robot Framework本身的机器上运行测试库的方法,以及使用除本机支持的Python和Java之外的其他语言实现库的方法.对于测试库,用户远程库看起来与 ...
- Atcoder ABC 139C
Atcoder ABC 139C 题意: 有 $ n $ 个正方形,选择一个起始位置,使得从这个位置向右的小于等于这个正方形的高度的数量最多. 解法: 简单递推. CODE: #include< ...
- elasticsearch _all
在轻量搜索中,我们介绍了 _all 字段:一个把其它字段值 当作一个大字符串来索引的特殊字段. query_string 查询子句(搜索 ?q=john )在没有指定字段时默认使用 _all 字段._ ...
- JAVA基础知识|小知识点
1.强烈建议,不使用char类型 那么,到底为什么java里不推荐使用char类型呢?其实,1个java的char字符并不完全等于一个unicode的字符.char采用的UCS-2编码,是一种淘汰的U ...
- expdp / impdp 用法详解 ,和exp / imp 的区别
一 关于expdp和impdp 使用EXPDP和IMPDP时应该注意的事项:EXP和IMP是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用.EXPDP和IMPDP是服务端的工具程 ...
- Linux设备驱动程序 之 vmalloc
vmalloc()函数的工作方式类似于kmalloc(),只不过在前者分配的内存虚拟地址是连续的,而物理地址则无须连续:这也是用户空间分配函数的工作方式:由malloc()返回的页在进程的虚拟地址空间 ...
- Echarts 设置 图标 默认平铺 数据为零时绘画
好久没写了 最近接了一个统计的功能 以前写的都是一些最基础的统计 废话少说 我先把自己遇到的问题列出来 仅供参考 __________________我是分割线__________________ ...
- VUE组件如何通信
Vue父子组件如何通信? 子组件通知父组件(调用父组件方法) 在父组件使用 on(eventName)监听事件,在子组件使用emit(eventName) 触发事件 : 父组件通知子组件(调用子组件方 ...
- linux下如何交叉编译util-linux?
1. 获取源码 wget https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v2.34/util-linux-2.34.tar.xz ...
- vim 快捷键 清空文件所有内容
vim清空文件所有内容 在使用vim编辑器的时候,有时候编辑一个文件,而文件内容比较多,如果需要快速清空整个文件,可以使用一下命令: 在命令模式下,首先执行 gg 这里是跳至文件首行 再执行: dG ...