上篇文章实现了了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的中断原理和中断类型,详细介绍了私有定时器,建立了完整的工程进行测试。

淘宝店铺:https://osrc.taobao.com

官网论坛:www.osrc.cn

视频链接:http://www.osrc.cn/forum.php?mod=viewthread&tid=1104

源码链接:http://pan.baidu.com/s/1bAstrC 密码:wv3i

第十四章 ZYNQ TIMER定时器中断的更多相关文章

  1. 第十三章 ZYNQ-MIZ701 TIMER定时器中断

      上篇文章实现了了PS接受来自PL的中断,本片文章将在ZYNQ的纯PS里实现私有定时器中断.每隔一秒中断一次,在中断函数里计数加1,通过串口打印输出. 本文所使用的开发板是Miz701 PC 开发环 ...

  2. 《Linux命令行与shell脚本编程大全》 第十四章 学习笔记

    第十四章:呈现数据 理解输入与输出 标准文件描述符 文件描述符 缩写 描述 0 STDIN 标准输入 1 STDOUT 标准输出 2 STDERR 标准错误 1.STDIN 代表标准输入.对于终端界面 ...

  3. perl 第十四章 Perl5的包和模块

    第十四章 Perl5的包和模块 by flamephoenix 一.require函数  1.require函数和子程序库  2.用require指定Perl版本二.包  1.包的定义  2.在包间切 ...

  4. Gradle 1.12 翻译——第十四章. 教程 - 杂七杂八

    有关其它已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或訪问:http://gradledoc.qiniudn.com ...

  5. C和指针 (pointers on C)——第十四章:预处理器

    第十四章 预处理器 我跳过了先进的指针主题的章节. 太多的技巧,太学科不适合今天的我.但我真的读,读懂.假设谁读了私下能够交流一下.有的小技巧还是非常有意思. 预处理器这一章的内容.大家肯定都用过.什 ...

  6. CSS3秘笈复习:十三章&十四章&十五章&十六章&十七章

    第十三章 1.在使用浮动时,源代码的顺序非常重要.浮动元素的HTML必须处在要包围它的元素的HTML之前. 2.清楚浮动: (1).在外围div的底部添加一个清除元素:clear属性可以防止元素包围浮 ...

  7. JavaScript高级程序设计:第十四章

    第十四章 一.表单的基础知识 在HTML中,表单是由<form>元素来表示的,而在javascript中,表单对应的则是HTMLFormElement类型.HTMLFormElement继 ...

  8. C#语言和SQL Server第十三 十四章笔记

    十三章  使用ADO.NET访问数据库 十四章使用ADO.NET查询和操作数据库 十三章:                                                       ...

  9. Gradle 1.12用户指南翻译——第二十四章. Groovy 插件

    其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...

随机推荐

  1. 非旋treap

    目录 核心思想 核心操作 其他操作 参考程序 核心思想 主要的思想与treap是一样的.通过让二叉查找树同时满足堆(随机参数)的性质来防止深度过大.与普通treap不同的是非旋treap通过树的分裂与 ...

  2. Maven的New中没有Servlet问题(IDEA)

    1.问题 第一次使用Maven骨架创建Web项目的时候,遇到了 New 里面没有 servlet 的问题. 2.原因 经过查询,是因为IDEA检测到项目中没有导入相关的 jar 包导致. 3.解决方法 ...

  3. Centos 6 can't found command subscription-manager

    [root@localhost ~]# subscription-manager: command not found-bash: -bash:: command not found resoluti ...

  4. 在使用vagrant访问PHP文件是报错“file not found”,好像是最新的NGINX不能识别document_root,只能改为自己的项目目录/vagrant_data

    出现该错误有很多可能,有可能是root配置不对,有可能是fastcgi_param SCRIPT_FILENAME参数不对等. 而本人遇到的也是参数不对,但是是一个比较少人提及的问题,nginx版本不 ...

  5. [Oracle] 简单建表语句

    // 注意表名,字段名,索引名 尽量不要带引号 CREATE TABLE FIRSTTB    ( "ID" NUMBER(8,0) not null primary key, & ...

  6. protected-broadcast 规范使用系统应用组件自定义广播

    1. protected-broadcast 规范使用系统应用组件自定义广播 参考:https://blog.csdn.net/TaylorPotter/article/details/7019424 ...

  7. C之数组

    1. 数组的地址就是数组里元素的首地址 2. 数组其实就是一块连续的内存空间 3. 每个元素所占大小取决于数组的类型 4. 所有指针变量在内存中的长度是一样的

  8. wan口的ip是干什么用的

    wan口的ip是外网的ip,属于公网的ip.主要用于外网的识别,WAN口主要用于连接外部网络,如ADSL.DDN.以太网等各种接入线路:而LAN口用来连接家庭内部网络,主要与家庭网络中的交换机.集线器 ...

  9. smart_pointer example

    #pragma oncetemplate<typename T>class smart_pointer{private: T* m_pRawPointer;public: smart_po ...

  10. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_21-页面静态化-静态化测试-静态化程序编写

    public String getPageHtml(String pageId){ /** * 静态化程序获取页面的DataUrl * * 静态化程序远程请求DataUrl获取数据模型 * * 静态化 ...