宋桓公

MiZ702学习笔记5——EMIO 使用详解

0
阅读(7278)

 

上次讲到MIO的使用,初步熟悉了EDK的使用,这次就来说说EMIO的使用。如你所见zynq的GPIO,分为两种,MIO(multiuse I/O)和EMIO(extendable multiuse I/O)

clip_image002

MIO分配在bank0和bank1直接与PS部分相连,EMIO分配在bank2和bank3直接和PL部分相连。除了bank1是22-bit之外,其他的bank都是32-bit。所以MIO有53个引脚可供我们使用,而EMIO有64个引脚可供我们使用。

使用EMIO的好处就,当MIO不够用时,PS可以通过驱动EMIO控制PL部分的引脚,接下来就来详细介绍下EMIO的使用。

EMIO的使用和MIO的使用其实是非常相似的。区别在于,EMIO的使用相当于,是一个PS + PL的结合使用的例子。所以,EMIO需要分配引脚,以及编译综合生成bit文件。

我们从添加ZYNQ的IP开始讲,这次添加一个配置更加简洁的ZYNQ IP:

clip_image004

添加了zynq IP之后,点击Run Block Automation,将DDR等引脚引出:

clip_image006

还是双击点击进入从新配置,选择Default:

clip_image008

再将EMIO引出8个引脚(最多能引出64个),引出的引脚都是按bank2到bank3顺序排列的,也就是说53个MIO之后,我们引出的这8个EMIO,分别是54~61号引脚,之后会在程序中体现。

clip_image010

PL的输出时钟,也勾选掉不要:

clip_image012

我们,没有用到AXI总线,这个也勾选掉不要:

clip_image014

OK,完成ZYNQ核的配置.

右击GPIO_0引脚部分,选择make external把GPIO_0引脚引出,

clip_image016

依然是,右键单击Block,文件选择Generate the output products,是文件得到一定的约束:

clip_image018

继续右键单击Block,文件选择Create a HDL wrapper,创建一个HDL 的顶层文件:

clip_image020

clip_image022

这里我们得去瞧瞧,Vivado到底给我创建了这样的顶层:

clip_image024

我们发现,之前引出的EMIO——GPIO_0,到了顶层他的名字叫gpio_0_tri_io,而不是GPIO_0。所以分配引脚的时候就要注意了名字别错了,

创建一个约束文件,分配引脚如下:

set_property PACKAGE_PIN T22 [get_ports {gpio_0_tri_io[0]}]

set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[0]}]

set_property PACKAGE_PIN T21 [get_ports {gpio_0_tri_io[1]}]

set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[1]}]

set_property PACKAGE_PIN U22 [get_ports {gpio_0_tri_io[2]}]

set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[2]}]

set_property PACKAGE_PIN U21 [get_ports {gpio_0_tri_io[3]}]

set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[3]}]

set_property PACKAGE_PIN V22 [get_ports {gpio_0_tri_io[4]}]

set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[4]}]

set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[5]}]

set_property PACKAGE_PIN W22 [get_ports {gpio_0_tri_io[5]}]

set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[6]}]

set_property PACKAGE_PIN U19 [get_ports {gpio_0_tri_io[6]}]

set_property IOSTANDARD LVCMOS33 [get_ports {gpio_0_tri_io[7]}]

set_property PACKAGE_PIN U14 [get_ports {gpio_0_tri_io[7]}]

可以,开始生成bit文件了:

clip_image026

编译成功之后,依然是导出硬件,打开SDK,然后新建一个工程,以及添加一个main.C文件,具体过程参加上一篇笔记。

添加程序如下:

#include <stdio.h>

#include "xgpiops.h"

#include "sleep.h"

#include <stdio.h>
#include "xgpiops.h"
#include "sleep.h"


int main()
{
	static XGpioPs psGpioInstancePtr;
	XGpioPs_Config* GpioConfigPtr;
	int iPinNumber= 54;			//54,EMIO的第一个引脚
	u32 uPinDirection = 0x1;	//1表示输出,0表示输入
	int xStatus;

	//--IO的初始化
	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");
	//--IO的输入输出操作
	XGpioPs_SetDirectionPin(&psGpioInstancePtr, iPinNumber,uPinDirection);//配置MIO输出方向
	XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, iPinNumber,1);//配置MIO的第7位输出
	//--IO的段操作
	XGpioPs_SetDirection(&psGpioInstancePtr,2,0xffffffff);		//bank2的EMIO全部配置成输出
	XGpioPs_SetOutputEnable(&psGpioInstancePtr,2,0xffffffff);	//bank2的EMIO全部使能
	XGpioPs_Write(&psGpioInstancePtr,2,0x50);					//对整个bank2的IO进行段操作
	while(1)
	{
		XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 1);//点亮
		sleep(1);											//延时
		XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 0);//熄灭
		sleep(1);											//延时
	}

	return 0;
}

我们发现,驱动EMIO和MIO基本是一模一样的,上篇笔记中的添加的"xgpio.h"其实是多此一举,上次的程序中我们只要把

static XGpio psGpioInstancePtr;

这句替换成:

static XGpioPs psGpioInstancePtr;

"xgpio.h"其实是为系统自带的以总线的方式驱动IO的GPIO核服务的。这一点也是很容易搞错的地方。(呵呵,我之前就弄错了)GPIO核的使用也非常简单,我看看是否在下篇笔记里讲讲。

调试过程,也和上次笔记基本一样(请参考上篇笔记),不同的是,在此之前得先下载bit文件,下载文件可以直接在SDK中进行:

clip_image028

clip_image030

这次我们看看,如何在线调试,点击状态栏中的小爬虫:

clip_image032

clip_image034

最后,想说明一点,SDK的调试功能。不管是在线调试还是调试,这个不是非常好用,可能存在有时可以有时又不行(zed,和MiZ702我都试过),所以一定要确保USB线的稳定,最后插到电脑主机后面的USB,或者弄一个好点的可以单独供电的USB分线器。