基于ZYNQ的GPIO多中断使用

9 篇文章 1 订阅
2 篇文章 0 订阅

1、工程如下
在这里插入图片描述
2、将gpio_0、gpio_1、gpio_2和gpio_3位宽都配置为1,同时引出0和1的中断,并接入zynq的irq中断控制器。
3、生成bitstream,并生成xsa文件。
4、
main.c

#include <stdio.h>
#include "xil_printf.h"
#include "xparameters.h"

#include "intc.h"
#include "gpio.h"
#include "gpio1.h"

static XScuGic Intc;

int main()
{
	int status;
	status = Intc_Init(&Intc);
	xil_printf(" %d \r\n",status);
	status = Gpio_Init(&Intc);
    xil_printf(" %d \r\n",status);
    status = Gpio1_Init(&Intc);
    xil_printf(" %d \r\n",status);
    while(1);
    return 0;
}

intc.c

#include "xscutimer.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xparameters.h"
#include "xil_printf.h"

#define INTC_DEVICE_ID				XPAR_PS7_SCUGIC_0_DEVICE_ID

int Intc_Init(XScuGic *Intc){
	int Status;
	//init intc
	XScuGic_Config *Intc_ConfigPtr;
	//初始化中断
	Intc_ConfigPtr = XScuGic_LookupConfig(INTC_DEVICE_ID);
	if (NULL == Intc_ConfigPtr) {
		return XST_FAILURE;
	}
	Status = XScuGic_CfgInitialize(Intc,Intc_ConfigPtr,Intc_ConfigPtr->CpuBaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	//初始化ARM处理器的异常处理
	Xil_ExceptionInit();
	//连接到Xilinx提供的通用中断处理程序XScuGic_InterruptHandler,
	//所有产生的中断都要经过GIC,GIC负责使能中断,废弃中断,赋予优先级,发送到CPU,
	//中断发生时ARM处理器会先询问中断控制器哪一个外设产生的中断,第三个参数是传递给处理程序的
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, Intc);
	Xil_ExceptionEnable();
	return XST_SUCCESS;
}

intc.h

#ifndef __INTC_H_
#define __INTC_H_

#include "xscugic.h"

int Intc_Init(XScuGic *Intc);

#endif

gpio.c

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

#include "gpio.h"
#include "sleep.h"

#define GPIO_DEVICE_ID_1			XPAR_GPIO_1_DEVICE_ID
#define GPIO_DEVICE_ID_3			XPAR_GPIO_3_DEVICE_ID

#define INTC_GPIO_INTERRUPT_ID_1	XPAR_FABRIC_AXI_GPIO_1_IP2INTC_IRPT_INTR

#define GPIO_CHANNEL_1		1
#define GPIO_CHANNEL_3		1

static XGpio Gpio_1;
static XGpio Gpio_3;

static int dispaly_0 = 0;
u32 InputData;

static void GpioHandler1(void *CallBackRef);

void GpioHandler1(void *CallbackRef)
{
	XGpio *Gpio_11 = (XGpio *)CallbackRef;
	//去抖
	usleep(10);
	//读输入
	if(XGpio_DiscreteRead(Gpio_11,GPIO_CHANNEL_1) == 0x1){
		//设定输出,跳变
		XGpio_DiscreteWrite(&Gpio_3,GPIO_CHANNEL_3,dispaly_0&0x1);
		xil_printf(" %d \r\n",dispaly_0);
		dispaly_0++;
	}
	XGpio_InterruptClear(Gpio_11, GPIO_CHANNEL_1);
}
int Gpio_Init(XScuGic *Intc){
	int Status;
	//初始化gpio_1
	Status = XGpio_Initialize(&Gpio_1, GPIO_DEVICE_ID_1);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	//配置gpio_1为输入
	XGpio_SetDataDirection(&Gpio_1,GPIO_CHANNEL_1,1);
	//初始化gpio_3
	Status = XGpio_Initialize(&Gpio_3, GPIO_DEVICE_ID_3);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	//配置gpio_3为输出
	XGpio_SetDataDirection(&Gpio_3,GPIO_CHANNEL_3,0);
	//配置中断类型
	XScuGic_SetPriorityTriggerType(Intc,INTC_GPIO_INTERRUPT_ID_1,0xA0, 0x3);
	//将gpio_1中断连接到中断处理程序1
	Status = XScuGic_Connect(Intc, INTC_GPIO_INTERRUPT_ID_1, (Xil_ExceptionHandler)GpioHandler1, &Gpio_1);
	if (Status != XST_SUCCESS) {
		return Status;
	}
	//在GIC上使能gpio_1中断
	XScuGic_Enable(Intc, INTC_GPIO_INTERRUPT_ID_1);
	//在goio_1上使能中断
	XGpio_InterruptEnable(&Gpio_1, GPIO_CHANNEL_1);
	//在goio_1上使能全局中断
	XGpio_InterruptGlobalEnable(&Gpio_1);
	return XST_SUCCESS;
}

gpio.h

#ifndef __GPIO_H_
#define __GPIO_H_

#include "xscugic.h"

int Gpio_Init(XScuGic *Intc);

#endif

gpio1.c

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

#include "gpio.h"
#include "sleep.h"

#define GPIO_DEVICE_ID_0			XPAR_GPIO_0_DEVICE_ID
#define GPIO_DEVICE_ID_2			XPAR_GPIO_2_DEVICE_ID

#define INTC_GPIO_INTERRUPT_ID_0	XPAR_FABRIC_AXI_GPIO_0_IP2INTC_IRPT_INTR

#define GPIO_CHANNEL_0		1
#define GPIO_CHANNEL_2		1

static XGpio Gpio_0;
static XGpio Gpio_2;

static int dispaly_0 = 0;
u32 InputData;

static void GpioHandler0(void *CallBackRef);

void GpioHandler0(void *CallbackRef)
{
	XGpio *Gpio_00 = (XGpio *)CallbackRef;
	//去抖
	usleep(10);
	//读输入
	InputData = XGpio_DiscreteRead(Gpio_00,GPIO_CHANNEL_0);
	if(InputData == 0x01){
		//设定输出,跳变
		XGpio_DiscreteWrite(&Gpio_2,GPIO_CHANNEL_2,dispaly_0&0x1);
		xil_printf(" %d \r\n",dispaly_0);
		dispaly_0++;
	}
	XGpio_InterruptClear(Gpio_00, GPIO_CHANNEL_0);
}
int Gpio1_Init(XScuGic *Intc){
	int Status;
	//初始化gpio_0
	Status = XGpio_Initialize(&Gpio_0, GPIO_DEVICE_ID_0);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	//配置gpio_0为输入
	XGpio_SetDataDirection(&Gpio_0,GPIO_CHANNEL_0,1);
	//初始化gpio_2
	Status = XGpio_Initialize(&Gpio_2, GPIO_DEVICE_ID_2);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	//配置gpio_2为输出
	XGpio_SetDataDirection(&Gpio_2,GPIO_CHANNEL_2,0);
	//配置中断类型
	XScuGic_SetPriorityTriggerType(Intc,INTC_GPIO_INTERRUPT_ID_0,0xA0, 0x3);
	//将gpio_0中断连接到中断处理程序0
	Status = XScuGic_Connect(Intc, INTC_GPIO_INTERRUPT_ID_0, (Xil_ExceptionHandler)GpioHandler0, &Gpio_0);
	if (Status != XST_SUCCESS) {
		return Status;
	}
	//在GIC上使能gpio_0中断
	XScuGic_Enable(Intc, INTC_GPIO_INTERRUPT_ID_0);
	//在goio_0上使能中断
	XGpio_InterruptEnable(&Gpio_0, GPIO_CHANNEL_0);
	//在goio_0上使能全局中断
	XGpio_InterruptGlobalEnable(&Gpio_0);
	return XST_SUCCESS;
}

gpio1.h

#ifndef __GPIO1_H_
#define __GPIO1_H_

#include "xscugic.h"

int Gpio1_Init(XScuGic *Intc);

#endif

5、现象就是连接gpio_2和gpio_3的两个led随着gpio_0和gpio_1的按压,交替的亮灭。

  • 1
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
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 ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值