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 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...