http://m.blog.csdn.net/article/details?id=52123465

http://blog.chinaaet.com/songhuangong/p/43084

本文介绍在zynq中三种实现GPIO的方式,分别为MIO、EMIO和IP方式。

MIO和EMIO方式是使用PS部分的GPIO模块来实现GPIO功能的,支持54个MIO(可输出三态)、64个输入和128个输出(64个输出和64个输出使能)EMIO

而IP方式是在PL部分实现 GPIO功能,PS部分通过M_AXI_GP接口来控制该GPIO IP模块;另外EMIO模块虽然使用PS部分GPIO但也使用了PL部分的管脚资源。

MIO方式实现GPIO

vivado中zynq设置如下图

由图中可见要选中打开GPIO,其下自动显示可用于GPIO的MIO(当MIO作为其他功能时就不能作为GPIO使用了),其中MIO 7、MIO 8只能作为输出使用,因为它们用于VMODE管脚(参考UG585第14章:14.2.3)

软件部分如下

#include <stdio.h>
#include "platform.h"
#include "xgpiops.h"#define LED1    0
#define LED2    9static void delay(int dly)
{int i, j;for (i = 0; i < dly; i++) {for (j = 0; j < 0xffff; j++) {;}}
}int main()
{int Status;XGpioPs_Config *ConfigPtr;XGpioPs Gpio;init_platform();ConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr,ConfigPtr->BaseAddr);if (Status != XST_SUCCESS){return XST_FAILURE;}XGpioPs_SetDirectionPin(&Gpio, LED1, 1);XGpioPs_SetDirectionPin(&Gpio, LED2, 1);XGpioPs_SetOutputEnablePin(&Gpio, LED1, 1);XGpioPs_SetOutputEnablePin(&Gpio, LED2, 1);while (1) {XGpioPs_WritePin(&Gpio, LED1, 0);XGpioPs_WritePin(&Gpio, LED2, 1);delay(1000);XGpioPs_WritePin(&Gpio, LED1, 1);XGpioPs_WritePin(&Gpio, LED2, 0);delay(1000);}cleanup_platform();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

EMIO方式实现GPIO

vivado中zynq设置如下图

图中可知GPIO中选择使用EMIO,并选择位宽(这里例子中选择3);其vivado中连接如下图

上图可知除了FIXED IO和DDR接口外,还多了3个3对(一个输入,一个输出和一个输出使能)GPIO管脚。

不同于MIO,这里三个IO管脚(一个输入,一个输出和一个输出使能在自动生成的顶层模块中合并为一个IO)要绑定到芯片对应管脚上

软件部分如下

#include <stdio.h>
#include "platform.h"
#include "xgpiops.h"#define LED_R   54
#define LED_G   55
#define LED_B   56
#define LED_ON  0
#define LED_OFF 1static void delay(int dly)
{int i, j;for (i = 0; i < dly; i++) {for (j = 0; j < 0xffff; j++) {;}}
}int main()
{int Status;XGpioPs_Config *ConfigPtr;XGpioPs Gpio;init_platform();ConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr,ConfigPtr->BaseAddr);if (Status != XST_SUCCESS) {print("cfg init err\n");return XST_FAILURE;}XGpioPs_SetDirectionPin(&Gpio, LED_R, 1);XGpioPs_SetOutputEnablePin(&Gpio, LED_R, 1);XGpioPs_SetDirectionPin(&Gpio, LED_G, 1);XGpioPs_SetOutputEnablePin(&Gpio, LED_G, 1);XGpioPs_SetDirectionPin(&Gpio, LED_B, 1);XGpioPs_SetOutputEnablePin(&Gpio, LED_B, 1);while (1) {XGpioPs_WritePin(&Gpio, LED_R, LED_ON);delay(1000);XGpioPs_WritePin(&Gpio, LED_G, LED_ON);delay(1000);XGpioPs_WritePin(&Gpio, LED_B, LED_ON);delay(1000);XGpioPs_WritePin(&Gpio, LED_R, LED_OFF);delay(1000);XGpioPs_WritePin(&Gpio, LED_G, LED_OFF);delay(1000);XGpioPs_WritePin(&Gpio, LED_B, LED_OFF);delay(1000);}cleanup_platform();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

类似MIO方式(都为PS部分GPIO操作),设置为输出并设置输出使能,但要注意这里的GPIO号是从54开始的3个。

IP方式实现GPIO

vivado中zynq设置如下图

图中可知GPIO中MIO和EMIO都不选择,但要打开M_AXI_GP接口(这里选择M_AXI_GP0)和复位管脚,如下图

当然用到了PL部分逻辑则至少需要一个时钟输出到PL部分,这里选择FCLK_CLK0输出50MHz,如下图

推荐加入zynq后,不要自动连接,再加入gpio并位宽设置为3,具体设置如下图

GPIO设置好后,再点击上面的蓝色字体的自动连接,即可得到上面的连接,这样可以减少手动连接量。

最后vivado中连接如下图

与EMIO类似需要将顶层三个GPIO管脚要绑定到芯片对应管脚上。

软件部分如下

#include <stdio.h>
#include "platform.h"
#include "xgpio.h"#define AXI_GPIO_DEVICE_ID  XPAR_GPIO_0_DEVICE_ID
#define XGPIO_BANK1         1
#define XGPIO_BANK2         2#define LED34_R_PIN         0x01
#define LED34_G_PIN         0x02
#define LED34_B_PIN         0x04static void delay(int dly)
{int i, j;for (i = 0; i < dly; i++) {for (j = 0; j < 0xffff; j++) {;}}
}int main()
{XGpio_Config *XGpioCfg;XGpio XGpio;int Status;init_platform();XGpioCfg = XGpio_LookupConfig(AXI_GPIO_DEVICE_ID);Status = XGpio_CfgInitialize(&XGpio, XGpioCfg, XGpioCfg->BaseAddress);if (Status != XST_SUCCESS) {return XST_FAILURE;}XGpio_SetDataDirection(&XGpio, XGPIO_BANK1, ~(LED34_R_PIN | LED34_G_PIN | LED34_B_PIN));XGpio_DiscreteWrite(&XGpio, XGPIO_BANK1, LED34_R_PIN | LED34_G_PIN | LED34_B_PIN);while (1) {XGpio_DiscreteWrite(&XGpio, XGPIO_BANK1, ~LED34_R_PIN);delay(1000);XGpio_DiscreteWrite(&XGpio, XGPIO_BANK1, ~(LED34_R_PIN | LED34_G_PIN));delay(1000);XGpio_DiscreteWrite(&XGpio, XGPIO_BANK1, ~(LED34_R_PIN | LED34_G_PIN | LED34_B_PIN));delay(1000);XGpio_DiscreteWrite(&XGpio, XGPIO_BANK1, ~(LED34_G_PIN | LED34_B_PIN));delay(1000);XGpio_DiscreteWrite(&XGpio, XGPIO_BANK1, ~(LED34_B_PIN));delay(1000);XGpio_DiscreteWrite(&XGpio, XGPIO_BANK1, LED34_R_PIN | LED34_G_PIN | LED34_B_PIN);delay(1000);}cleanup_platform();return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

这里实现的功能与EMIO方式中功能相同,当时IP方式中为PL部分实现的GPIO,所以调用的函数与前面两种GPIO实现函数不同,注意包含的GPIO头文件,前两种是#include "xgpiops.h"而这最后一种为#include "xgpio.h"

总结

MIO和EMIO方式使用PS部分的GPIO模块,其中MIO方式不占用PL部分资源,其输出管脚只能为固定的54个(而且要在未被其它外设使用的情况下),EMIO方式会占用PL的管脚资源,其管脚可在PL部分任意选择(除特殊功能管脚),IP方式除了占用PL部分管脚资源外还会占用PL部分逻辑资源,所以其GPIO功能在PL部分实现其调用函数也和前两种不同,最后EMIO和IP方式在vivado都需要绑定管脚。

学了zynq一段时间,一上来的时候就被zynq的GPIO唬住了,实在没搞清楚zynq的GPIO怎么回事,一会这样,一会那样,最后才慢慢发现zynq至少有3种GPIO可以调用。难怪我觉得每篇介绍GPIO的博客说的有一些不一样呢。

我们先看有哪三种GPIO:MIO、EMIO、AXI_GPIO。其中MIO和EMIO是直接挂在PS上的GPIO。而AXI_GPIO是通过AXI总线挂在PS上的GPIO上。

我们先看一下MIO和EMIO:下图EMIO和MIO的结构。其中MIO分布在BANK0,BANK1,而EMIO则分布在BANK2、BANK3。注意一下几项:

首先、MIO在zynq上的管脚是固定的,而EMIO,是通过PL部分扩展的,所以使用EMIO时候需要在约束文件中分配管脚,所以设计EMIO的程序时,

需要生成PL部分的bit文件,烧写到FPGA中。

其次、由下图可以看出MIO共占54bit,而EMIO占64bit。其中MIO占用IO号为0-53。而EMIO占用IO号为54-117。

再者、无论是EMIO还是MIO都属于PS上的IO,直接由PS操作。在调用头文件,只调用#include "xgpiops.h"即可,而在调用AXI_GPIO时,则需要#include "xgpio.h"。

最后、在设计好bd文件后、系统会自动在路径:..\standalone_bsp_0\ps7_cortexa9_0\include生成 xparameters.h 文件.我们可以在

xparameters.h文件中查看我们在bd设计时添加的外设ID。例如我们添加了EMIO,可以查到到该IO的地址和ID号。
#define XPAR_PS7_GPIO_0_DEVICE_ID 0
#define XPAR_PS7_GPIO_0_BASEADDR 0xE000A000
#define XPAR_PS7_GPIO_0_HIGHADDR 0xE000AFFF

再举例添加了两个AXI_GPIO,例化为BTNS_4BIT和SW_4BIT

/* Definitions for driver GPIO */
#define XPAR_XGPIO_NUM_INSTANCES 2/* Definitions for peripheral BTNS_4BIT */
#define XPAR_BTNS_4BIT_BASEADDR 0x41210000
#define XPAR_BTNS_4BIT_HIGHADDR 0x4121FFFF
#define XPAR_BTNS_4BIT_DEVICE_ID 0
#define XPAR_BTNS_4BIT_INTERRUPT_PRESENT 0
#define XPAR_BTNS_4BIT_IS_DUAL 0/* Definitions for peripheral SW_4BIT */
#define XPAR_SW_4BIT_BASEADDR 0x41200000
#define XPAR_SW_4BIT_HIGHADDR 0x4120FFFF
#define XPAR_SW_4BIT_DEVICE_ID 1
#define XPAR_SW_4BIT_INTERRUPT_PRESENT 0
#define XPAR_SW_4BIT_IS_DUAL 0

再来看一下,AXI_GPIO相当于GPIO的IP核,我们调用时是占用相应AXI总线地址空间,如下图,占用地址为0x41200000和0x41210000

zynq学习03 zynq中三种实现GPIO的方式相关推荐

  1. Python中三种表示NA的方式

    Python中三种表示NA的方式 # -*- coding: utf-8 -*- import numpy as np import pandas as pd# data_frame = np.loa ...

  2. android项目中有哪几种依赖关系,Android Studio项目中三种依赖的添加方式

    通常一个AS项目中的依赖关系有三种,一是本地依赖(主要是对本地的jar包),二是模块依赖,三是远程依赖:添加这些依赖的目的在于上我们想要在项目的某一个模块中使用其中的功能,比如okttp这个网络框架库 ...

  3. java go md5_Go语言中三种不同md5计算方式的性能比较

    前言 本文主要介绍的是三种不同的 md5 计算方式,其实区别是读文件的不同,也就是磁盘 I/O, 所以也可以举一反三用在网络 I/O 上.下面来一起看看吧. ReadFile 先看第一种, 简单粗暴: ...

  4. Spring中三种配置Bean的方式

    1.使用xml配置文件 由Spring Framework本身决定,此处不详细说. 2.使用Java注解的配置 如果一个类使用了@Service,那么此类将自动注册成一个bean,不需要再在appli ...

  5. python 中三种定义类的方式

    在Python中方,有三种定义类的方法: 常规方式.@classmethod修饰方式.@staticmethod修饰方式 class类定义 In [1]: class A:...: def commo ...

  6. 安卓:Android项目中三种依赖的添加方式

    添加本地依赖 首先将所需的 jar 或者 aar 包放在libs文件夹下. 方式1(适合jar) 右击jar包,选择Add As Library,最后sync. 方式2 (适合jar 和 aar) 在 ...

  7. 【强化学习】DQN 的三种改进在运筹学中的应用

    这篇文章主要介绍 DQN 的三种改进:Nature DQN.Double DQN.Dueling DQN 在运筹学中的应用,并给出三者的对比,同时也会给出不同增量学习下的效果. 这三种具体的改进方式可 ...

  8. VMWare学习总结(2)——VMware中三种网络连接的区别

    1.概述 大家在安装完虚拟机后,默认安装了如下图的两块虚拟网卡--VMnet1和VMnet8,其中VMnet1是host网卡,用于host方式连接网络:VMnet8是NAT网卡,用于NAT方式连接网络 ...

  9. 直立车模控制中三种滤波算法简单分析(清华卓晴)

    摘自:https://mp.weixin.qq.com/s/WbCh0NFAnsf9y2blQenf7g 让我想起余义的一篇文章也是说到平衡车有三种滤波,我想和卓晴说的是一样的吧. https://b ...

最新文章

  1. 随机变量,概率密度及其统计量
  2. Error writing file '/tmp/...' (Errcode: 28)
  3. 做生意的六大秘诀和十要诀
  4. vivo不小心把内部自研技术方案写进了“年终总结”,我看了直接好家伙
  5. WPF 基础控件之 GroupBox样式
  6. Linux中对两文件处理
  7. MacOS使用top命令查看进程使用内存
  8. java字面量和符号引用_JVM中的直接引用和符号引用
  9. led灯条维修_康佳液晶电视LED42F2200N灯条问题导致不开机故障修复
  10. Golang: How to sort struct with multiple sort parameters?
  11. 记录一次失败的Git操作
  12. n1进入recovery模式_N1盒子系列 篇一:N1简明降级刷机教程
  13. px和毫米的换算_px与厘米换算(px怎么转换为cm)
  14. unnormal C++
  15. C++ #ifdef 和 #endif
  16. RT-Thread:STM32F407虚拟U盘,无法识别拔出问题解决方案
  17. Linux 程序编译过程的来龙去脉
  18. 第2大电商平台贝壳数据平台的演进!
  19. 这家为AI for Science而生的新研究院,要让科研进入“安卓模式”
  20. charles手机抓包教程

热门文章

  1. 直播预告|灵动MM32 MCU助力全国大学生智能汽车竞赛——基础培训
  2. 第十六届全国大学生智能汽车竞赛 英飞凌芯片申请情况
  3. 压力传感器 ZNHM-I-5KG初步测试
  4. 看看那些在公众号留言中的照片
  5. 为什么我们的信标信号被干扰?
  6. mmap映射大于4g的文件_尴尬,win10镜像文件install.wim大于4G,如何将它装进U盘
  7. java简单通讯录的实现02person类_用java实现简单的小游戏(你一定玩过)
  8. 辅助改方办理方法 计算机联锁,辅助所
  9. delphi listview动态添加图片_网站图片如何优化适合收录
  10. linux下查看vnc端口_怎样查vnc端口,Linux下根据进程名怎样查端口