本篇文章主要介绍外设(PL)产生的中断请求,在PS端进行处理。
在PL端通过按键产生中断,PS接受到之后点亮相应的LED.
本文所使用的开发板是zedboard
PC 开发环境版本:Vivado 2015.4 Xilinx SDK 2015.4
搭建硬件工程
建好工程后,添加ZYNQ IP
双击 ZYNQ,打开Re-customize IP对话框,使能IRQ_P2P
使能UART1
点击Run Connection Automation,按照如图所示配置,点击OK
添加一个GPIO IP,按照如图所示配置,使能中断。点击Run Connection Automation
再添加一个GPIO IP,按照如图所示配置,点击OK
把axi_gpio_0的ip2intc_irpt和ZYNQ PS的 IRQ_F2P[0:0]连在一起
搭建好的硬件系统连接,如图所示
生成顶层文件,点击Generate BitStream
软件工程
新建一个Hello World工程,把以下代码添加进去
1 #include <stdio.h> 2 #include "platform.h" 3 #include "xparameters.h" 4 #include "xscugic.h" 5 #include "xil_exception.h" 6 #include "xgpio.h" 7 8 //parameter definitions 9 #define INTC_DEVICE_ID XPAR_PS7_SCUGIC_0_DEVICE_ID //DEVICE_ID用来初始化函数,索引数组元素 10 #define LED_DEVICE_ID XPAR_AXI_GPIO_1_DEVICE_ID 11 #define BTNS_DEVICE_ID XPAR_AXI_GPIO_0_DEVICE_ID 12 #define INTC_GPIO_INTERRUPT_ID XPAR_FABRIC_AXI_GPIO_0_IP2INTC_IRPT_INTR 13 #define BTN_INT XGPIO_IR_CH1_MASK 14 #define DELAY 100000000 15 16 XGpio LED; 17 XGpio BTNInst; 18 XScuGic INTCInst; 19 static int btn_value; 20 21 //Function protype 22 static void BTN_Intr_Handler(void *baseaddr_p); 23 static int InterruptSystemSetup(XScuGic *XScuGicInstancePtr); 24 static int IntcInitFunction(u16 DeviceId,XGpio *GpioInstancePtr); 25 26 void BTN_Intr_Handler(void *InstancePtr) 27 { 28 unsigned char led_val=0; 29 //Ignore additional button presses 30 if((XGpio_InterruptGetStatus(&BTNInst) & BTN_INT) != BTN_INT) 31 { 32 return; 33 //Disable GPIO interrupts 34 XGpio_InterruptDisable(&BTNInst,BTN_INT); 35 } 36 btn_value = XGpio_DiscreteRead(&BTNInst,1); 37 switch(btn_value) 38 { 39 case 1: led_val = 0x01;break; //led[7:0]=0x01 40 case 2: led_val = 0x02;break; 41 case 4: led_val = 0x03;break; //亮1和2 42 case 8: led_val = 0x04;break; 43 case 16: led_val = 0x05;break; //亮0和2 44 default:break; 45 } 46 47 XGpio_DiscreteWrite(&LED,1,led_val); 48 //Acknowledge GPIO interrupts 49 (void)XGpio_InterruptClear(&BTNInst,BTN_INT); 50 //Enable GPIO interrupts 51 XGpio_InterruptEnable(&BTNInst,BTN_INT); 52 } 53 54 int main(void) 55 { 56 int status; 57 58 //按键初始化 59 status = XGpio_Initialize(&BTNInst,BTNS_DEVICE_ID); 60 if(status != XST_SUCCESS) return XST_FAILURE; 61 62 //初始化LED 63 status = XGpio_Initialize(&LED,LED_DEVICE_ID); 64 if(status != XST_SUCCESS) return XST_FAILURE; 65 66 //设置按键IO的方向为输入 67 XGpio_SetDataDirection(&BTNInst,1,0xff); 68 //设置LED IO 的方向为输出 69 XGpio_SetDataDirection(&LED,1,0X00); 70 71 //初始化中断控制器 72 status = IntcInitFunction(INTC_DEVICE_ID,&BTNInst); 73 if(status != XST_SUCCESS) return XST_FAILURE; 74 75 while(1){} 76 77 return 0; 78 } 79 80 int IntcInitFunction(u16 DeviceId,XGpio *GpioInstancePtr) 81 { 82 XScuGic_Config *IntcConfig; 83 int status; 84 85 //Interrupt controller initialization 86 IntcConfig = XScuGic_LookupConfig(DeviceId); 87 status = XScuGic_CfgInitialize(&INTCInst,IntcConfig,IntcConfig->CpuBaseAddress); 88 if(status != XST_SUCCESS) return XST_FAILURE; 89 90 //Call interrupt setup function 91 status = InterruptSystemSetup(&INTCInst); 92 if(status != XST_SUCCESS) return XST_FAILURE; 93 94 //Register GPIO interrupt handler 95 status = XScuGic_Connect(&INTCInst,INTC_GPIO_INTERRUPT_ID,(Xil_ExceptionHandler)BTN_Intr_Handler,(void *)GpioInstancePtr); 96 if(status != XST_SUCCESS) return XST_FAILURE; 97 98 //Enable GPIO interrupts 99 XGpio_InterruptEnable(GpioInstancePtr,1); 100 XGpio_InterruptGlobalEnable(GpioInstancePtr); 101 102 //Enable GPIO interrupts in the controller 103 XScuGic_Enable(&INTCInst,INTC_GPIO_INTERRUPT_ID); 104 105 return XST_SUCCESS; 106 } 107 108 int InterruptSystemSetup(XScuGic *XScuGicInstancePtr) 109 { 110 //Register GIC interrupt handler 111 Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,XScuGicInstancePtr); 112 Xil_ExceptionEnable(); 113 114 return XST_SUCCESS; 115 }