【ZYNQ-7000开发之十二】中断:PS接收来自PL的中断

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

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

搭建硬件工程

建好工程后,添加ZYNQ IP

双击 ZYNQ,打开Re-customize IP对话框,使能IRQ_P2P

【ZYNQ-7000开发之十二】中断:PS接收来自PL的中断_第1张图片

使能UART1

【ZYNQ-7000开发之十二】中断:PS接收来自PL的中断_第2张图片

点击Run Connection Automation,按照如图所示配置,点击OK

【ZYNQ-7000开发之十二】中断:PS接收来自PL的中断_第3张图片

添加一个GPIO IP,按照如图所示配置,使能中断。点击Run Connection Automation

【ZYNQ-7000开发之十二】中断:PS接收来自PL的中断_第4张图片

再添加一个GPIO IP,按照如图所示配置,点击OK

【ZYNQ-7000开发之十二】中断:PS接收来自PL的中断_第5张图片

把axi_gpio_0的ip2intc_irpt和ZYNQ PS的 IRQ_F2P[0:0]连在一起

搭建好的硬件系统连接,如图所示

【ZYNQ-7000开发之十二】中断:PS接收来自PL的中断_第6张图片

生成顶层文件,点击Generate BitStream

软件工程

新建一个Hello World工程,把以下代码添加进去

#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 int 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);
    switch (btn_value){

                case 1: led_val = 0x01; break;
                case 2: led_val = 0x02; break;
                case 4: led_val = 0x03; break;
                case 8: led_val = 0x04; break;
                case 16:led_val = 0x05; 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;

}

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

你可能感兴趣的:(FPGA,Zynq,ARM,AXI,嵌入式)