zynq 7000系列gpio中断使用

xilinx 库函数有一个比较通用的初始化流程

1、定义外设结构体:

XGpioPs xgpio;
XScuGic intc;

2、定义外设配置指针:

XGpioPs_Config *gpioConfig;

XScuGic_Config *IntcConfig;

3、根据外设DEVICE_ID寻找配置:

gpio_Config = XGpioPs_LookupConfig(GPIO_DEVICE_ID);

IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);

4、初始化外设

XGpioPs_CfgInitialize(&xgpio, gpioConfig, gpioConfig->BaseAddr);

XScuGic_CfgInitialize(&intc, IntcConfig, IntcConfig->CpuBaseAddress);

注意第三个参数和配置所在的内存位置有关,函数原型中是EffectiveAddr,即base address

5、调用各个外设的api

GPIO中断配置流程,分为GPIO控制器初始化和中断控制器(GIC)初始化,以及设置中断触发类型和绑定中断回调等

1、GPIO控制器初始化

#include "xparameters.h"
#include "xgpiops.h"

//定义GPIO设备ID
#define GPIOPS_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID    

//定义按键和LED的MIO编号,看板子的原理图
#define PS_KEY1 50
#define PS_KEY2 51
#define PS_LED1 0
#define PS_LED2 13

//定义全局设备结构体变量
XGpioPs xgpio;
XGpioPs_Config *gpio_Config;

//根据器件 ID 查找配置信息
gpio_Config = XGpioPs_LookupConfig(GPIOPS_DEVICE_ID);

//初始化 GPIO driver
status = XGpioPs_CfgInitialize(&xgpio, gpio_Config, gpio_Config->BaseAddr);

//设置 KEY 所连接的 MIO 引脚的方向为输入,0为输入
XGpioPs_SetDirectionPin(&xgpio, PS_KEY1, 0);
XGpioPs_SetDirectionPin(&xgpio, PS_KEY2, 0);

//设置 LED 所连接的 MIO 引脚的方向为输出、使能输出并设置默认输出电平
XGpioPs_SetDirectionPin(&xgpio, PS_LED1, 1);
XGpioPs_SetDirectionPin(&xgpio, PS_LED2, 1);
//1为使能输出
XGpioPs_SetOutputEnablePin(&xgpio, PS_LED1, 1);
XGpioPs_SetOutputEnablePin(&xgpio, PS_LED2, 1);
//0为输出低电平
XGpioPs_WritePin(&xgpio, PS_LED1, 0x0);
XGpioPs_WritePin(&xgpio, PS_LED2, 0x0);

2、GIC控制器初始化

#include "xscugic.h"
#include "xil_exception.h"

//GIC控制器的设备ID
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
//MIO的中断号为52,参考UG585
#define GPIO_INTERRUPT_ID XPAR_XGPIOPS_0_INTR	

//全局结构体定义
XScuGic intc;

//中断控制器配置信息指针
XScuGic_Config *IntcConfig;		

//根据器件 ID 查找配置信息
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);

//初始化 Gic driver
status = XScuGic_CfgInitialize(&intc, IntcConfig, IntcConfig->CpuBaseAddress);

3、使能中断异常,注册回调函数

//设置并使能中断异常
//XIL_EXCEPTION_ID_INT和XScuGic_InterruptHandler是库函数自带的
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
		(Xil_ExceptionHandler) XScuGic_InterruptHandler, &intc);
Xil_ExceptionEnable();

//为中断设置中断处理函数
//intr_handler是实际的回调函数,(void *) gpio是传递给回调函数的参数,用于获取中断源
status = XScuGic_Connect(&intc, GpioIntrId,
		(Xil_ExceptionHandler) intr_handler, (void *) gpio);

4、设置GPIO中断触发类型

//使能来自于 Gpio 器件的中断
XScuGic_Enable(&intc, GpioIntrId);

//设置 KEY 按键的中断类型为下降沿中断
XGpioPs_SetIntrTypePin(&xgpio, PS_KEY1, XGPIOPS_IRQ_TYPE_EDGE_FALLING);
XGpioPs_SetIntrTypePin(&xgpio, PS_KEY2, XGPIOPS_IRQ_TYPE_EDGE_FALLING);

//使能按键 KEY 中断
XGpioPs_IntrEnablePin(&xgpio, PS_KEY1);
XGpioPs_IntrEnablePin(&xgpio, PS_KEY2);

/*库函数中定义了以下几种中断触发类型,具体可用哪些参考UG585****************************/
#define XGPIOPS_IRQ_TYPE_EDGE_RISING	0x00U  /**< Interrupt on Rising edge */
#define XGPIOPS_IRQ_TYPE_EDGE_FALLING	0x01U  /**< Interrupt Falling edge */
#define XGPIOPS_IRQ_TYPE_EDGE_BOTH	0x02U  /**< Interrupt on both edges */
#define XGPIOPS_IRQ_TYPE_LEVEL_HIGH	0x03U  /**< Interrupt on high level */
#define XGPIOPS_IRQ_TYPE_LEVEL_LOW	0x04U  /**< Interrupt on low level */
/*********************************************************************************/

5、回调函数示例,实现功能为按下一次按键LED翻转一次

static void intr_handler(void *callback_ref)
{
	XGpioPs *gpio = (XGpioPs *) callback_ref;
	xil_printf("enter interrupt!\t");
	//读取 KEY 按键引脚的中断状态,判断是否发生中断
	if (XGpioPs_IntrGetStatusPin(gpio, PS_KEY1))
	{
		xil_printf("PS_KEY1 press!\r\n");
		XGpioPs_WritePin(gpio, PS_LED1, ~XGpioPs_ReadPin(gpio, PS_LED1));
        //禁用PS_KEY1的中断,防止无限进入中断
		XGpioPs_IntrDisablePin(gpio, PS_KEY1);
        //清除按键 KEY 中断
		XGpioPs_IntrClearPin(gpio, PS_KEY1); 
        //使能按键 KEY 中断
		XGpioPs_IntrEnablePin(gpio, PS_KEY1); 
	}

	if (XGpioPs_IntrGetStatusPin(gpio, PS_KEY2))
	{
		xil_printf("PS_KEY2 press!\r\n");
		XGpioPs_WritePin(gpio, PS_LED2, ~XGpioPs_ReadPin(gpio, PS_LED2));
		XGpioPs_IntrDisablePin(gpio, PS_KEY2);//禁用PS_KEY2的中断,防止无限进入中断
		XGpioPs_IntrClearPin(gpio, PS_KEY2); //清除按键 KEY 中断
		XGpioPs_IntrEnablePin(gpio, PS_KEY2); //使能按键 KEY 中断
	}
}

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值