ZYNQ7000-AXI GPIO详解

2023-05-16

摘要

AXI GPIO是ZYNQ的一个IP核,它能够将PS侧的AXI4-Lite接口转成PL侧的IO口,可解决PS侧IO口不够用的问题。本文就AXI GPIO的概念、作用、配置与使用做了详细说明,展示了示例的Vivado工程和AXI GPIO输入、输出与中断配置的代码。

关键词:AXI GPIOZYNQAXI4-LiteGPIO中断

前言

本文参考:PG144 - AXI GPIO v2.0 Product Guide (v2.0)

一. AXI GPIO的概念与作用

AXI GPIO是ZYNQ PL部分的一个IP软核,此IP核提供AXI-Lite Master接口转GPIO的功能,且一个AXI-Lite Master通过AXI interconnect可以与多个AXI GPIO IP核相连,如下图所示。也就是说PS部分通过GP接口以及AXI GPIO IP核可实现多个GPIO,一个GP接口最多可以接几个AXI GPIO IP核我不知道,手册中没写,我这里接了4个没什么问题。.

我们知道ZYNQ的PS可通过EMIO来使用PL部分的引脚实现GPIO功能,但当使用的引脚很多时,PS程序中控制引脚方向、中断等将变得繁琐,这时如果使用PS的GP接口(AXI3 Master)接口通过AXI Interconnect连接AXI GPIO IP核,就可以在PS部分通过更简单的程序方便地控制众多PL引脚实现GPIO功能。

所以,从功能上来说,PS通过EMIO还是AXI GPIO来实现GPIO没有区别,都能输入/输出以及产生中断,但AXI GPIO在多引脚时在程序的复杂度方面有一定优势

二. AXI GPIO IP核设置与使用

2.1 AXI GPIO的最大工作时钟频率

需要注意,AXI GPIO的AXI-Lite接口的时钟频率,超频可能会导致此IP核无法正常工作

2.2 AXI GPIO设置

AXI GPIO IP核默认为单通道,可选GPIO宽度为1~32,可设置GPIO方向(注意如果在这里设置了All Input/Output,那么在PS程序中就无需再设置GPIO方向,设置了也无效,建议不要在这里设置,通过PS程序去设置,保持灵活性),可设置输出默认值与三态默认值。

可勾选Enable Dual Channel,打开双通道。

可勾选Enable Interrupt,打开GPIO中断功能,此中断属于PL对PS的中断,所以需要连接到ZYNQ7核的IRQ_F2P端口,如下图所示。

因为使用了AXI接口,我们知道AXI是读写数据的,它必须对应存储器(RAM,DDR等),所以在设置好IP核并连线完成后,需要对每个AXI GPIO的S_AXI进行存储器地址映射,规定S_AXI去读写哪个地址段。

打开Address Editor窗口,右击选择Assign All即可。

效果如下图。

这里需要说明,因为在PS的库函数中对多个AXI GPIO的情况是有排序的(在xparameters.h中每个AXI GPIO对应不同的ID,如下图),我们需要知道PL的Block Design中哪个AXI GPIO对应PS库中的AXI GPIO 0,哪个对应AXI GPIO 1。

这里的排序依据是ip核的名称,与同GP0接口相连还是GP1接口相连没有关系,PS并不区分axi gpio与哪个GP相连。axi_gpio_0会被设为ID 0,ID从0开始向后排,若不存在axi_gpio_0,则axi_gpio_1会被设为ID 0,以此类推

明白PL中的axi gpio与PS库函数中的ID的对应关系是重要的,它帮助我们对引脚命名,以及在PS中操作我们想操作的GPIO。

2.3 关于AXI GPIO中断的细节

注意:

1.AXI GPIO只能使能整个通道中断,而无法像EMIO一样单独使能通道中某个引脚的中断,当使能某个通道中断后,该通道所有输入引脚均能产生中断信号,效果完全相同。

一种可行的将中断固定到引脚的办法是设置通道中其它引脚为输出,输出引脚无法产生中断,中断就相当于固定到了唯一的输入引脚上,

2.因为AXI GPIO中断属于IRQ_F2P,而IRQ_F2P的中断类型只能设置为上升沿或者高电平,而不能是下降沿或者低电平。如下图(参考ug585 Table7-4)。

三. 在PS中控制AXI GPIO输入、输出与中断

3.1 AXI GPIO作为输入输出使用,不使用中断

步骤:初始化AXI GPIO -> 设置AXI GPIO方向 -> 读/写AXI GPIO

#include "xgpio.h"
#include "sleep.h"

#define AXIGPIO_CHANNEL_1    1U
#define AXIGPIO_CHANNEL_2    2U

XGpio axiGpio0;
XGpio axiGpio1;

int main(void)
{
	// 初始化AXI GPIO
	XGpio_Initialize(&axiGpio0, XPAR_GPIO_0_DEVICE_ID);
	XGpio_Initialize(&axiGpio1, XPAR_GPIO_1_DEVICE_ID);

	// 设置AXI GPIO的方向,对应位为0表示输出,为1表示输入
	XGpio_SetDataDirection(&axiGpio0, AXIGPIO_CHANNEL_1, 0x0); // 设置axiGpio0的通道1为全输出
	XGpio_SetDataDirection(&axiGpio1, AXIGPIO_CHANNEL_2, 0xFFFF0000); // 设置axiGpio1的通道2高16位输入,低16位输出

	u32 axiGpio1_ch2_data = 0;
	while(1)
	{
		sleep(1);
		XGpio_DiscreteWrite(&axiGpio0, AXIGPIO_CHANNEL_1, 0x3); // 向axiGpio0的通道1的第0位和第1位写1

		axiGpio1_ch2_data = XGpio_DiscreteRead(&axiGpio1, AXIGPIO_CHANNEL_2); // 读取axiGpio1的通道2的值,输出引脚也可读
		sleep(1);
	}

	return 0;
}

3.2 使用AXI GPIO中断

步骤:初始化AXI GPIO -> 打开系统的中断处理功能 -> 初始化中断控制器 -> 设置中断优先级与类型,关联中断处理函数 -> 使能中断

#include "xgpio.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "sleep.h"


#define AXIGPIO_CHANNEL_1    1U
#define AXIGPIO_CHANNEL_2    2U

#define AXIGPIO_IRQ_TYPE_HIGH   1U
#define AXIGPIO_IRQ_TYPE_PEDGE  3U

#define AXIGPIO_IRQ_PRIORITY  128U


XGpio axiGpio0;
XScuGic scuGic;

void axiGpio0_Handler(void *CallbackRef);

int axiGpio0_intrFlag = 0;


int main(void)
{
	// 初始化AXI GPIO
	XGpio_Initialize(&axiGpio0, XPAR_GPIO_0_DEVICE_ID);

	// 打开系统的中断处理功能
	Xil_ExceptionInit(); // 初始化异常句柄,只在很早版本的bsp中需要,此处为了兼容性保留
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, &scuGic);
	Xil_ExceptionEnable(); // 使能系统中断

	// 初始化中断控制器
	XScuGic_Config *scuGicConfig;
	scuGicConfig = XScuGic_LookupConfig(XPAR_XSCUTIMER_0_DEVICE_ID); // 根据器件ID查找配置
	XScuGic_CfgInitialize(&scuGic, scuGicConfig, scuGicConfig->CpuBaseAddress);

	// 设置对应ID中断的的优先级与触发类型
	XScuGic_SetPriorityTriggerType(&scuGic, XPAR_FABRIC_GPIO_0_VEC_ID, AXIGPIO_IRQ_PRIORITY, AXIGPIO_IRQ_TYPE_HIGH);
	// 连接中断ID与中断服务函数
	XScuGic_Connect(&scuGic, XPAR_FABRIC_GPIO_0_VEC_ID, (Xil_InterruptHandler)axiGpio0_Handler, &axiGpio0);
	// 启用对应中断ID的中断源
	XScuGic_Enable(&scuGic, XPAR_FABRIC_GPIO_0_VEC_ID);

	// 启动AXI GPIO中断
	XGpio_InterruptGlobalEnable(&axiGpio0);
	// 使能对应通道的中断
	XGpio_InterruptEnable(&axiGpio0, AXIGPIO_CHANNEL_1);

	while(1)
	{
		sleep(1);

		if (axiGpio0_intrFlag)
		{
			xil_printf("This is axiGpio0 interrupt!");

			axiGpio0_intrFlag = 0; // 复原中断标志
			XGpio_InterruptEnable(&axiGpio0, AXIGPIO_CHANNEL_1); // 重新使能中断
		}

		sleep(1);
	}

	return 0;
}


void axiGpio0_Handler(void *CallbackRef)
{
	XGpio *axiGpioPtr = (XGpio *)CallbackRef;

	axiGpio0_intrFlag = 1;

	// 关闭中断
	XGpio_InterruptDisable(axiGpioPtr, AXIGPIO_CHANNEL_1);

	// 清除中断寄存器,不清除无法再次进入中断
	XGpio_InterruptClear(axiGpioPtr, AXIGPIO_CHANNEL_1);
}


徐晓康的博客持续分享高质量硬件、FPGA与嵌入式知识,软件,工具等内容,欢迎大家关注。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ZYNQ7000-AXI GPIO详解 的相关文章

随机推荐

  • yum 安装libpcap

    针对于centos系统安装libpcap库命令 xff1a yum install libpcap yum install libpcap devel
  • 计算机网络自考2020,2020年8月自考02141计算机网络技术真题及答案

    以下是湖南自考生网为考生们整理的 2020年8月自考02141计算机网络技术真题及答案 xff0c 考生可通过自考历年真题练习更有把握的面对考试 xff0c 对题型更加熟悉 xff0c 从而取得更佳的成绩 供考生参考 2020年8月高等教育
  • DLL丢失一键修复

    DLL丢失一键修复 今天不小心删了DLL相关的库 xff0c 费了好久才搞好 xff0c 记录一下 原因 xff1a 删除了win10中的这些库 解决办法 xff1a 使用一键修复工具 DLL丢失一键修复工具 xff1a 获取工具
  • springmvc的配置文件详解

    springmvc xml需要配置的东西 配置controller扫描包 使用组件扫描器省去在spring容器配置每个Controller类的繁琐 使用context component scan自动扫描标记 64 Controller的控
  • Bug随手记----关于java.lang.IllegalStateException: The following classes could not be excluded because the

    Consider the following If you want an embedded database H2 HSQL or Derby please put it on the classpath If you have data
  • linux:Systemd使用(systemctl)

    系统服务管理工具systemd是为了便于linux用户操作系统服务的管理 xff0c systemd提供了systemctl命令工具进行systemd的各项操作 Systemd的版本 systemd version systemd和syst
  • C++面试宝典:进程间通讯方式概述

    1 管道 我们来看一条 Linux 的语句 netstat tulnp grep 8080 学过 Linux 命名的估计都懂这条语句的含义 xff0c 其中 是管道的意思 xff0c 它的作用就是把前一条命令的输出作为后一条命令的输入 在这
  • ubuntu16.04LTS更换阿里源

    sudo gedit etc apt sources list 替换 xff1a 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 deb cdrom Ubuntu 16 04 LTS Xenial
  • a++多线程下出现消失的请求现象

    a 43 43 多线程下出现消失的请求现象 a 43 43 多线程下出现消失的请求现象是一个常见的多线程运行结果错误的例子 我们先来看一下a 43 43 代码执行图 xff1a 按照我们想让它执行的顺序执行 xff0c 结果应该是3 但在多
  • 2013年十佳优秀主席将获得传智播客.NET学院培训名额

    2013年CSDN高校俱乐部十佳优秀主席将会免费获得价值9580元的传智播客 NET学院免费培训名额 培训时间为2015年之前有效 优秀主席评选截止日期为10月底 截止日期之前请提交你的评选内容 评选内容是俱乐部介绍 自我介绍和俱乐部活动介
  • MySQL各数据类型的特点

    MySQL各数据类型的特点 常用的整数类型 常见误区 int n 是设置数据最大的显示宽度 xff0c 所占的存储空间不会改变 常用的浮点类型 123456789 987654321 61 decimal 18 9 占用9个字节 涉及财务等
  • Redis持久化——RDB、AOF

    Redis持久化 RDB AOF 什么是持久化 redis所有数据都保存在内存中 xff0c 对数据的更新异步保存到磁盘上 在Redis中持久化的方式有两种 xff0c 一种是快照持久化 xff0c 一种是AOF持久化 xff0c 各有各的
  • Redis主从复制—看完这篇你就懂了

    Redis主从复制 主从复制 xff0c 是指将一台Redis服务器的数据 xff0c 复制到其他的Redis服务器 前者称为主节点 master leader xff0c 后者称为从节点 slave follower xff1b 数据的复
  • 轻松搞定单例模式以及线程安全等问题

    单例模式 单例模式 xff08 Singleton Pattern xff09 是 Java 中最简单的设计模式之一 这种类型的设计模式属于创建型模式 xff0c 它提供了一种创建对象的最佳方式 这种模式涉及到一个单一的类 xff0c 该类
  • 设计模式之原型模式

    原型模式 定义 xff1a 指原型实例指定创建对象的种类 xff0c 并且通过拷贝这些原型创建新的对象 不需要知道任何创建的细节 xff0c 不需要调用构造函数类型 xff1a 创建型 适用的场景 类初始化消耗较多资源 xff08 比较重的
  • 设计模式之外观模式

    外观模式 概念介绍 定义与类型 定义 xff1a 又叫门面模式 xff0c 提供了一个统一的接口 xff0c 用来访问子系统中的一群接口外观模式定义了一个高层接口 xff0c 这个接口使得子系统更容易被访问或者使用类型 xff1a 结构型
  • Mac无法连接本地Linux服务器 无法ping通

    遇到的问题 xff1a 虚拟机是从Win环境下复制到Mac上的 xff0c 在Win电脑下可以直接使用Xshell远程连接 xff0c 但在Mac下 xff0c 无法连接而且Ping不通 虚拟机使用的是CentOS 7版本 解决方案 查看M
  • gazebo视角设置问题

    How can I make my objects robot appear in image raw topic when using Gazebo camera plugin Initial view after gazebo star
  • DISM命令使用小结

    DISM命令使用小结 文章目录 DISM命令使用小结操作WIM镜像说明演示 操作系统映像说明添加功能启用本地策略启用Hyper V 操作WIM镜像 说明 REM 制作镜像并添加一个分卷 dism capture image imagefil
  • ZYNQ7000-AXI GPIO详解

    摘要 AXI GPIO是ZYNQ的一个IP核 xff0c 它能够将PS侧的AXI4 Lite接口转成PL侧的IO口 xff0c 可解决PS侧IO口不够用的问题 本文就AXI GPIO的概念 作用 配置与使用做了详细说明 xff0c 展示了示