版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

 
本文介绍在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 9 static void delay(int dly)
{
int i, j;
for (i = ; i < dly; i++) {
for (j = ; 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, );
XGpioPs_SetDirectionPin(&Gpio, LED2, );
XGpioPs_SetOutputEnablePin(&Gpio, LED1, );
XGpioPs_SetOutputEnablePin(&Gpio, LED2, ); while () {
XGpioPs_WritePin(&Gpio, LED1, );
XGpioPs_WritePin(&Gpio, LED2, );
delay();
XGpioPs_WritePin(&Gpio, LED1, );
XGpioPs_WritePin(&Gpio, LED2, );
delay();
}
cleanup_platform();
}

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 1 static void delay(int dly)
{
int i, j;
for (i = ; i < dly; i++) {
for (j = ; 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, );
XGpioPs_SetOutputEnablePin(&Gpio, LED_R, );
XGpioPs_SetDirectionPin(&Gpio, LED_G, );
XGpioPs_SetOutputEnablePin(&Gpio, LED_G, );
XGpioPs_SetDirectionPin(&Gpio, LED_B, );
XGpioPs_SetOutputEnablePin(&Gpio, LED_B, ); while () {
XGpioPs_WritePin(&Gpio, LED_R, LED_ON);
delay();
XGpioPs_WritePin(&Gpio, LED_G, LED_ON);
delay();
XGpioPs_WritePin(&Gpio, LED_B, LED_ON);
delay();
XGpioPs_WritePin(&Gpio, LED_R, LED_OFF);
delay();
XGpioPs_WritePin(&Gpio, LED_G, LED_OFF);
delay();
XGpioPs_WritePin(&Gpio, LED_B, LED_OFF);
delay();
}
cleanup_platform();
}

类似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 0x04 static void delay(int dly)
{
int i, j;
for (i = ; i < dly; i++) {
for (j = ; 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 () {
XGpio_DiscreteWrite(&XGpio, XGPIO_BANK1, ~LED34_R_PIN);
delay();
XGpio_DiscreteWrite(&XGpio, XGPIO_BANK1, ~(LED34_R_PIN | LED34_G_PIN));
delay();
XGpio_DiscreteWrite(&XGpio, XGPIO_BANK1, ~(LED34_R_PIN | LED34_G_PIN | LED34_B_PIN));
delay();
XGpio_DiscreteWrite(&XGpio, XGPIO_BANK1, ~(LED34_G_PIN | LED34_B_PIN));
delay();
XGpio_DiscreteWrite(&XGpio, XGPIO_BANK1, ~(LED34_B_PIN));
delay();
XGpio_DiscreteWrite(&XGpio, XGPIO_BANK1, LED34_R_PIN | LED34_G_PIN | LED34_B_PIN);
delay();
}
cleanup_platform();
return ;
}

这里实现的功能与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中三种实现GPIO的方式的更多相关文章

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

    Spring中三种配置Bean的方式分别是: 基于XML的配置方式 基于注解的配置方式 基于Java类的配置方式 一.基于XML的配置 这个很简单,所以如何使用就略掉. 二.基于注解的配置 Sprin ...

  2. smarty中三种变量的访问方式

    在模板中smarty有三种变量,第一种,php分配的变量,第二种配置文件里的变量,第三种,PHP全局数组里的变量,配置文件里变量的访问方式可以是{#bgcolor#},"#"必须紧 ...

  3. Selenium中三种等待的使用方式---规避网络延迟、代码不稳定问题

    在UI自动化测试中,必然会遇到环境不稳定,网络慢的情况,这时如果你不做任何处理的话,代码会由于没有找到元素,而报错.这时我们就要用到wait(等待),而在Selenium中,我们可以用到一共三种等待, ...

  4. Qt中三种解析xml的方式

    在下面的随笔中,我会根据xml的结构,给出Qt中解析这个xml的三种方式的代码.虽然,这个代码时通过调用Qt的函数实现的,但是,很多开源的C++解析xml的库,甚至很多其他语言解析xml的库,都和下面 ...

  5. Android Studio项目中三种依赖的添加方式

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

  6. js中三种定义变量的方式const, var, let的区别。

    const   var  let区别 1.const 定义的变量不可以修改,而且必须初始化 const a = 3;正确 const a;错误,必须初始化 console.log("函数外c ...

  7. js中三种定义变量 const, var, let 的区别

    js中三种定义变量的方式const, var, let的区别 1.const定义的变量不可以修改,而且必须初始化. 1 const b = 2;//正确 2 // const b;//错误,必须初始化 ...

  8. iOS开发UI篇—iOS开发中三种简单的动画设置

    iOS开发UI篇—iOS开发中三种简单的动画设置 [在ios开发中,动画是廉价的] 一.首尾式动画 代码示例: // beginAnimations表示此后的代码要“参与到”动画中 [UIView b ...

  9. C#中三种定时器对象的比较

    ·关于C#中timer类 在C#里关于定时器类就有3个1.定义在System.Windows.Forms里2.定义在System.Threading.Timer类里3.定义在System.Timers ...

随机推荐

  1. 编译lua固件NodeMcu 8266

    https://www.cnblogs.com/yangfengwu/p/10547024.html 因为我现在的Wifi的教程是lua语言编写的,但是有些功能需要自己编译lua固件才可以,这篇文章就 ...

  2. [PHP]Laravel无法使用COOKIE和SESSION的解决方法

    COOKIE和SESSION的具体使用百度和官方文档上都有. 但是,文档里没有说明必须经过相应的中间件才能使用,百度搜索结果都是彼此copy的bullshit!!! 其实最终解决办法很简单,完全不是网 ...

  3. 如何判断当前脚本运行在node还是浏览器中

    判断global对象,如果是window,就是运行在浏览器中,如果global对象是undefined,则运行在node中.

  4. 第03组 Beta冲刺(3/4)

    队名:不等式方程组 组长博客 作业博客 团队项目进度 组员一:张逸杰(组长) 过去两天完成的任务: 文字/口头描述: 制定了初步的项目计划,并开始学习一些推荐.搜索类算法 GitHub签入纪录: 暂无 ...

  5. 分类模型的评价指标Fscore

    小书匠深度学习 分类方法常用的评估模型好坏的方法. 0.预设问题 假设我现在有一个二分类任务,是分析100封邮件是否是垃圾邮件,其中不是垃圾邮件有65封,是垃圾邮件有35封.模型最终给邮件的结论只有两 ...

  6. fork,vfork

    转自 http://blog.csdn.net/todd911/article/details/14062103 1.fork函数 一个现有的进程可以调用fork函数创建一个新的子进程. #inclu ...

  7. [转]【kafka】用 Docker 部署 Kafka

    ref : https://www.jianshu.com/p/7635ea96e53f 用 Docker 部署 Kafka   Kafka 简介 作为一个消息中间件,Kafka 以高扩展性.高吞吐量 ...

  8. [转]怎样与 CORS 和 cookie 打交道

    原文地址:https://segmentfault.com/a/1190000018756960 前言 CORS 与 cookie 在前端是个非常重要的问题,不过在大多数情况下,因为前后端的 doma ...

  9. odoo开发笔记 -- 借助模块queue_job实现异步方法调用

    场景描述: 对比了几个定时调度的框架,发现各有优缺点: celery 很强,异步定时调度,异步周期调度,也有延时调度的功能,但是延时调度的案例比较少,遂暂时不使用. queue_job,一个odoo第 ...

  10. JZ落选跟我们有什么关系

    今天中午睡前刷了一下微博,看到JZ派落选了,底下一大堆冷嘲热讽的. 比如,养了一堆白眼狼,给了XG一堆利好政策,却这样FZ. 这种心态像极了多子女家庭的生活. 多子女家庭里,总有几个是性格比较乖巧,也 ...