AXI_GPIO

news2024/12/27 13:49:35

REVIEW

关于PS端已经学习过:

zynq PS端 GPIO-CSDN博客

zynq PS点灯-CSDN博客

C基础与SDK调试方法-CSDN博客

Zynq上GPIO无论是MIO还是EMIO,都是属于PS侧的资源,相当于是硬核。

而作为一个PS与PL相互协作的平台,当PS侧的GPIO硬核不够用或者无法使用的场合,我们能否使用PL端的逻辑资源来构建一个或多个GPIO软核呢?

AXI_GPIO

1.  今日摸鱼任务

简单学习对 AXI GPIO 核,
并以 AXI GPIO 核为基础,
完成 EDA 拓展板上拨码开关控制 LED 亮灭实验。

小梅哥视频:

12A_AXI_GPIO原理与应用(一)_哔哩哔哩_bilibili

12B_AXI_GPIO原理与应用(二)_哔哩哔哩_bilibili

小梅哥课程笔记:【zynq课程笔记】【裸机】【第12课 】【AXI_GPIO原理与应用】 - ACZ702开发板 - 芯路恒电子技术论坛 - Powered by Discuz! (corecourse.cn)

小梅哥教材:

03_【裸机教程】基于C编程的Zynq裸机程序设计与应用教程v2.4.5.pdf

第三章 基于 AXI GPIO LED 亮灭

2.  AXI 总线接口

AXI ,即 Advanced Extensible Interface(高级可扩展接口),它是由 Arm 定义的接口协议,包含在“高级微控制器总线架构 AMBA”标准中。
AXI是一种总线协议,是一种面向高性能、高带宽、低延迟的片内总线。
它的地址/控制和数据相位是分离的,支持不对齐的数据传输,同时在突发传输中,只需要首地址,同时分离的读写数据通道、并支持 Outstanding 传输访问和乱序访问,并更加容易进行时序收敛。
ZYNQ7000 系列开发板上 AXI 协议,通常指 AXI4 协议。该协议共包含三种接口,也可以说是三种总线,分别为 AXI4 AXI-Lite AXI-Stream ,在 ZYNQ 内部实现着 PS PL 之间的交互,不同接口面向不同的应用场景,分别如下:
AXI4:
(AXI4-Full)
主要面向 高性能地址映射 memory map)通信的需求,是面向地址映射的接口,在单地址传输的情况下最大允许 256 个时钟周期的数据突发长度。
AXI4 总线允许符合 AXI4 的系统实现非常高的数据吞吐量,同时还支持数据大小调整、多个 outstanding 操作和乱序事务处理。
在硬件级别, AXI4 允许为每个 AXI 主从对使用不同的时钟构建系统。
此外, AXI4 协议允许插入寄存器片(通常称为流水线级)以帮助时序收敛。
为了与 AXI4-Lite 区分, AXI4 也被叫作 AXI4-Full
AXI4-Lite:
用于 简单、低吞吐量的内存映射 通信
(例如,与控制寄存器和状态寄存器之间的通信)
是一个轻量级的地址映射单次传输接口,占用很少的逻辑单元。
该接口是 AXI4 接口的简化版,突发长度从 256 被限制到 1,
也就意味着无法进行突发传输,逻辑资源的减少,
也就导致无法实现较为复杂功能。
AXI4-Stream:
主要面向 高速流数据传输
与 AXI4 的区别是没有了地址接口,因此不涉及读写数据的概念,数据只是进行简单的接收与发送。
这种方式减少了传输时的延时,允许无限制的数据突发传输规模。
虽然 ZYNQ 支持这三种总线,
但是在 ZYNQ PS 与 PL 之间仅支持 AXI4 AXI4-Lite 总线
AXI4-Stream 总线只能在 PL 中实现

3.  AXI_GPIO

 Xilinx官方为我们提供了一个名为AXI GPIO的软核。该核使用标准的AXI总线与PS交互,用户可以通过AXI总线,控制AXI GPIO的输入输出模式、输出值、读取指定引脚等。该IP核的结构如下:

从图中可以看出,最右侧有两个具有三态输出功能的端口,分别为GPIO和GPIO2,这也就意味着该控制器可以最多提供2个通道的GPIO。
每个通道的GPIO都有3个标准的信号,也就是输出值(GPIO_O)输入值(GPIO_I)以及管脚输出使能控制信号(GPIO_T)
输出值GPIO_O : 使用一个名为GPIO_DAT的寄存器/D触发器存储所需要输出的值
输入值GPIO_I : 使用一个名为GPIO_DATA_IN的寄存器/D触发器存储GPIO Pin管脚上的值
输出使能控制信号GPIO_T : 使用一个名为GPIO_TRI的寄存器/D触发器存储设置状态

这两个三态缓冲器工作时,其输入输出状态受GPIO_T信号控制。

GPIO_T=0时,为输出态,三态缓冲器会输出GPIO_O的值;

GPIO_T=1时,为输入态,此时GPIO_I的值会输入到AXI GPIO中。

因此,我们只需要通过对这3个寄存器进行读写,就能够实现对该Pin的状态的控制和读取。

这些寄存器由谁读写,又是通过什么方式读写呢?

这个就是我们刚刚提到的,PS通过AXI4-Lite总线来读写这些寄存器。

另外该控制器还提供了中断检测逻辑,以及中断控制寄存器,

用于中断检测以及中断使能/屏蔽/状态显示。

4.  设计流程

本次实验框图:

①配置设置

基础流程可以参照:zynq PS点灯-CSDN博客

本次只记录一些重点:

添加IP核:ZYNQ + AXI GPIO

本次ZYNQ只需要配置DDR:

配置AXI_GPIO核:两通道8位:

快进到配置引脚:使用的是xc7z010clg400-1 + EDA扩展版

生成.xdc .bit   .hdf文件

②Launch SDK

打开 COMMON.h 文件:
添加 AXI_GPIO 的头文件声明:
#include "AXI_GPIO.h"
随后在用户宏定义下添加 AXI GPIO 的器件 ID 宏定义:
#define GPIO_0_ID XPAR_AXI_GPIO_0_DEVICE_ID

main.c
#include"COMMON.h"
int main(void)
{
    uint32_t State;
    AXI_GPIO_Init(&AXI_GPIO0,GPIO_0_ID); //初始化 AXI GPIO0
    //设置通道 1 为输入
    AXI_GPIO_Set_Channel(&AXI_GPIO0, XGPIO_IR_CH1_MASK, 0xFF, 0);
    //设置通道 2为输出
    AXI_GPIO_Set_Channel(&AXI_GPIO0, XGPIO_IR_CH2_MASK, 0x00, 0);
        while(1)
        {
            //读取通道 1 输入的值
            State = XGpio_DiscreteRead(&AXI_GPIO0,XGPIO_IR_CH1_MASK);
            //将通道 2 设置为输出,输出从通道 1 读取的值
            AXI_GPIO_Set_Channel(&AXI_GPIO0, XGPIO_IR_CH2_MASK, 0, State);
        }
        
    return 0;
}
在弹幕里面学到的,字体放大: Ctrl + Shift + '+' 

此时的效果:

拨码开关可控制对应的LED亮灭

5.  代码解析

AXI_GPIO_Init(XGpio *InstPtr, uint16_t DeviceId)
/*****************************************************************************
**  @brief    初始化AXI_GPIO
**  @param    InstPtr        GPIO实例指针
**  @param    DeviceId    GPIO设备ID
**    Sample:    AXI_GPIO_Init(&AXI_GPIO0,GPIO_0_ID);    //初始化AXI GPIO0
*****************************************************************************/
void AXI_GPIO_Init(XGpio *InstPtr, uint16_t DeviceId)
{
    XGpio_Initialize(InstPtr, DeviceId);
}
AXI_GPIO_Set_Channel(XGpio *InstPtr, uint8_t Channel, uint32_t Dri, uint32_t Data)
/*****************************************************************************
**  @brief    设定AXI GPIO某通道的模式与状态
**  @param    InstPtr        GPIO实例指针
**  @param    Channel        GPIO通道,1或2
**  @param    Dir            输入/输出:0为输出,1为输入,每一位表示一个引脚
**  @param    Data        输出电平高低:0为低,1为高,每一位表示一个引脚
**  Sample:    //设置Gpio0的通道1全为输出模式,且全输出为低电平
**          AXI_GPIO_Set_Channel(&AXI_GPIO0, XGPIO_IR_CH1_MASK, 0, 0);
*****************************************************************************/
void AXI_GPIO_Set_Channel(XGpio *InstPtr, uint8_t Channel, uint32_t Dri, uint32_t Data)
{
    XGpio_SetDataDirection(InstPtr, Channel, Dri);
    XGpio_DiscreteWrite(InstPtr, Channel, Data);
}
XGpio_DiscreteRead(XGpio * InstancePtr, unsigned Channel)

/****************************************************************************/
/**
* Read state of discretes for the specified GPIO channnel.
*
* @param    InstancePtr is a pointer to an XGpio instance to be worked on.
* @param    Channel contains the channel of the GPIO (1 or 2) to operate on.
*
* @return    Current copy of the discretes register.
*
* @note        The hardware must be built for dual channels if this function
*        is used with any channel other than 1.  If it is not, this
*        function will assert.
*
*****************************************************************************/
u32 XGpio_DiscreteRead(XGpio * InstancePtr, unsigned Channel)
{
    Xil_AssertNonvoid(InstancePtr != NULL);
    Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
    Xil_AssertNonvoid((Channel == 1) ||
            ((Channel == 2) && (InstancePtr->IsDual == TRUE)));

    return XGpio_ReadReg(InstancePtr->BaseAddress,
                  ((Channel - 1) * XGPIO_CHAN_OFFSET) +
                  XGPIO_DATA_OFFSET);
}

算法流程大致相同:

        初始化GPIO驱动程序

        设置指定引脚方向

        读/写指定管脚的值/状态

不同点

PS GPIO在输出指定管脚的值/状态时,需要先使能该引脚作为输出。

而在硬件逻辑系统设计方面,AXI GPIO则是与EMIO类似,由于使用的是PL端引脚,在导出后还需要进行管脚分配和约束。

尝试控制单个Pin

#include"COMMON.h"
int main(void)
{
    uint32_t State;
    AXI_GPIO_Init(&AXI_GPIO0,GPIO_0_ID); //初始化 AXI GPIO0
    //设置通道 1 为输入
    AXI_GPIO_Set_Channel(&AXI_GPIO0, XGPIO_IR_CH1_MASK, 0xFF, 0);
    //设置通道 2为输出
    AXI_GPIO_Set_Channel(&AXI_GPIO0, XGPIO_IR_CH2_MASK, 0x00, 0);
        while(1)
        {
            //读取通道 1 ,拨码开关7输入的值
            State = AXI_GPIO_GetPin(&AXI_GPIO0, XGPIO_IR_CH1_MASK,7);
            //通道 2 ,led5设置为输出,输出从通道 1 拨码开关7读取的值
            AXI_GPIO_SetPin(&AXI_GPIO0, XGPIO_IR_CH2_MASK, 5, State);
        }

    return 0;
}

6. 小作业

配置AXI GPIO为单通道16位位宽,

通过软件编程,将高8位配置为输入,获取拨码开关电平;

将低8位设置为输出,使用从拨码开关获取的电平控制LED,

实现拨码开关控制LED亮灭设计。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1809821.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用opencv在图像上画带刻度线的对角线,以图像中心点为0点

使用OpenCV在图像上绘制带刻度线的对角线,可以通过以下步骤实现。我们将首先找到图像的中心点,然后绘制对角线线,并在这些线的适当位置绘制刻度线。以下是详细的C代码示例: void Draw_diagonal(cv::Mat& mat, double dFactor…

【Python教程】4-字符串、列表、字典、元组与集合操作

在整理自己的笔记的时候发现了当年学习python时候整理的笔记,稍微整理一下,分享出来,方便记录和查看吧。个人觉得如果想简单了解一名语言或者技术,最简单的方式就是通过菜鸟教程去学习一下。今后会从python开始重新更新&#xff0…

shell编程(四)—— 运算符

和其他编程语言一样,bash也有多种类型的运算符,本篇对bash的相关运算符做简单介绍。 一、运算符 1.1 算术运算符 常见的算术运算符,如加()、减(-)、乘(*)、除&#xf…

Qt安装时出现无法下载存档,环境配置,main中自定义类编译不过问题

1. Qt安装时出现无法下载存档 进入Qt安装程序exe所在的文件目录,一般在下载文件夹,右键打开cmd。cmd输入:对应的exe镜像提速。 .\qt-online-installer-windows-x64-4.8.0.exe --mirror https://mirrors.cloud.tencent.com/qt/ 2. 环境配置 …

统计信号处理基础 习题解答10-11

题目 我们希望根据一个人的身高来估计他的体重。为了判断其可行性,对N100个人取数据,产生有序的数据对(h,w),其中h代表身高,w代表体重。得到的数据如图10.9(a)所示的。解释你如何利用MMSE估计量根据一个人的身高来猜测他的体重。对于这些数据的建模有些什么样的假设…

6、后端项目初始化

打开idea后, New Project ,用Maven构建 Spring Boot 项目 点击Next后:先勾选两个基本的依赖,后面再手动添加其它需要的依赖 Spring Web: 表示是一个web应用程序 Lombok:写实体类的时候添加Data注解后就会自动加上g…

npm install 的原理

1. 执行命令发生了什么 ? 执行命令后,会将安装相关的依赖,依赖会存放在根目录的node_modules下,默认采用扁平化的方式安装,排序规则为:bin文件夹为第一个,然后是开头系列的文件夹,后…

关于头条项目经验面试题的总结

文章目录 前言一、论坛项目经典话术二、请你介绍一下你最近的项目吧2.1 话术1 三、你的公司的开发环境是怎么搭建的?四、登录你们是怎么做的?4.1 账号密码登录4.2 手机验证码发送4.2.1 手机验证码发送4.2.2 手机验证码登录 五、用户行为限流是怎么做的&a…

Java面向对象-方法的重写、super

Java面向对象-方法的重写、super 一、方法的重写二、super关键字1、super可以省略2、super不可以省略3、super修饰构造器4、继承条件下构造方法的执行过程 一、方法的重写 1、发生在子类和父类中,当子类对父类提供的方法不满意的时候,要对父类的方法进行…

1000道互联网大厂面试题:ZooKeeper+Dubbo+Spring+MySQL等(含答案)

然后存储回内存,这个过程可能会出现多个线程交差。 24、a a b 与 a b 的区别 25、我能在不进行强制转换的情况下将一个 double 值赋值给 long类型的变量吗? 26、3*0.1 0.3 将会返回什么?true 还是 false? 27、int 和 Inte…

C语言学生管理系统

整理U盘发现一个C语言写的学生管理系统&#xff0c;全部代码放放我上传的资源里了 #include<stdio.h> #include<stdlib.h> #include<string.h>//需要用到strcmp函数#define LEN 15//姓名和学号的最大字符数 #define N 50//最大学生人数int n 0, t 1;//n代表…

企业微信应用 应用号内消息链接无法在企微内置浏览器打开 windows PC客户端 问题解决

问题 需求是每周在企微的应用号上发送周报&#xff0c;周报中会带着进入系统的链接&#xff0c;点击进入可以查看详情。系统需要登录鉴权&#xff0c;因此需要在内置浏览器打开便于自动认证。 但是&#xff0c;在企微应用号发送的链接&#xff0c;手机上可以正常使用企微内置…

【Vue】请求动态渲染数据

目标 请求获取数据存入 vuex, 映射渲染 安装 axios yarn add axios准备actions 和 mutations App.vue页面中调用 action, 获取数据 验证数据是否存储成功 动态渲染 cart-item.vue

现实转虚拟:Video2Game引领3D互动体验

在当今数字化时代&#xff0c;虚拟环境的创建对于游戏开发、虚拟现实应用和自动驾驶模拟器等多个领域至关重要。然而&#xff0c;传统的虚拟环境创建过程不仅复杂而且成本高昂&#xff0c;通常需要专业人员和专业软件开发工具的参与。例如&#xff0c;著名的《侠盗猎车手V》以其…

Java_中间件——Redis

Redis 介绍&#xff1a; Redis是一个基于内存的key-value结构数据库&#xff08;MySQL是通过数据文件方式存储在磁盘上&#xff0c;数据结构是二维表&#xff09; 特点&#xff1a; 更改配置文件&#xff1a; 使用密码&#xff1a; redis默认是不需要密码的&#xff0c;如果…

苹果WWDC大会AI亮点:大揭晓

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

vscode 中 eslint 无效?npm init 是什么?

vscode 中 eslint 无效 我想要给一个项目添加 eslint&#xff0c;按照 eslint 官方指南操作&#xff1a; npm init eslint/configlatest自动安装了相关依赖并创建配置文件 eslint.config.mjs。 按理说&#xff0c;此刻项目应该已经配置好 eslint 了。但是我的编辑器 vscode …

初识springclould到生产者消费者的RPC通信

SpringClould SpringBoot和SpringClould搭建springcloud创建项目管理实体类模块服务提供者模块消费者 Eureka 服务注册与发现 SpringBoot和SpringClould springboot和springclould都是spring系列的衍生品&#xff0c;都可以在spring的官网找到对应的参考文档和学习路线以及核心…

贪心算法06(leetcode738,968)

参考资料&#xff1a; https://programmercarl.com/0738.%E5%8D%95%E8%B0%83%E9%80%92%E5%A2%9E%E7%9A%84%E6%95%B0%E5%AD%97.html 738. 单调递增的数字 题目描述&#xff1a; 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。…

Python 学习flask创建项目

1、使用pycharm创建flask项目 2、运行访问地址 3、可以看到访问地址内容 4、可以增加路由&#xff0c;尝试访问获取参数