Menu Close

Xilinx Zyqn在SDK平台对GPIO的操作

Xilinx-ZYNQ集成了最通用两大硬件平台:ARM和FPGA,ARM和FPGA 的结合更是给设计带来了高性能,高灵活性等便利,而且也是目前非常流行的设计方式。

Xilinx-ZYNQ作为通用的SOC平台,可以有两种方式去控制GPIO(LED,Switch)等。

本实验平台:zynq7030平台

一、通过纯PL端进行控制(FPGA侧)

通常可以通过FPGA进行操作去控制PL端。

二、通过PS端进行控制(ARM侧)

硬件部分不在此文章描述,可参考Helloworld和EMIO的硬件操作,生成bit文件,导出到硬件并导入到SDK平台。

本文章主要讲SDK程序下的GPIO的控制:

SDK有专有的GPIO控制API,主要针对MIO或EMIO硬件接口。

  • PS端有三种GPIO:MIO、EMIO、AXI_GPIO。其中MIO和EMIO是直接挂在PS上的GPIO。
  • AXI_GPIO是通过AXI总线挂在PS上的GPIO上。
  • MIO在zynq上的管脚是固定的(而且多数已经被分配为固定功能,如UART,Enet , USB,SPI,SD CARD等),而EMIO,是通过PL部分扩展的,所以使用EMIO时候需要在约束文件中分配管脚,所以设计EMIO的程序时需要生成PL部分的bit文件,烧写到FPGA中。(注意:不能整体将MIO设成EMIO,否则SOC的原有功能将会受到影响,只能将本次设计中没有用到MIO映射成EMIO)
  • MIO共占54bit,分布在GPIO BANK0, BANK1上,其中BANK0 32个MIO ,MIO0-31, BANK1 有22个MIO,MIO32-53. 注意:这里的BANK是GPIO的逻辑BANK与实际物理的BANK(如 BANK500,BANK501等)不同,其中MIO占用IO号为0-53。
  • 而EMIO占64bit。分布在GPIO BANK2,BANK3上,每个BANK上有32个GPIO,EMIO占用IO号为54-117,这个编号是仅接着MIO的编号进行的。

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

%title插图%num

MIO或EMIO可以有两种操作方式:

  • 一种是基于管脚(PIN) 的操作,对应一组操作函数。
  • 另一种是基于 BANK的操作,对应另一种操作函数。
  • 两种操作函数都在”xgpiops.h”中定义,”xgpiops.c”是实现函数。
  • MIO pin number 0-53(54个)
  • EMIO pin number 54-117(64个)

/* Pin APIs in xgpiops.c */   对Pin的API操作,区别在于有“Pin”

u32 XGpioPs_ReadPin(XGpioPs *InstancePtr, u32 Pin);

//读取指定管脚号对应的输入值

void XGpioPs_WritePin(XGpioPs *InstancePtr, u32 Pin, u32 Data);

//写入对应管脚号的值,32位Data,只有最低位有效

void XGpioPs_SetDirectionPin(XGpioPs *InstancePtr, u32 Pin, u32 Direction);//指定对应管脚号的管脚方向,0输入,1为输出

举例如下:

int i=0;    for (i=0;i<8;i++)

{

XGpioPs_SetDirectionPin(&psGpioInstancePtr,54+i,1);

GpioPs_WritePin(&psGpioInstancePtr,54+i, 1);

}

 

设置所有LED管脚为输出,且点亮8个灯。

 

下面列出了基于BANK操作的一组函数,对应关系如下:

对Bank的API操作,区别在于没有“Pin”,功能说明参考pin的API说明

u32 XGpioPs_Read(XGpioPs *InstancePtr, u8 Bank);

void XGpioPs_Write(XGpioPs *InstancePtr, u8 Bank, u32 Data);

void XGpioPs_SetDirection(XGpioPs *InstancePtr, u8 Bank, u32 Direction);

 

举例如下:

While(1)

{

XGpioPs_SetDirection(&psGpioInstancePtr,2, 0xff);

XGpioPs_Write(&psGpioInstancePtr, 2, 1);

}

设置所有Bank2管脚为输出,所有管脚为高,点亮所有LED。

实验目的:

基于PIN number的编程实现例程,将八位LED输出设计成约每秒中,奇数和偶数交替点亮。

总共3种状态:

(1)LED 0,2,4,8 点亮,

(2)LED 1,3,5,7 点亮,

(3)全灭的状态

代码实例:

//定义延时函数

static void delay(int dly)

{

int i, j;

for (i = 0; i < dly; i++) {

for (j = 0; j < 0xffff; j++) {

;

}

}

}

int i=0;

for (i=0;i<8;i++)

{   XGpioPs_SetDirectionPin(&psGpioInstancePtr,54+i,1);     //设置管脚的方向,配置EMIO输出方向,0输入1输出

XGpioPs_SetOutputEnablePin(&psGpioInstancePtr,54+i,1);  //使能LED管脚

}  }

while(1)

{     //Pin 操作

for(i=0;i<8;i++)

{        XGpioPs_WritePin(&psGpioInstancePtr,54+i,i+1);      }

delay(1000);   //LED0,2,4,6点亮

for(i=0;i<8;i++)

{      XGpioPs_WritePin(&psGpioInstancePtr,54+i,i);      }

delay(1000); //LED1,3,5,7点亮,交替亮

for(i=0;i<8;i++)

{      XGpioPs_WritePin(&psGpioInstancePtr,54+i,0);      }

delay(1000);  //全熄灭

}

编译运行,并观察zynq7030开发板上LED的运行状态。可以按F11和F6进行Debug单步运行检查问题,观察变化。

%title插图%num

 

Posted in C语言, SoC, SoC硬件开发, 嵌入式计算机语言, 文章

发表评论

相关链接