zynq 7000系列gpio中断使用

本文详细介绍了在Xilinx平台上使用XGpioPs和XScuGic库进行GPIO控制器和中断控制器GIC的初始化,包括配置外设结构体、查找配置、初始化步骤,以及GPIO中断的设置和回调函数实现。
摘要由CSDN通过智能技术生成

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
    评论
Zynq芯片中,GPIO引脚的中断是通过AXI_GPIO模块和PS相连的中断信号线的电平变换引发的。可以通过配置中断触发方式来设置GPIO引脚的中断。具体来说,可以使用XScuGic_SetPriorityTriggerType函数来设置中断触发优先级和触发类型。例如,可以通过设置中断触发类型为上升沿触发来使得当GPIO引脚的电平变为上升沿时触发中断。 需要注意的是,GPIO引脚的中断方式已经由硬件决定好了,无法在此处进行配置。参考函数的注释中提到,只有两种方式可以设置中断,即高电平和上升沿,这里的高电平和上升沿指的是AXI_GPIO模块和PS相连的中断信号线的电平变换引发PS中断,而不是GPIO引脚的中断方式。 因此,在配置中断触发方式时,需要确定好AXI_GPIO模块和PS相连的中断信号线的电平变换方式并设置相应的中断触发类型。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [zynq-7000.rar_linux 中断 zynq_zynq DMA_zynq DMA Linux_zynq gpio_i2](https://download.csdn.net/download/weixin_42651887/86201535)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [ZYNQ_GPIO_中断](https://blog.csdn.net/Master_0_/article/details/125125000)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值