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、按一下灯跳好几下
这是因为按键有抖动。