ZYNQ SOC 入门基础(三)EMIO 实验

1.1 EMIO 和MIO的对比介绍
在ZYNQ SOC 入门基础(二)MIO 实验中讲解了MIO的使用,本节就来讲一下EMIO的使用。在实上一章中对ZYNQ的GPIO做了简单的介绍,ZYNQ的GPIO有(multiuse I/O)MIO和(extendable multiuse I/O) EMIO。

MIO分配在Bank0和Bank1直接与PS相连,EMIO分配在Bank2和Bank3与PL部分相连。除了Bank1是22bit之外,其他的Bank都是32bit。所以MIO有54个引脚,EMIO有64个引脚。使用EMIO的好处就是。当MIO 不够使用时,PS可以通过驱动EMIO控制PL部分的引脚,接下来就详细介绍EMIO的使用。

EMIO的使用和MIO的使用是很相似的。区别在于,EMIO的使用相当于一个PS+PL结合的例子。所以EMIO需要分配引脚,以及综合、实现、生成比特流。

1.2 电路分析与实验现象
本节将使用Miz7035开发板,通过过SDK 操作EMIO来控制LED流水灯的操作。

1.3 创建VIVADO 工程
step1: 新建一个名为Miz_sys的工程,芯片类型选择xc7z035ffg676-2。

step2:创建一个BD文件,并命名为system

step3: 添加ZYNQ7 Processing System, 根据ZYNQ SOC 入门基础(一)Hello World 实验的设置配置好输入时钟频率与内存型号。

step4: 勾选EMIO,如下图

step5: 单击 OK, 仔细观察发现ZYNQ的核心多出了一组引脚名为GPIO_0,这个正是我们刚刚设置的一组EMIO。右击该引脚,选择make external 把GPIO_0 引脚引出。效果如下:

step6: 单击 GPIO_0,将其修改为 EMIO_0,如下图所示

Step7:右键单击 Block 文件,文件选择 Generate the Output Products。 
Step8:单击 Block 文件,选择 Create a HDL wrapper,根据 Block 文件内容产生一个 HDL 的顶层文件,并选择让 vivado 自动完成

1.4 创建约束文件
开发板选择的是Miz7035,在此直接把以下约束添加到约束文件里即可。
set_property PACKAGE_PIN B9 [get_ports {emio_0_tri_io[0]}]
set_property IOSTANDARD LVCMOS15 [get_ports {emio_0_tri_io[0]}]

set_property PACKAGE_PIN J10 [get_ports {emio_0_tri_io[1]}]
set_property IOSTANDARD LVCMOS15 [get_ports {emio_0_tri_io[1]}]

set_property PACKAGE_PIN H11 [get_ports {emio_0_tri_io[2]}]
set_property IOSTANDARD LVCMOS15 [get_ports {emio_0_tri_io[2]}]

set_property PACKAGE_PIN G9 [get_ports {emio_0_tri_io[3]}]
set_property IOSTANDARD LVCMOS15 [get_ports {emio_0_tri_io[3]}]

1.5 生成比特流并导入到SDK
1.6 在SDK中
step1:单击 File-New-Application project。

Step2:选择 Empty Application,创建一个空的工程,单击 Finish 完成创建。

step3: 添加 mian.c 程序,输入以下程序

#include "xgpiops.h"
#include "sleep.h"

int main()
{
static XGpioPs psGpioInstancePtr;
XGpioPs_Config* GpioConfigPtr;
int xStatus;

//-- EMIO的初始化
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");
//--EMIO的输入输出操作
XGpioPs_SetDirectionPin(&psGpioInstancePtr, 54,1);
XGpioPs_SetDirectionPin(&psGpioInstancePtr, 55,1);
XGpioPs_SetDirectionPin(&psGpioInstancePtr, 56,1);
XGpioPs_SetDirectionPin(&psGpioInstancePtr, 57,1);
//使能EMIO输出
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 54,1);
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 55,1);
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 56,1);
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 57,1);

while(1)
{
XGpioPs_WritePin(&psGpioInstancePtr, 54, 1);//EMIO的第0位输出1
usleep(200000); //延时
XGpioPs_WritePin(&psGpioInstancePtr, 54, 0);//EMIO的第0位输出0
usleep(200000); //延时
XGpioPs_WritePin(&psGpioInstancePtr, 55, 1);//EMIO的第1位输出1
usleep(200000); //延时
XGpioPs_WritePin(&psGpioInstancePtr, 55, 0);//EMIO的第1位输出0
usleep(200000); //延时
XGpioPs_WritePin(&psGpioInstancePtr, 56, 1);//EMIO的第2位输出1
usleep(200000); //延时
XGpioPs_WritePin(&psGpioInstancePtr, 56, 0);//EMIO的第2位输出0
usleep(200000); //延时
XGpioPs_WritePin(&psGpioInstancePtr, 57, 1);//EMIO的第3位输出1
usleep(200000); //延时
XGpioPs_WritePin(&psGpioInstancePtr, 57, 0);//EMIO的第3位输出0
usleep(200000); //延时

}
return 0;
}

step4:连接开发板,并上电。下载程序到开发板上。

---------------------
作者:MaoChuangAn
来源:CSDN
原文: https://blog.csdn.net/MaoChuangAn/article/details/83444130

推荐阅读