ZYNQ-Vitis(SDK)裸机开发之(四)PS端MIO和EMIO的使用

news2024/11/25 9:06:03

目录

一、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 __cplusplus
 extern "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		54

typedef 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){
		//使能输出的GPIO
		XGpioPs_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);
#endif

	while(1){
	//************************************GPIO-Test*********************************//
#ifdef GPIO_Test
		set_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◕∀◕)ノ

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

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

相关文章

吃鸡游戏msvcp140.dll丢失的解决方法

msvcp140.dll 是一个与 Microsoft Visual C Redistributable 相关的动态链接库(DLL)文件,是 Windows 操作系统中众多应用程序正常运行所必需的关键组件之一。以下是对 msvcp140.dll 文件的总体介绍和msvcp140.dll丢失的多个解决方案分享。 *…

预付费水电表系统厂家怎么选择?

1.预付费水电表系统概述 预付费水电表系统是一种现代化的计量和管理系统,它颠覆了传统的后付费模式,用户需预先支付费用才能使用水电,大大提高了物业管理和用户缴费的效率。该系统主要由智能电表、水表和集中控制管理系统三大部分组成。 2.…

【创建型模式】建造者模式

一、建造者模式概述 建造者模式定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同得表示。(对象创建型模式)。 建造者模式分析: 1.将客户端与包含多个部件得复杂对象得创建过程分离,客户端无需知道复杂对象…

TCP/IP 协议栈在 Linux 内核中的 运行时序分析

1、Linux内核概述 1.1 Linux内核结构 一个完整的Linux内核一般由5部分组成,它们分别是内存管理、进程管理、进程间通信、bai虚拟文件系统和网络接口。 1、内存管理 内存管理主要完成的是如何合理有效地管理整个系统的物理内存,同时快速响应内核各个子…

SQL Serve---嵌套查询

定义 嵌套查询:主要用于复杂的查询中。在SQL语言中,一个Select From Where语句称为一个查询块,将一个查询块嵌套在另一个查询的Where子句或Having短语中的查询称为嵌套查询。 子查询的类型 使用别名的子查询 使用IN和NOT IN的子查询 使用比较…

Modelsim自动化仿真脚本(TCL)——简单实例

目录 1. Modelsim与TCL脚本的关系 2.实验文件 2.1设计文件 2.2仿真测试文件 2.3. 脚本文件 3. 实验步骤 3.1. 创建文件夹 3.2. 指定路径 3.3. 创建工程 3.4. 运行命令 3.4. 实验效果 1. Modelsim与TCL脚本的关系 TCL(Tool Command Language)是…

基于机器学习的人脸发型推荐算法研究与应用实现

1.摘要 本文主要研究内容是开发一种发型推荐系统,旨在识别用户的面部形状,并根据此形状推荐最适合的发型。首先,收集具有各种面部形状的用户照片,并标记它们的脸型,如长形、圆形、椭圆形、心形或方形。接着构建一个面部…

我到底应该先学python还是C++?

根据你的情况,我还是建议你继续用Python,因为中学阶段最应该死磕的是算法。 也不需要精通Python,因为编程语言只是工具,能够熟练使用就可以了,而且现在信息学竞赛几乎都已经支持Python了,C已经不是必选项了…

宿舍预付费电控系统

1.系统概述 宿舍预付费电控系统是一种现代化的电力管理解决方案,旨在提高校园或公寓楼的能源效率,同时确保公平、透明的用电管理。通过预付费模式,用户需先充值后用电,避免了后期收费的困扰,也鼓励了节能行为。 2.功…

LangChain LangServe 学习笔记

LangChain LangServe 学习笔记 0. 引言1. LangServe 概述2. 特性3. 限制4. 安装5. 示例应用程序6. OpenAPI文档7. Python SDK 客户端8. Playground9. 聊天可运行页面 0. 引言 使用 LangServe 可以立即将您的LLM应用程序变成 API 服务器。 LangServe 使用 FastAPI 构建&#x…

道合顺传感新品上市!高性能氢气传感器DSB14-G3K-J详解

道合顺传感高性能氢气传感器DSB14-G3K-J正式发布!超强抗干扰能力优势明显。应对氢气安全挑战、高性能氢气传感器国产化、为储能保驾护航。 氢气,作为现今能源领域中的新贵,在储能行业中应用广泛且备受瞩目。但氢气易燃、易爆特性使其在生产、…

鉴权设计(一)———— 登录验证

1、概述 网站系统出于安全性的考虑会对用户进行两个层面的校验:身份认证以及权限认证。这两个认证可以保证只有特定的用户才能访问特定的数据的需求。 本文先实现一个基于jwt拦截器redis注解实现的简单登录验证功能。 2、设计思路 jwt用于签发token。 拦截器用于拦…

PDF被加密无法打印的解决办法

思路很清晰:先解密→再打印 分享四个工具,可以轻松解密PDF: ⭐i love pdf I LOVE PDF是一款免费的PDF网站,界面设计简洁,首页没有广告,但每个功能的操作界面是有广告的,不会影响使用。 部分功…

MAC M1版IDEA热部署JRebel

1、在idea里面安装jrebel插件 2、下载激活工具:ReverseProxy_darwin_amd64 下载地址(Mac早期用户使用Safari下载,不要用Chrome,否则下载之后会把.dms后缀名去掉) 特别注意:M1用户请使用下面的下载&#xff…

ORA-19760: error starting change tracking(btc)

备份时候显示ORA19760 1、使用命令查看参数是否开启 SELECT * FROM v$block_change_tracking;2、未开启状态 3、查询数据文件位置 select * from v$dbfile;路径截止到最后/前面。 4、开启块修改跟踪 alter database enable block change tracking using file …

市场份额第一!博睿数据持续领跑中国APM市场

近日,全球领先的IT市场研究和咨询公司IDC发布《中国IT统一运维软件产品市场跟踪报告,2023H2》。报告显示,2023下半年博睿数据以 17.6%的市场份额蝉联 APM(应用性能监控)市场第一。2023年全年博睿数据以18.8%的市场份额持续领跑中国APM市场。 …

从三大层次学习企业架构框架TOGAF

目录 前言 掌握TOGAF的三个层次 层次1:怎么学? 层次2:怎么用? 层次3:怎么思? 结束语 前言 对于一名架构师来讲,如果说编程语言是知识库层次中的入门石,那么企业架构框架则相当…

基于springboot实现房屋租赁管理系统设计项目【项目源码+论文说明】计算机毕业设计

基于springboot实现房屋租赁管理系统设计演示 摘要 互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为人们提供服务。针对房屋租赁信息管理混乱&…

【面试经典 150 | 链表】删除链表的倒数第 N 个结点

文章目录 写在前面Tag题目来源解题思路方法一:统计节点个数方法二:双指针 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更…… 专栏内容以分析题目为主,并附带一些对于本…

官方助力:SpringAI快速尝鲜体验(SpringBoot3+Gradle8+JDK17)

SpringAI 自从OpenAI的ChatGPT爆火之后,各种AI大模型开始席卷互联网,作为知名框架的Spring官方也是小小的顺应了一波潮流,就在不久前官方推出了针对AI的部分,称为SpringAI目前最新版本为0.8.1,下面是官网的截图。 直通车https:/…