• 第十四章 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。 
    中断体系结构框图图下:
    wps949F.tmp

    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接口中为高电平触发。如图所示: 
    wps94A0.tmp

    14.1.4私有定时器

    zynq中每个ARM core都有自己的私有定时器,私有定时器的工作频率为CPU的一半,比如Miz702的ARM工作频率为666MHZ,则私有定时器的频率为333MHz. 
    私有定时器的特性如下:
    (1)32位计数器,达到零时产生一个中断 
    (2)8位预分频计数器,可以更好的控制中断周期 
    (3)可配置一次性或者自动重加载模式 
    (4)定时器时间可以通过下式计算: 
    定时时间 = [(预分频器的值 + 1) (加载值 + 1)]/定时器频率

    14.2 搭建硬件工程

    Step1:新建一个名为为Miz702_sys的工程

    wps94A1.tmp

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

    wps94B2.tmp

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

    wps94B3.tmp

    Step4:单击Finish

    wps94B4.tmp

    14.3使用IP Integrator创建硬件系统

    Step1:单击Create Block Design

    Step2:输入system

    wps94B5.tmp

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

    wps94C6.tmp

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

    wps94C7.tmp

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

    wps94C8.tmp

    Step6:直接单击OK

    wps94D9.tmp

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

    wps94DA.tmp

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

    wps94DB.tmp

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

    wps94DC.tmp

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

    wps94EC.tmp

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

    wps94ED.tmp

    Step12:选择Leave Let Vivado manager wrapper and auto-update 然后单击OK

    Step13:执行->产生bit文件wps94EE.tmp

    14.4导出SOC硬件到SDK

    Step1:File->Export->Export Hardware

    wps94EF.tmp

    Step2:勾选Include bitstream 直接单击OK

    wps9500.tmp

    Step3:File->Launch SDK加载到SDK

    wps9501.tmp

    Step4:单击OK

    wps9502.tmp

    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------------- ");

       //  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 ",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

  • 相关阅读:
    jQuery获取option的一些常用方法
    111
    网站架构
    软件测试分类
    Python之import的用法
    解决:appium-doctor不是内部或外部命令
    mysql四种常见的数据库引擎
    mysql之数据类型
    彻底清除mysql(windows平台)
    Tkinter基于Combobox控件实现二级菜单联动
  • 原文地址:https://www.cnblogs.com/milinker/p/5906014.html
Copyright © 2020-2023  润新知