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

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

官网论坛:www.osrc.cn

源码链接:http://pan.baidu.com/s/1skC582T 密码:eyhp

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

  1. 灵动微电子ARM Cortex M0 MM32F0010 Timer定时器中断定时功能的配置

    灵动微电子ARM Cortex M0 MM32F0010 Timer定时器中断定时功能的配置 目录: 1.Timer1高级定时器Timer3通用定时器Timer14基本定时器简介 2.Timer1高级 ...

  2. 第十四章 ZYNQ TIMER定时器中断

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

  3. 79.ZYNQ内部私有定时器中断

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

  4. ZYNQ入门实例——定时器中断与程序固化

    一.前言 APU系统中CPU以串行执行代码的方式完成操作,软件方式很难做到精准计时,因此调用内部定时器硬件完成计时是更好的选择.本文以定时器中断方式控制LED周期性闪烁为例学习私有定时器的使用.同时学 ...

  5. 【TCP/IP详解 卷一:协议】第二十三章 TCP的保活定时器

    本章介绍保活定时器. 在 TCP 的三握四挥 章节中,我们介绍了 处在 TIME_WAIT 的 2MSL定时器:在 TCP的超时与重传 章节中,我们介绍了 重传定时器:在上一章节中,我们介绍了 防止死 ...

  6. S02_CH08_ ZYNQ 定时器中断实验

    S02_CH08_ ZYNQ 定时器中断实验 上一章实现了PS接受来自PL的中断,本章将在ZYNQ的纯PS里实现私有定时器中断.每隔一秒中断一次,在中断函数里计数加1,通过串口打印输出. 8.1中断原 ...

  7. STM32学习笔记——定时器中断(向原子哥学习)

    定时器中断 STM32 的定时器功能十分强大,有 TIME1 和 TIME8 等高级定时器,也有 TIME2~TIME5 等通用定时器,还有 TIME6 和TIME7 等基本定时器.在本章中,我们将利 ...

  8. JZ2440 裸机驱动 第10章 系统时钟和定时器

    本章目标      了解S3C2410/S3C2440的时钟体系结构     掌握通过设置MPLL改变系统时钟的方法     掌握在不同的频率下设置存储控制器的方法     掌握PWM定时器的用法   ...

  9. 4-MSP430定时器_定时器中断

    一开始没写好就上传了,,,,,,,,这次来个全的 自己学MSP430是为了写一篇关于PID的文章,需要430在proteus上做仿真,一则认为在自动控制算法上PID真的很经典,PLC设备上大多是模块式 ...

随机推荐

  1. codeforces gym #101987B- Cosmetic Survey(floyd)

    题目链接: https://codeforces.com/gym/101987/my 题意: 顶点数为$n$,边数为$m$ 求出每个点对$(a,b)$,$a$到$b$的最小路径的最大值 数据范围: $ ...

  2. Reconnect due to socket error java.nio.channels.ClosedChannelException

    storm整合kafka后出现如下异常: 错误原因:有部分kafka服务器连接不上导致,检查一下是不是每个kafka都能连接到(有的kafka配置使用的是host,记得配置相同的环境) 造成异常代码段 ...

  3. Python实现进度条的效果

    from itertools import cycle from time import sleep for frame in cycle(r'-\|/-\|/'): print('\r', fram ...

  4. HTTP之缓存

    1. 保持副本的新鲜 HTTP 有一些简单的机制可以在不要求服务器记住有哪些缓存拥有其文档副本的情况下,保持已缓存数据与服务器数据之间充分一致.HTTP 将这些简单的机制称为文档过期(document ...

  5. 求N个集合的并集

    做容器放置实验时,需要计算下载N个Images的总size(Image之间可能会有可以共享的size). 一开始想到的是Images两两之间求交集,然后慢慢推到了容斥原理...时间复杂度大概就是O(N ...

  6. mvc partialView断点调试问题

    mvc中的partialview 在前端f12调试时,默认看不到代码的.  在Js中加上debugger;  调试时会走到断点,多出个VM打头的局部视图页面.

  7. You can't specify target table 'a' for update in FROM clause

    项目中有一个功能变动上线,其中有一张表ttt的字段cc,历史数据需要处理,把字段cc中为'xxx'的值替换为'yyy'. 表A结构如下: CREATE TABLE `ttt` ( `id` bigin ...

  8. kotlin使用中辍标记法调用函数

    fun main(arg: Array<String>) { var str = "hello world" print(str div("l")) ...

  9. 14 Flutter仿京东商城项目 头部搜索导航布局 修改主题 修正ScreenAdapter类

    main.dart import 'package:flutter/material.dart'; import 'routes/router.dart'; void main() => run ...

  10. Java实现ModbusTCP通信

    一个项目,需要用Java实现使用ModbusTCP和硬件设备通信 资料 代码下载 本文的代码和仿真软件:蓝奏云下载 官网资料 Modbus官网 Modbus协议 Modbus技术资源 MODBUS T ...