ZYNQ学习之旅--PS_AXIGPIO

这里写目录标题

简介

在本实验中,我们将在硬件设计时添加一个 AXI GPIO 的 IP 核。IP 的定义为“用于 ASIC 或 FPGA 中的预先设计好的电路功能模块”。IP 主要分为软 IP、固 IP 和硬 IP。软 IP 是用 Verilog/VHDL 等硬件描述语言描述的功能块,但是并不涉及用什么具体电路元件实现这些功能。固 IP 是完成了综合的功能块。硬 IP 提供设计的最终阶段产品——掩膜。
AXI GPIO 就是一个软 IP,它通过使用 PL 端的逻辑资源来实现我们需要的功能,实际上在芯片中并不存在这样一个电路。这与 PS 端的 GPIO 不同,PS 端的 GPIO 是一个实际的电路。在官方资料中我们可以看到 AXI GPIO 的结构框图如下图所示,从结构框图中我们可以看到模块通过一个 AXI4-Lite 来实现主机对模块的访问,来读取和配置 AXI GPIO 内的各个寄存器,同时,模块还可以产生中断信号来通知主机中断事件的发生。另外可以看到 AXI GPIO 有两个通道,可以配置为单通道或双通道模式。各个I/O既可以在软件上配置也可以在硬件设计时被动的配置为输入或输出。
在这里插入图片描述

BD硬件设计

在这里插入图片描述
BD设计也比较简单,加入ZYNQ核和一个AXI_GPIO核,然后自动连线就好了。

软件设计

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include <xgpiops.h>
#include "xgpio.h"
#include "xil_exception.h"
#include "xscugic.h"
#include <xil_types.h>
#include <sleep.h>

#define		AXI_GPIO_ID XPAR_GPIO_0_DEVICE_ID
#define		PS_GPIO_ID	XPAR_XGPIOPS_0_DEVICE_ID
#define		AXI_INT_ID	XPAR_FABRIC_GPIO_0_VEC_ID
#define		SGC_ID		XPAR_PS7_SCUGIC_0_DEVICE_ID
#define		PS_LED		50
XGpioPs gpiops;
XGpioPs_Config *gpiops_config;
XGpio axi_gpio;
XScuGic_Config *SCG_config;
XScuGic SGC_inst;
void AXI_Handler(void *callback);
u32 init();
u32 setup();
int data = 0x0;

int main()
{
    init_platform();
    print("Hello World\n\r");
    init();
    setup();
    cleanup_platform();
    return 0;
}

u32 init(){
	u32 status;
	//PS端的led进行初始化
	gpiops_config = XGpioPs_LookupConfig(PS_GPIO_ID);
	status = XGpioPs_CfgInitialize(&gpiops, gpiops_config,
			gpiops_config->BaseAddr);
	if(status!=XST_SUCCESS){
		print("failed\n");
		return XST_FAILURE;
	}
	//对AXI_GPIO进行初始化
	status = XGpio_Initialize(&axi_gpio, AXI_GPIO_ID);
	if(status!=XST_SUCCESS){
		print("failed\n");
		return XST_FAILURE;
	}

	return  0;
}

u32 setup(){
	u32 status;
	XGpio_SetDataDirection(&axi_gpio, 0x1,
				    0x1);
	XGpioPs_SetDirectionPin(&gpiops, PS_LED, 0x1);
	XGpioPs_SetOutputEnablePin(&gpiops, PS_LED, 0x1);
	XGpioPs_WritePin(&gpiops, PS_LED, 0x0);
	XGpio_InterruptEnable(&axi_gpio, 0x1);
	XGpio_InterruptGlobalEnable(&axi_gpio);
	SCG_config = XScuGic_LookupConfig(SGC_ID);
	status = XScuGic_CfgInitialize(&SGC_inst, SCG_config,
			SCG_config->CpuBaseAddress);
	if(status!=XST_SUCCESS){
		print("failed\n");
		return XST_FAILURE;
	}
	//中断优先级和触发方式设置
	XScuGic_SetPriorityTriggerType(&SGC_inst, AXI_INT_ID,
						0xA0, 0x1);
	//异常中断处理部分
	Xil_ExceptionInit();
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
						 (Xil_ExceptionHandler)XScuGic_InterruptHandler,
						 &SGC_inst);
	Xil_ExceptionEnable();
	//设置中断控制器的回调函数,打开中断控制器的使能
	XScuGic_Connect(&SGC_inst, AXI_INT_ID,
				(Xil_InterruptHandler)AXI_Handler, &axi_gpio);
	XScuGic_Enable(&SGC_inst, AXI_INT_ID);
	return 0;
}

 void AXI_Handler(void *callback){
	 int key_value;
	 XGpio *xgpio_axi = (XGpio *)callback;
	 print("产生中断\n");
	 key_value = XGpio_DiscreteRead(xgpio_axi, 0x1);
	 XGpio_InterruptDisable(xgpio_axi,0x1);
	 usleep(20000);
	 if(key_value == 0){
		 data = ~data;
		 XGpioPs_WritePin(&gpiops,PS_LED , data);
	 }
	 XGpio_InterruptClear(xgpio_axi, 0x1);
	 XGpio_InterruptEnable(xgpio_axi, 0x1);
 }

利用AXI_GPIO产生中断控制PS端的LED。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值