zynq例程总结 - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki

printf_gpio_intr

image

#include "stdio.h"
#include "xparameters.h"
#include "xgpio.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xil_printf.h"
#include "sleep.h"

//器件ID宏定义
#define SCUGIC_ID	XPAR_SCUGIC_0_DEVICE_ID		//中断控制器
#define AXI_GPIO_ID XPAR_AXI_GPIO_0_DEVICE_ID	//PL端  AXI GPIO器件
#define GPIO_INT_ID XPAR_FABRIC_GPIO_0_VEC_ID	//PL端  AXI GPIO中断

//连接端口宏定义
#define LED_CHANNEL 1
#define LED 0b0011

#define KEY_CHANNEL  2
#define KEY_MASK     XGPIO_IR_CH2_MASK

//函数声明
void axi_gpio_intr_handler(void *CallbackRef);		//中断服务函数

//PL端AXI_GPIO
XGpio axi_gpio;					//PL端 AXI GPIO 驱动实例


//中断控制
XScuGic scugic;					//中断控制器  驱动实例
XScuGic_Config * scugic_cfg;    //中断控制器  配置信息

u8 led_val;						//LED显示状态
u8 key_flag = 0;			    //中断标志

int main() {
	printf("AXI_GPIO Test!\n");

	//初始化PL端  AXI GPIO驱动
	XGpio_Initialize(&axi_gpio, AXI_GPIO_ID);

	//初始化中断控制器驱动
	scugic_cfg = XScuGic_LookupConfig(SCUGIC_ID);
	XScuGic_CfgInitialize(&scugic, scugic_cfg, scugic_cfg->CpuBaseAddress);

	//配置PL AXI GPIO LED: CH1
	XGpio_SetDataDirection(&axi_gpio, LED_CHANNEL, ~LED);

	//配置PL AXI GPIO KEY: CH2
	XGpio_SetDataDirection(&axi_gpio, KEY_CHANNEL, 0b0011); //设置PL AXI GPIO通道1为输入
	XGpio_InterruptEnable(&axi_gpio, KEY_MASK);		//使能通道1中断
	XGpio_InterruptGlobalEnable(&axi_gpio);			//使能AXI GPIO全局中断

	//设置中断优先级和触发类型(高电平触发)
	XScuGic_SetPriorityTriggerType(&scugic, GPIO_INT_ID, 0xA0, 0x1);
	//关联中断源AXI_GPIO和中断处理函数axi_gpio_intr_handler
	XScuGic_Connect(&scugic, GPIO_INT_ID, axi_gpio_intr_handler, &axi_gpio);
	//使能AXI GPIO中断
	XScuGic_Enable(&scugic, GPIO_INT_ID);

	//设置并打开中断异常处理功能
	Xil_ExceptionInit();
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
			(Xil_ExceptionHandler) XScuGic_InterruptHandler, &scugic);
	Xil_ExceptionEnable();

	while (1) {
		if (key_flag) {
			key_flag = 0;
			led_val = ~led_val;
			XGpio_DiscreteWrite(&axi_gpio, LED_CHANNEL, led_val);	//改变LED亮灭
		}
	}

	return 0;
}

// AXI GPIO 中断服务函数
void axi_gpio_intr_handler(void *CallbackRef) {
	xil_printf("now in irq!\r\n");
	u8 key_value = 1;
	XGpio *GpioPtr = (XGpio *) CallbackRef;

	XGpio_InterruptDisable(GpioPtr, KEY_MASK);				//AXI GPIO中断失能
	key_value = XGpio_DiscreteRead(GpioPtr, KEY_CHANNEL);
	xil_printf("key_value=%x\r\n", key_value);

	usleep(100000);												//延时100ms,按键消抖
	if (key_value == 0b0001 || key_value == 0b0010) {			//判断按键按下
		key_flag = 1;
	}

	XGpio_InterruptClear(GpioPtr, KEY_MASK);				//清除中断标志
	XGpio_InterruptEnable(GpioPtr, KEY_MASK);				//AXI GPIO中断使能
}