carlpc

【Zedboard入门】GPIO控制--MIO和EMIO的使用(VIVADO+PS+PL)

0
阅读(21709)

最近刚刚拿到了zedboard开发板,就开始了学习之旅。一来除了进行纯逻辑测试外,接下来就体验zedboard的特色PS+PL。当然第一步就是要点亮开发板上的流水灯。

作为菜鸟,我把几种方法都试了,MIO和EMIO来控制流水灯。

关于MIO来进行控制的教程网上有挺多的,我就推荐我看过的:http://blog.chinaaet.com/detail/35978

EMIO的详细教程好像比较少,就动手弄了下,希望对有需要的有点帮助。

在添加ZYNQ processing system后,就开始配置成EMIO的模式。

配置如图,其他选项默认。

image

确定后,核就会有GPIO_O出现,然后右击该引脚,选择make external

image

然后,核的配置就完成了,就下来需要进行管脚的约束,我是将这8个脚接到8个LED上,所以约束文件如下:
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_rtl_tri_i[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_rtl_tri_i[0]}]
set_property PACKAGE_PIN U14 [get_ports {gpio_0_tri_io[7]}]
set_property PACKAGE_PIN U19 [get_ports {gpio_0_tri_io[6]}]
set_property PACKAGE_PIN W22 [get_ports {gpio_0_tri_io[5]}]
set_property PACKAGE_PIN V22 [get_ports {gpio_0_tri_io[4]}]
set_property PACKAGE_PIN U21 [get_ports {gpio_0_tri_io[3]}]
set_property PACKAGE_PIN U22 [get_ports {gpio_0_tri_io[2]}]
set_property PACKAGE_PIN T21 [get_ports {gpio_0_tri_io[1]}]
set_property PACKAGE_PIN T22 [get_ports {gpio_0_tri_io[0]}]
set_property PACKAGE_PIN F22 [get_ports {gpio_rtl_tri_i[1]}]
set_property PACKAGE_PIN G22 [get_ports {gpio_rtl_tri_i[0]}]

这样就完成了整个硬件平台的搭建,然后综合,布局布线,生成比特流,并下载到板子中,开始转战SDK平台(导出至SDK平台的方法详见以上链接的博客)。

软件的编写

对于EMIO控制,可以进行位操作,可以进行段操作。接下来我将详细说下代码 :

#include <stdio.h>
#include "platform.h"
#include "xil_types.h"
#include "xgpio.h"
#include "xgpiops.h"
#include "xparameters.h"

int main()
{

    static XGpioPs psGpioInstancePtr;   //定义PS的GPIO指针
    XGpioPs_Config *GpioConfigPtr; //XGpioPs 结构体中还包含一个结构体,查bsp中的h文件
    init_platform();
    int xStatus;
    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 \n\r");

///////////段操作///////////

    XGpioPs_SetDirection(&psGpioInstancePtr,2,0xffffffff);
    XGpioPs_SetOutputEnable(&psGpioInstancePtr,2,0xffffffff);
    XGpioPs_Write(&psGpioInstancePtr,2,0x0);

///////////位操作///////////   

    XGpioPs_SetDirectionPin(&psGpioInstancePtr, 54,1);  //0输入,1输出
    XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 54,1);   //0 为dis,1为enable
   XGpioPs_WritePin(&psGpioInstancePtr,54,0);

    return 0;
}

段操作中,函数中有个重要的参数2,为什么是2呢?可以从下面这个图中得到答案
01

GPIO的相关信号被分为了4个bank,bank0与bank1为MIO信号,bank2与bank3为EMIO信号,所以我们用到了EMIO应选择Bank  2

位操作中,函数的参数54,这个参数是怎么来的呢?

从上图中,可以看出,MIO占据了54根线,级0~53,

所以EMIO是从54开始编码的。所以本文中使用的8个LED的引脚编号分别是54-61。

这样就能用EMIO来控制LED了。