zoukankan      html  css  js  c++  java
  • 【转】ZYNQ中三种实现GPIO的方式

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
    本文链接:https://blog.csdn.net/husipeng86/article/details/52123465
     
    本文介绍在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设置如下图

    mio_vivado中配置

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

    软件部分如下

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

    EMIO方式实现GPIO

    vivado中zynq设置如下图

    emio_vivado中配置

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

    emio_vivado中连接

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

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

    软件部分如下

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

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

    IP方式实现GPIO

    vivado中zynq设置如下图

    axi_gpio_vivado中配置

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

    axi_gpio_vivado中配置_GP和复位

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

    axi_gpio_vivado中配置_时钟

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

    axi_gpio_ip设置

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

    最后vivado中连接如下图

    axi_gpio_vivado中连接

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

    软件部分如下

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

  • 相关阅读:
    hadoop中namenode发生故障的处理方法
    开启虚拟机所报的错误:VMware Workstation cannot connect to the virtual machine. Make sure you have rights to run the program, access all directories the program uses, and access all directories for temporary fil
    Hbase的安装与部署(集群版)
    分别用反射、编程接口的方式创建DataFrame
    用Mapreduce求共同好友
    SparkSteaming中直连与receiver两种方式的区别
    privot函数使用
    Ajax无刷新显示
    使用ScriptManager服务器控件前后台数据交互
    数据库知识
  • 原文地址:https://www.cnblogs.com/xianyufpga/p/11431142.html
Copyright © 2011-2022 走看看