正文
77.PS接收来自PL的按键中断
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
本篇文章主要介绍外设(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工程,把以下代码添加进去
#include <stdio.h>
#include "platform.h"
#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 //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
#define DELAY 100000000 XGpio LED;
XGpio BTNInst;
XScuGic INTCInst;
static int btn_value; //Function protype
static void BTN_Intr_Handler(void *baseaddr_p);
static int InterruptSystemSetup(XScuGic *XScuGicInstancePtr);
static int IntcInitFunction(u16 DeviceId,XGpio *GpioInstancePtr); void BTN_Intr_Handler(void *InstancePtr)
{
unsigned char led_val=;
//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,);
switch(btn_value)
{
case : led_val = 0x01;break; //led[7:0]=0x01
case : led_val = 0x02;break;
case : led_val = 0x03;break; //亮1和2
case : led_val = 0x04;break;
case : led_val = 0x05;break; //亮0和2
default:break;
} XGpio_DiscreteWrite(&LED,,led_val);
//Acknowledge GPIO interrupts
(void)XGpio_InterruptClear(&BTNInst,BTN_INT);
//Enable GPIO interrupts
XGpio_InterruptEnable(&BTNInst,BTN_INT);
} 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,,0xff);
//设置LED IO 的方向为输出
XGpio_SetDataDirection(&LED,,0X00); //初始化中断控制器
status = IntcInitFunction(INTC_DEVICE_ID,&BTNInst);
if(status != XST_SUCCESS) return XST_FAILURE; while(){} return ;
} 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,);
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被点亮
#include <stdio.h>
#include "platform.h"
#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 //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
#define DELAY 100000000 XGpio LED;
XGpio BTNInst;
XScuGic INTCInst;
static int btn_value; //Function protype
static void BTN_Intr_Handler(void *baseaddr_p);
static int InterruptSystemSetup(XScuGic *XScuGicInstancePtr);
static int IntcInitFunction(u16 DeviceId,XGpio *GpioInstancePtr); void BTN_Intr_Handler(void *InstancePtr)
{
unsigned char led_val=;
//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,);
switch(btn_value)
{
case : led_val = 0x01;break; //led[7:0]=0x01
case : led_val = 0x02;break;
case : led_val = 0x03;break; //亮1和2
case : led_val = 0x04;break;
case : led_val = 0x05;break; //亮0和2
default:break;
} XGpio_DiscreteWrite(&LED,,led_val);
//Acknowledge GPIO interrupts
(void)XGpio_InterruptClear(&BTNInst,BTN_INT);
//Enable GPIO interrupts
XGpio_InterruptEnable(&BTNInst,BTN_INT);
} 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,,0xff);
//设置LED IO 的方向为输出
XGpio_SetDataDirection(&LED,,0X00); //初始化中断控制器
status = IntcInitFunction(INTC_DEVICE_ID,&BTNInst);
if(status != XST_SUCCESS) return XST_FAILURE; while(){} return ;
} 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,);
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;
}