• ZYNQ学习之——MIO


    1、GPIO基础知识

      Zynq7000 系列芯片有 54 个 MIO(multiuse I/O) ,它们分配在 GPIO 的 Bank0 和Bank1 隶属于 PS 部分, 这些 IO 与 PS 直接相连。 不需要添加引脚约束, MIO 信号对 PL部分是不可见,即PL不能对这部分IO信号进行任何操作。 所以对 MIO 的操作可以看作是纯 PS 的操作。 参考芯片手册看到

      Bank0:MI0[31:0]
      Bank1:MI0[52:53]
      Bank2:EMI0[31:0]
      Bank3:EMI0[63:32]

    GPIO 的控制寄存器地址空间

    很多寄存器,但是一般的操作关注部分寄存器就可以了。

    DATA_RO: 此寄存器使能软件观察 PIN 脚, 当 GPIO 被配置成输出的时候, 这个寄存器的值会反应输出的 PIN 脚情况。
    DATA:此寄存器控制输出到 GPIO 的值, 读这个寄存器的值可以读到最后一次写入该寄存器的值。
    MASK_DATA_LSW:位操作寄存器, 写入 GPIO 16bit 其他没有改变的位置保存原先的状态
    MASK_DATA_MSW:位操作寄存器, 写入 GPIO 16bit 其他没有改变的位置保存原先的状态
    DIRM:此寄存器控制输出的开关, 当 DIRM[x]=0 时候, 禁止输出
    OEN: 输出使能, 当 OEN[x]=0 的时候输出关闭, PIN 脚处于三态
    因此, 如果要读 IO 状态就得读 DATA_RO 的值, 如果是对某一位进行操作就是写
    MASK_DATA_LSW/MASK_DATA_MSW
    具体的相关参数请参考技术手册 ug585-Zynq-7000-TRM.pdf

    2、FPGA硬件创建。

      MIO的操作硬件创建比较简单,外置只需添加MIO外置就可以了。

     然后编译导出硬件到SDK软件中。

    3、SDK软件

      首先就是要创建一个APP工程,这里就不做讲解了。看一下软件设计,就是纯C开发了。

        

               

     #include "xgpiops.h"
     #include "sleep.h"
     int main()
     {
        static XGpioPs psGpioInstancePtr;
        XGpioPs_Config* GpioConfigPtr;
        int iPinNumber= 7; //板子的LED连接的是MIO7,这个根据板子的硬件设计做对应修改
        u32 uPinDirection = 0x1; //设置IO方向。1表示输出,0表示输入
        int xStatus;

      //--MIO的初始化
        GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
        if(GpioConfigPtr == NULL)
        return XST_FAILURE;

        xStatus = XGpioPs_CfgInitialize(&psGpioInstancePtr,GpioConfigPtr, GpioConfigPtr->BaseAddr);
        if(XST_SUCCESS != xStatus)
        print(" PS GPIO INIT FAILED ");
      //--MIO的输入输出操作
        XGpioPs_SetDirectionPin(&psGpioInstancePtr, iPinNumber,uPinDirection);//配置MIO输出方向
        XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, iPinNumber,1);//配置MIO的第7位输出

        //以下是库函数的操作方式。
        /* while(1)
        {
          XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 1);//点亮MIO的第7位输出1
          usleep(500000); //us延时
          XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 0);//熄灭MIO的第7位输出0
          usleep(500000); //us延时
        }*/

        //以下是寄存器的操作方式。

        while(1)

        {
          XGpioPs_WriteReg(0xE000A000,0x00000000, 0xFF7FFFFF&0xFFFF0080);
          usleep(500000); //us延时
          XGpioPs_WriteReg(0xE000A000,0x00000000, 0xFF7FFFFF&0xFFFF0000);
          usleep(500000); //us延时
        }
      return 0;
    }

     分析以下一些Xilinx的函数:

    GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);  查找对应ID设备是否存在,如果不存在出错,如果存在就可以做下一步的初始化。

    可以查到

    /* Definitions for peripheral PS7_GPIO_0 */
    #define XPAR_PS7_GPIO_0_DEVICE_ID 0
    #define XPAR_PS7_GPIO_0_BASEADDR 0xE000A000  //这个就是MIO的基地址
    #define XPAR_PS7_GPIO_0_HIGHADDR 0xE000AFFF  //这个结束地址不需要管

  • 相关阅读:
    HDU 5791 Two(训练题002 F)
    HDU 5783 Divide the Sequence (训练题002 B)
    关于01背包和完全背包二重循环的顺序(前人之技,后人惊叹)
    关于01背包求第k优解
    最长上升子序列(logN算法)
    ACM课程总结
    Problem F
    关于狄克斯特拉算法(dijkstra)总结
    Problem I
    OBJ文件格式分析工具: objdump, nm,ar
  • 原文地址:https://www.cnblogs.com/mouou/p/6132303.html
Copyright © 2020-2023  润新知