zoukankan      html  css  js  c++  java
  • 第十三章 ZYNQ-MIZ702 PL中断请求

    本篇文章主要介绍外设(PL)产生的中断请求,在PS端进行处理。
    在PL端通过按键产生中断,PS接受到之后点亮相应的LED.

    本文所使用的开发板是Miz702 PC 开发环境版本:Vivado 2015.4 Xilinx SDK 2015.4

    13.0本章难度系数★★☆☆☆☆☆

    13.1 ZYNQ 中断介绍

    13.1.1 ZYNQ中断框图

    wps5134.tmp

    wps5135.tmp

    可以看到本例子中PL到PS部分的中断经过ICD控制器分发后后同时进入CPU1 和CPU0。从下面的表格中可以看到中断向量的具体值。PL到PS部分一共有20个中断可以使用。其中4个是快速中断。剩余的16个是本章中涉及了,可以任意定义。如下表所示。

    wps5136.tmp

    13.1.2 ZYNQ CPU软件中断 (SGI)

    ZYNQ 2个CPU 都具备各自16个软件中断。

    wps5137.tmp

    13.1.3 ZYNQ CPU 私有端口中断

    这些中断都是固定死的,不能修改。这里有2个PL到CPU的快速中断nFIQ

    wps5148.tmp
    11.1.4 ZYNQ PS和PL共享中断

    wps5149.tmpwps514A.tmp


    13.2 搭建硬件工程

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

    wps514B.tmp

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

    wps514C.tmp

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

    wps515D.tmp

    Step4:单击Finish

    wps515E.tmp

    13.3使用IP Integrator创建硬件系统

    Step1:单击Create Block Design

    Step2:输入system

    wps515F.tmp

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

    wps5161.tmp

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

    wps5162.tmp

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

    wps5172.tmp

    Step6:直接单击OK

    wps5173.tmp

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

    wps5174.tmp

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

    wps5175.tmp

    Step9:双击 ZYNQ,打开Re-customize IP对话框,使能IRQ_F2P

    wps5186.tmp

    Step10:使能UART1点击Run Connection Automation,按照如图所示配置后单击OK

    wps5187.tmp

    Step11:添加一个GPIO IP,添加5个输入,按照如图所示配置,使能中断

    wps5188.tmp

    wps5189.tmp

    Step12:再添加一个GPIO IP,添加8个输出按照如图所示配置,点击OK

    wps518A.tmp

    wps519A.tmp

    Step13:单击Run Connection Automation,将2个GPIO进行自动连线

    wps519B.tmp

    Step14:把axi_gpio_0的ip2intc_irpt和ZYNQ PS的 IRQ_F2P[0:0]连在一起,并且修改GPIO的名字如图所示:搭建好的硬件系统连接,如图所示

    wps519C.tmp

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

    wps519D.tmp

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

    wps519E.tmp

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

    wps519F.tmp

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

    wps51B0.tmp

    Step19:添加xdc约束文件

    set_property IOSTANDARD LVCMOS33 [get_ports {btns_5bits_tri_i[4]}]

    set_property IOSTANDARD LVCMOS33 [get_ports {btns_5bits_tri_i[3]}]

    set_property IOSTANDARD LVCMOS33 [get_ports {btns_5bits_tri_i[2]}]

    set_property IOSTANDARD LVCMOS33 [get_ports {btns_5bits_tri_i[1]}]

    set_property IOSTANDARD LVCMOS33 [get_ports {btns_5bits_tri_i[0]}]

    set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[0]}]

    set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[1]}]

    set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[2]}]

    set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[3]}]

    set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[4]}]

    set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[5]}]

    set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[6]}]

    set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[7]}]

    set_property PACKAGE_PIN T18 [get_ports {btns_5bits_tri_i[0]}]

    set_property PACKAGE_PIN R18 [get_ports {btns_5bits_tri_i[1]}]

    set_property PACKAGE_PIN R16 [get_ports {btns_5bits_tri_i[2]}]

    set_property PACKAGE_PIN P16 [get_ports {btns_5bits_tri_i[3]}]

    set_property PACKAGE_PIN N15 [get_ports {btns_5bits_tri_i[4]}]

    set_property PACKAGE_PIN T22 [get_ports {leds_8bits_tri_o[0]}]

    set_property PACKAGE_PIN T21 [get_ports {leds_8bits_tri_o[1]}]

    set_property PACKAGE_PIN U22 [get_ports {leds_8bits_tri_o[2]}]

    set_property PACKAGE_PIN U21 [get_ports {leds_8bits_tri_o[3]}]

    set_property PACKAGE_PIN V22 [get_ports {leds_8bits_tri_o[4]}]

    set_property PACKAGE_PIN W22 [get_ports {leds_8bits_tri_o[5]}]

    set_property PACKAGE_PIN U19 [get_ports {leds_8bits_tri_o[6]}]

    set_property PACKAGE_PIN U14 [get_ports {leds_8bits_tri_o[7]}]

    Step19:执行->产生bit文件wps51B1.tmp

    13.4导出SOC硬件到SDK

    Step1:File->Export->Export Hardware

    wps51B2.tmp

    Step2:勾选Include bitstream 直接单击OK

    wps51B3.tmp

    Step3:File->Launch SDK加载到SDK

    wps51C4.tmp

    Step4:单击OK

    wps51C5.tmp

    13.5软件工程

    新建一个PL_PS_INTC空的工程,并且添加main.c把以下代码添加进去

    #include "xparameters.h"

    #include "xscugic.h"

    #include "xil_exception.h"

    #include "xgpio.h"

    // Parameter definitions

    #define INTC_DEVICE_ID      XPAR_PS7_SCUGIC_0_DEVICE_ID

    #define LED_DEVICE_ID       XPAR_AXI_GPIO_1_DEVICE_ID

    #define BTNS_DEVICE_ID      XPAR_AXI_GPIO_0_DEVICE_ID

    #define INTC_GPIO_INTERRUPT_ID XPAR_FABRIC_AXI_GPIO_0_IP2INTC_IRPT_INTR

    #define BTN_INT             XGPIO_IR_CH1_MASK // This is the interrupt mask for channel one

    #define DELAY 100000000

    XGpio   LED;

    XGpio   BTNInst;

    XScuGic INTCInst;

    static u8 btn_value;

    //----------------------------------------------------

    // PROTOTYPE FUNCTIONS

    //----------------------------------------------------

    static void BTN_Intr_Handler(void *baseaddr_p);

    static int InterruptSystemSetup(XScuGic *XScuGicInstancePtr);

    static int IntcInitFunction(u16 DeviceId, XGpio *GpioInstancePtr);

    //----------------------------------------------------

    //  INTERRUPT SERVICE ROUTINE(ISR)

    //also know as : INTERRUPT HANDLER FUNCTION

    // - called by the buttons interrupt, performs push buttons read

    //----------------------------------------------------

    void BTN_Intr_Handler(void *InstancePtr)

    {

    unsigned char led_val = 0;

    // Ignore additional button presses

    if ((XGpio_InterruptGetStatus(&BTNInst) & BTN_INT) !=

                BTN_INT) {

    return;

    // Disable GPIO interrupts

        XGpio_InterruptDisable(&BTNInst, BTN_INT);

                 }

        btn_value = ~XGpio_DiscreteRead(&BTNInst, 1)&0x1f;

    switch (btn_value){

    case 0x01: led_val = 0x01; break;

    case 0x02: led_val = 0x02; break;

    case 0x04: led_val = 0x04; break;

    case 0x08: led_val = 0x08; break;

    case 0x10: led_val = 0x10; break;

    default:break;  }

        XGpio_DiscreteWrite(&LED,1,led_val);

    // Acknowledge GPIO interrupts

        (void)XGpio_InterruptClear(&BTNInst, BTN_INT);

    // Enable GPIO interrupts

        XGpio_InterruptEnable(&BTNInst, BTN_INT);

    }

    //----------------------------------------------------

    // MAIN FUNCTION

    //----------------------------------------------------

    int main (void)

    {

    int status;

    // 初始化按键

      status = XGpio_Initialize(&BTNInst, BTNS_DEVICE_ID);

    if(status != XST_SUCCESS) return XST_FAILURE;

    //初始化LED

      status = XGpio_Initialize(&LED, LED_DEVICE_ID);

    if(status != XST_SUCCESS) return XST_FAILURE;

    // 设置按键IO的方向为输入

      XGpio_SetDataDirection(&BTNInst, 1, 0xFF);

    //设置LED IO的方向为输出

      XGpio_SetDataDirection(&LED, 1, 0x00);

    // 初始化中断控制器

      status = IntcInitFunction(INTC_DEVICE_ID, &BTNInst);

    if(status != XST_SUCCESS) return XST_FAILURE;

    while(1){

      }

    return (0);

    }

    //----------------------------------------------------

    // INTERRUPT SETUP FUNCTIONS

    //----------------------------------------------------

    int IntcInitFunction(u16 DeviceId, XGpio *GpioInstancePtr)

    {

    XScuGic_Config *IntcConfig;

    int status;

    // Interrupt controller initialization

        IntcConfig = XScuGic_LookupConfig(DeviceId);

        status = XScuGic_CfgInitialize(&INTCInst, IntcConfig, IntcConfig->CpuBaseAddress);

    if(status != XST_SUCCESS) return XST_FAILURE;

    // Call interrupt setup function

        status = InterruptSystemSetup(&INTCInst);

    if(status != XST_SUCCESS) return XST_FAILURE;

    // Register GPIO interrupt handler

        status = XScuGic_Connect(&INTCInst,

                                 INTC_GPIO_INTERRUPT_ID,

                                 (Xil_ExceptionHandler)BTN_Intr_Handler,

                                 (void *)GpioInstancePtr);

    if(status != XST_SUCCESS) return XST_FAILURE;

    // Enable GPIO interrupts

        XGpio_InterruptEnable(GpioInstancePtr, 1);

        XGpio_InterruptGlobalEnable(GpioInstancePtr);

    // Enable GPIO interrupts in the controller

        XScuGic_Enable(&INTCInst, INTC_GPIO_INTERRUPT_ID);

    return XST_SUCCESS;

    }

    int InterruptSystemSetup(XScuGic *XScuGicInstancePtr)

    {

    // Register GIC interrupt handler

        Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,

                                     (Xil_ExceptionHandler)XScuGic_InterruptHandler,

                                     XScuGicInstancePtr);

        Xil_ExceptionEnable();

    return XST_SUCCESS;

    }

    13.6结果

    下载好之后,按键按下可以看到相应的LED被点亮

    13.7 本章小结

    本章学习了外部中断,通过PL传递开发板按键的中断,然后在PS接受处理中断。

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

    官网论坛:www.osrc.cn

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

    源码链接:http://pan.baidu.com/s/1jHCdRds 密码:zvtu

  • 相关阅读:
    《Java程序设计》第七次学习总结
    《Java程序设计》第六次学习总结
    实验二:Java面向对象程序设计
    《信息安全系统设计基础》第二次学习总结
    《信息安全系统设计基础+Linux 内核分析》第一次学习总结
    《Java程序设计》第五次学习总结
    《Java程序设计》第四次学习总结
    《Java程序设计》第三次学习总结
    next_permutation 函数
    POJ 3268 (dijkstra算法)
  • 原文地址:https://www.cnblogs.com/milinker/p/5906004.html
Copyright © 2011-2022 走看看