ZYNQ-Vitis(SDK)裸机开发之(四)PS端MIO和EMIO的使用
目录
一、ZYNQ中MIO和EMIO简介
二、Vivado中搭建block design
1.配置PS端MIO:
2.配置PS端EMIO:
三、Vitis中新建工程进行GPIO控制
1. GPIO操作头文件gpio_hdl.h:
2.GPIO操作源文件gpio_hdl.c:
3.main函数进行调用
例程开发环境:
SOC芯片:ZYNQ7020
开发环境:Vivado2020.2,Vitis2020.2
一、ZYNQ中MIO和EMIO简介
以ZYNQ7020为例,GPIO总共118个,分为了4个bank(ZU+的GPIO和bank数量有所增加),其中MIO有两个bank,需要注意的是bank1的GPIO数量只有22个,其余三个都有32个。
MIO和EMIO均为PS端的GPIO,由PS控制,其中MIO可直接配置复用成PS外设,而EMIO则可以连接到PL端,复用为PL端搭建的外设资源

-
二、Vivado中搭建block design
Vivado工程详细搭建方法,可见以下文章:
ZYNQ-Linux开发之(二)Vivado工程搭建、Block Design设计搭建、PS、PL的IP核的使用配置
该工程是在ZYNQ-Vitis(SDK)裸机开发之(一)基础上进行的修改,具体文件见如下连接:
ZYNQ-Vitis(SDK)裸机开发之(一)串口收发使用:PS串口+PL串口、多个串口使用方法
1.配置PS端MIO:
双击IP核进行配置,选择MIO Configuration-----I/O Peripherals-----GPIO MIO,勾选后,默认全部MIO都启用
PS端的MIO是不需要在XDC文件中进行约束的,可直接使用


我的板卡使用的是MIO7和MIO8,分别控制两个LED灯,需要根据自己的原理图进行选择


2.配置PS端EMIO:
双击IP核进行配置,选择MIO Configuration-----I/O Peripherals-----GPIO EMIO,勾选后,选取使用的EMIO个数,我这选择使用4个EMIO,其中两个用来控制PL端的LED,剩余两个用作其他使用,这里不用管。

勾选EMIO后,要将连接LED的PL端引脚与EMIO进行约束,这样才能通过EMIO来控制PL端LED的亮灭,值得注意的是,选取EMIO后,系统默认是从GPIO0开始使用,约束的话也要从GPIO[0]开始约束,在XDC文件中增加管脚约束,具体对应引脚需要根据自己项目的硬件原理图确定,我的PL端两个LED分别连接到了L15和H15,对应XDC文件中约束到GPIO[0]和GPIO[1]上如下:


-
三、Vitis中新建工程进行GPIO控制
1. GPIO操作头文件gpio_hdl.h:
(1)定义GPIO初始化以及配置使用的实例(多个GPIO其实可以公用同一个实例,这里为了方便分区才每个GPIO都实例化了一个结构体)
(2)使用宏定义重新定义PS GPIO的外设ID号
(3)定义工程中使用到的GPIO号,这里有个需要注意的地方,在第一章节就说明了,GPIO分为4个bank,其中0、1bank是MIO,2、3bank是EMIO,工程中使用了两个MIO和两个EMIO,那么这四个GPIO对应的IO号并不是连续的,参见如下关系可知,本工程中MIO对应的GPIO号是7、8,EMIO对应的GPIO号是54、55(因为在vivado中约束时,将PL端的LED约束到了EMIO的[0]和[1]上,从bank的开头数起,对应bank2上的GPIO号即54、55)
/*
* Max pins in the GPIO device ZYNQ
* 0 - 31, Bank 0
* 32 - 53, Bank 1
* 54 - 85, Bank 2
* 86 - 117, Bank 3
*/
(4)定义一些枚举变量,用来表示GPIO的输入输出方向、电平的高低、以及是否使能状态等
(5)声明一些GPIO操作相关的函数,例如GPIO初始化、GPIO点评输出、GPIO输入等操作函数
/*!\file gpio_hdl.h\brief firmware functions to manage gpio\version 2024-04-10, V1.0.0\author tbj
*/#ifndef GPIO_HDL_H
#define GPIO_HDL_H#include "xgpiops.h"#ifdef __cplusplusextern "C" {
#endif//GPIO初始化实例
XGpioPs MIOLed0, MIOLed1, EMIOLed0, EMIOLed1;//GPIO外设地址ID
#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID//LED灯对应的PS和PL的IO
#define LED0_GPIO_PS_MIO 7
#define LED1_GPIO_PS_MIO 8
#define LED0_GPIO_PL_EMIO 55
#define LED1_GPIO_PL_EMIO 54typedef enum{GPIO_DIR_INPUT = 0,GPIO_DIR_OUTPUT,
}GPIO_DIR;typedef enum{GPIO_VALUE_OFF = 0,GPIO_VALUE_ON,
}GPIO_VALUE;typedef enum{GPIO_DISABLE = 0,GPIO_ENABLE,
}GPIO_EN_STU;//初始化GPIO
int gpio_polled_init(XGpioPs * Gpio_Ptr, u32 Gpio_Pin, GPIO_DIR Gpio_dir, GPIO_VALUE Gpio_init_value,GPIO_EN_STU Gpio_en);
//设置GPIO输出
int set_gpio_value(XGpioPs * Gpio_Ptr, u32 Gpio_Pin, GPIO_VALUE Gpio_value);
//读取GPIO输入
int read_gpio_value(XGpioPs * Gpio_Ptr, u32 Gpio_Pin, GPIO_VALUE *Gpio_value);#ifdef __cplusplus
}
#endif#endif /* GPIO_HDL_H */
2.GPIO操作源文件gpio_hdl.c:
(1)分别对头文件中声明的三个GPIO相关函数进行了实现
/*!\file gpio_hdl.c\brief firmware functions to manage gpio\version 2024-04-10, V1.0.0\author tbj
*/#include "gpio_hdl.h"//GPIO初始化实例,因为EMIO也属于PS,所以都使用XGpioPs结构体(多个GPIO也可以只初始化一个实例共用)/* 功能:gpio初始化函数* 参数1:GpioPtr-GPIO对象指针* 参数2:Gpio_Pin-GPIO对应pin* 参数3:Gpio_dir-GPIO方向,输入还是输出* 参数4:Gpio_init_value-GPIO初始化值* 参数5:Gpio_en-GPIO是否使能* 说明:Gpio_init_value和Gpio_en,只有配置输出时有效,配置为输入模式时,可以随意填写*/
int gpio_polled_init(XGpioPs * Gpio_Ptr, u32 Gpio_Pin, GPIO_DIR Gpio_dir, GPIO_VALUE Gpio_init_value,GPIO_EN_STU Gpio_en){int Status;XGpioPs_Config *ConfigPtr;ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);Status = XGpioPs_CfgInitialize(Gpio_Ptr, ConfigPtr,ConfigPtr->BaseAddr);if (Status != XST_SUCCESS) {return XST_FAILURE;}//配置GPIO的输入输出模式XGpioPs_SetDirectionPin(Gpio_Ptr, Gpio_Pin, Gpio_dir);//如果GPIO配置为输出模式,还要配置使能和默认输出值if(Gpio_dir == GPIO_DIR_OUTPUT){//使能输出的GPIOXGpioPs_SetOutputEnablePin(Gpio_Ptr, Gpio_Pin, Gpio_en);//初始化GPIO的值XGpioPs_WritePin(Gpio_Ptr, Gpio_Pin, Gpio_init_value);}/** Max pins in the ZynqMP GPIO device ZU+* 0 - 25, Bank 0* 26 - 51, Bank 1* 52 - 77, Bank 2* 78 - 109, Bank 3* 110 - 141, Bank 4* 142 - 173, Bank 5*//** Max pins in the GPIO device ZYNQ* 0 - 31, Bank 0* 32 - 53, Bank 1* 54 - 85, Bank 2* 86 - 117, Bank 3*/return XST_SUCCESS;
}/* 功能:设置GPIO的值* 参数1:GpioPtr-GPIO对象指针* 参数2:Gpio_Pin-GPIO对应pin* 参数3:Gpio_value-GPIO输出值*/
int set_gpio_value(XGpioPs * Gpio_Ptr, u32 Gpio_Pin, GPIO_VALUE Gpio_value){u32 Data;XGpioPs_WritePin(Gpio_Ptr, Gpio_Pin, Gpio_value);Data = XGpioPs_ReadPin(Gpio_Ptr, Gpio_Pin);if (Data != Gpio_value) {return XST_FAILURE;}return XST_SUCCESS;
}/* 功能:读取GPIO的值* 参数1:GpioPtr-GPIO对象指针* 参数2:Gpio_Pin-GPIO对应pin* 参数3:Gpio_value-GPIO读取值*/
int read_gpio_value(XGpioPs * Gpio_Ptr, u32 Gpio_Pin, GPIO_VALUE *Gpio_value){*Gpio_value = (GPIO_VALUE)XGpioPs_ReadPin(Gpio_Ptr, Gpio_Pin);return XST_SUCCESS;
}
3.main函数进行调用
(1)初始化GPIO相关状态,进行输入输出、使能等配置
(2)每隔1秒进行LED等的亮灭操作,查看GPIO输出操作是否好用
int main()
{//MIO EMIO测试
#ifdef GPIO_Test//初始化GPIO,包括输入输出模式、初始值、是否使能等gpio_polled_init(&MIOLed0, LED0_GPIO_PS_MIO, GPIO_DIR_OUTPUT, GPIO_VALUE_OFF, GPIO_ENABLE);gpio_polled_init(&MIOLed1, LED1_GPIO_PS_MIO, GPIO_DIR_OUTPUT, GPIO_VALUE_OFF, GPIO_ENABLE);gpio_polled_init(&EMIOLed0, LED0_GPIO_PL_EMIO, GPIO_DIR_OUTPUT, GPIO_VALUE_OFF, GPIO_ENABLE);gpio_polled_init(&EMIOLed1, LED1_GPIO_PL_EMIO, GPIO_DIR_OUTPUT, GPIO_VALUE_OFF, GPIO_ENABLE);
#endifwhile(1){//************************************GPIO-Test*********************************//
#ifdef GPIO_Testset_gpio_value(&EMIOLed0, LED0_GPIO_PL_EMIO, GPIO_VALUE_ON);sleep(1);set_gpio_value(&EMIOLed0, LED0_GPIO_PL_EMIO, GPIO_VALUE_OFF);set_gpio_value(&EMIOLed1, LED1_GPIO_PL_EMIO, GPIO_VALUE_ON);sleep(1);set_gpio_value(&EMIOLed1, LED1_GPIO_PL_EMIO, GPIO_VALUE_OFF);set_gpio_value(&MIOLed0, LED0_GPIO_PS_MIO, GPIO_VALUE_ON);sleep(1);set_gpio_value(&MIOLed0, LED0_GPIO_PS_MIO, GPIO_VALUE_OFF);set_gpio_value(&MIOLed1, LED1_GPIO_PS_MIO, GPIO_VALUE_ON);sleep(1);set_gpio_value(&MIOLed1, LED1_GPIO_PS_MIO, GPIO_VALUE_OFF);#endif}return 0;
}
创作不易,希望大家点赞、收藏、关注哦!!!ヾ(o◕∀◕)ノ
相关文章:
ZYNQ-Vitis(SDK)裸机开发之(四)PS端MIO和EMIO的使用
目录 一、ZYNQ中MIO和EMIO简介 二、Vivado中搭建block design 1.配置PS端MIO: 2.配置PS端EMIO: 三、Vitis中新建工程进行GPIO控制 1. GPIO操作头文件gpio_hdl.h: 2.GPIO操作源文件gpio_hdl.c: 3.main函数进行调用 例程开发…...
聊聊jvm中内存模型的坑
jvm线程的内存模型 看图,简单来说线程中操作的变量是副本。在并发情况下,如果数据发生变更,副本的数据就变为脏数据。这个时候就会有并发问题。 参考:https://www.cnblogs.com/yeyang/p/12580682.html 怎么解决并发问题 解决的…...
DevOps已死?2024年的DevOps将如何发展
随着我们进入2024年,DevOps也发生了变化。新兴的技术、变化的需求和发展的方法正在重新定义有效实施DevOps实践。 IDC预测显示,未来五年,支持DevOps实践的产品市场继续保持健康且快速增长,2022年-2027年的复合年增长率࿰…...
appium控制手机一直从下往上滑动
用于使用Appium和Selenium WebDriver在Android设备上滚动设置应用程序的界面。具体来说,它通过WebDriverWait和expected_conditions等待元素出现,然后使用ActionChains移动到该元素并执行滚动动作。在setUp中,它初始化了Appium的WebDriver和c…...
为什么光伏探勘测绘需要无人机?
随着全球对可再生能源需求的不断增长,光伏产业也迎来了快速发展的机遇。光伏电站作为太阳能发电的主要形式之一,其建设前期的探勘测绘工作至关重要。在这一过程中,无人机技术的应用正逐渐展现出其独特的优势。那么,为什么光伏探勘…...
day10 | 栈与队列 part-2 (Go) | 20 有效的括号、1047 删除字符串中的所有相邻重复项、150 逆波兰表达式求值
今日任务 20 有效的括号 (题目: . - 力扣(LeetCode))1047 删除字符串中的所有相邻重复项 (题目: . - 力扣(LeetCode))150 逆波兰表达式求值 (题目: . - 力扣(LeetCode)) 20 有效的括号 题目: . - 力扣&…...
深入解析Tomcat的工作流程
tomcat解析 Tomcat是一个广泛使用的开源Servlet容器,用于托管Java Web应用程序。理解Tomcat的工作流程对于开发人员和系统管理员来说是非常重要的。本文将深入探讨Tomcat的工作原理,包括请求处理、线程池管理、类加载、以及与Web服务器之间的通信。 ###…...
【web网页制作】html+css旅游家乡山西主题网页制作(3页面)【附源码】
山西旅游网页目录 涉及知识写在前面一、网页主题二、网页效果Page1、景点介绍Page2、酒店精选|出行攻略Page3、景色欣赏 三、网页架构与技术3.1 脑海构思3.2 整体布局3.3 技术说明书 四、网页源码4.1 主页模块源码4.2 源码获取方式 作者寄语 涉及知识 山西旅游主题网页制作&am…...
系统参数指标:QPS、TPS、PV、UV等
QPS QPS:Queries Per Second 是每秒查询率,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,即每秒的响应请求数,也即是最大吞吐能力。 TPS TPS:Tra…...
一入鸿蒙深似海,从此Spring是路人:鸿蒙开发面试题
详细内容请参考最新的官方鸿蒙文档,不保证时效性 写得不对的地方请多多指点,本文仅代表个人所学知识范围 联系方式QQ 1219723557,可一同交流学习 欢迎补充,希望能做一个汇总版本出来 1. 网络编程基本知识(较为简单&…...
【Python】使用OPC UA创建数据服务器
目录 准备工作服务器设置创建或获取节点设置节点值启动服务器查看服务器客户端总结 在工业自动化和物联网(IoT)领域,OPC UA(开放平台通信统一架构)已经成为一种广泛采用的数据交换标准。它提供了一种安全、可靠且独立于…...
JavaScript(六)-高级篇
文章目录 作用域局部作用域全局作用域作用域链JS垃圾回收机制闭包变量提升 函数进阶函数提升函数参数动态参数多余参数 箭头函数 解构赋值数组解构对象解构 遍历数组forEach方法(重点)构造函数深入对象创建对象的三种方式构造函数实例成员 & 静态成员…...
速盾:游戏cdn什么意思
CDN(Content Delivery Network)是指内容分发网络,它是由一组位于世界各地的服务器组成的网络,用于将内容有效地传输给用户。游戏CDN,顾名思义,就是用于游戏内容分发的网络。 在传统的网络传输模式中&#…...
数据库-Redis(11)
目录 51.什么是Redis事务? 52.Redis事务相关命令? 53.Redis事务的三个阶段?...
【网安小白成长之路】6.pikachu、sql-labs、upload-labs靶场搭建
🐮博主syst1m 带你 acquire knowledge! ✨博客首页——syst1m的博客💘 🔞 《网安小白成长之路(我要变成大佬😎!!)》真实小白学习历程,手把手带你一起从入门到入狱🚭 &…...
(七)C++自制植物大战僵尸游戏关卡数据加载代码讲解
植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/xjvbb 打开LevelData.h和LevelData.cpp文件。文件位置如下图所示。 LevelData.h 此头文件中定义了两个类,分别是OpenLevelData、LevelData,其中OpenLevelData用于加载文件数据。LevelData解析数据…...
wpf下RTSP|RTMP播放器两种渲染模式实现
技术背景 在这篇blog之前,我提到了wpf下播放RTMP和RTSP渲染的两种方式,一种是通过控件模式,另外一种是直接原生RTSP、RTMP播放模块,回调rgb,然后在wpf下渲染,本文就两种方式做个说明。 技术实现 以大牛直…...
Element-UI 自定义-下拉框选择年份
1.实现效果 场景表达: 默认展示当年的年份,默认展示前7年的年份 2.实现思路 创建一个新的Vue组件。 使用<select>元素和v-for指令来渲染年份下拉列表。 使用v-model来绑定选中的年份值。 3.实现代码展示 <template><div><el-…...
二叉树的链式存储
二叉树是一种非常重要的数据结构,它能够高效地进行数据的插入、删除和查找操作。二叉树的每个节点最多有两个子节点,分别是左子节点和右子节点。二叉树可以采用多种不同的存储方式来实现,其中链式存储是最为直观和常用的一种方法。本文将深入…...
[计算机效率] 鼠标手势工具:WGestures(解放键盘的超级效率工具)
3.22 鼠标手势工具:WGestures 通过设置各种鼠标手势和操作进行绑定。当用户通过鼠标绘制出特定的鼠标手势后就会触发已经设置好的操作。有点像浏览器中的鼠标手势,通过鼠标手势操纵浏览器做一些特定的动作。这是一款强大的鼠标手势工具,可以…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...
【记录坑点问题】IDEA运行:maven-resources-production:XX: OOM: Java heap space
问题:IDEA出现maven-resources-production:operation-service: java.lang.OutOfMemoryError: Java heap space 解决方案:将编译的堆内存增加一点 位置:设置setting-》构建菜单build-》编译器Complier...
SQLSERVER-DB操作记录
在SQL Server中,将查询结果放入一张新表可以通过几种方法实现。 方法1:使用SELECT INTO语句 SELECT INTO 语句可以直接将查询结果作为一个新表创建出来。这个新表的结构(包括列名和数据类型)将与查询结果匹配。 SELECT * INTO 新…...
【前端实战】如何让用户回到上次阅读的位置?
目录 【前端实战】如何让用户回到上次阅读的位置? 一、总体思路 1、核心目标 2、涉及到的技术 二、实现方案详解 1、基础方法:监听滚动,记录 scrollTop(不推荐) 2、Intersection Observer 插入探针元素 3、基…...
