Zynq3-PL端中断请求

1、参考

   米联客的PL端中断请求。主要是为了更直接的感受中断过程和SDK中中断处理函数。

2、搭建工程

   生成zynq,自动连线,选中中断,普通中断,如下图所示:

然后添加GPIO0,允许中断,设置为input 位宽为1,然后添加GPIO1,设置为output ,位宽为4。需要注意的是,如果一切都按照默认的来,GPIO0和GPIO1会变成6bit,需要清除board配置,如下图所示:

然后在自动连线的时候,在右边自己选择为custom。

添加xdc文件

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

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

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

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

set_property IOSTANDARD LVCMOS33 [get_ports btn_tri_i]

 

set_property PACKAGE_PIN R14 [get_ports {led_tri_o[0]}]

set_property PACKAGE_PIN P14 [get_ports {led_tri_o[1]}]

set_property PACKAGE_PIN N16 [get_ports {led_tri_o[2]}]

set_property PACKAGE_PIN M14 [get_ports {led_tri_o[3]}]

set_property PACKAGE_PIN L19 [get_ports btn_tri_i]

然后连接ZYNQ中的中断和GPIO0中的中断,然后生成bit文件,export,launch。

3、SDK端设计

SDK的界面类似于eclipse,新建APP,然后输入随意的名称,选择hello world的工程。

修改如下所示:

#include "xparameters.h"

#include "xscugic.h"

#include "xil_exception.h"

#include "xgpio.h"

XGpio GpioOutput;

// 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)&0x01;
if(btn_value==0x0)
	btn_value = 0x01;
else if(btn_value==0x10)
	btn_value = 0x01;
else
	btn_value = btn_value<<1;


switch (btn_value){

case 0x1: led_val = 0x01; break;

case 0x2: led_val = 0x02; break;

case 0x4: led_val = 0x04; break;

case 0x8: 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)

{

	u32 Delay;
	u32 Ledwidth;

	init_platform();

	XGpio_Initialize(&BTNInst, BTNS_DEVICE_ID);
	XGpio_SetDataDirection(&BTNInst, 1, 0xFF);

	XGpio_Initialize(&LED, LED_DEVICE_ID);
	XGpio_SetDataDirection(&LED, 1, 0x00);
	XGpio_DiscreteWrite(&LED, 1, 0x0);


	IntcInitFunction(INTC_DEVICE_ID, &BTNInst);

	while (1)

	{
		print("helllow ");
	}

		cleanup_platform();

		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;

}

结果:

我设置按键为BTN3,按下就会使得灯亮。

4、问题汇总

1、提示如下所示

这是因为没有将ZYNQ的中断和GPIO0的中断没连接在一起,需要重新连接,然后generate output products,生成bit。

2、使用米联客的main函数为何灯不亮?

上面的代码我进行了部分修改,米联客的程序不行是因为btn_value没能满足case要求。

3、按一下灯跳好几下

这是因为按键有抖动。

猜你喜欢

转载自blog.csdn.net/weixin_39813867/article/details/83544078