ZYNQ-7000开发中断:私有定时器中断

上篇文章实现了了PS接受来自PL的中断,本片文章将在ZYNQ的纯PS里实现私有定时器中断。每个一秒中断一次,在中断函数里计数加1,通过串口打印输出。

*本文所使用的开发板是Miz702(兼容zedboard)
PC 开发环境版本:Vivado 2015.2 Xilinx SDK 2015.2*

中断原理

中断对于保证任务的实时性非常必要,在ZYNQ里集成了中断控制器GIC(Generic Interrupt Controller).GIC可以接受I/O外设中断IOP和PL中断,将这些中断发给CPU。
中断体系结构框图图下:
这里写图片描述

软件中断(SGI)

SGI通过写ICDSGIR寄存器产生SGI.

共享中断SPI

通过PS和PL内各种I/O和存储器控制器产生。

私有中断(PPI)

包含:全局定时器,私有看门狗定时器,私有定时器以及来自PL的FIQ/IRQ。本文主要介绍PPI,其它的请参考官方手册ug585_Zynq_7000_TRM.pdf。
ZYNQ每个CPU链接5个私有外设中断,所有中断的触发类型都是固定不变的。并且来自PL的快速中断信号FIQ和中断信号IRQ反向,然后送到中断控制器因此尽管在ICDICFR1寄存器内反应的他们是低电平触发,但是PS-PL接口中为高电平触发。如图所示:
这里写图片描述

私有定时器

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

搭建硬件系统工程:

配置ZYNQ PS

把ZYNQ配置为只保留UART1,然后点击OK如图所示
这里写图片描述
点击Run Connection Automation,取消掉Apply Board Preset,如图
这里写图片描述
最终的框图很简洁,如图:
这里写图片描述

建立软件工程

建立一个Hello World工程
把Helloworld.c的代码修改如下:

#include <stdio.h>
#include "platform.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);  //每秒打印输出一次

}

上电测试

可以看到串口终端每秒输出一次,并且值加1递增。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值