软件环境:vivado 2017.4 硬件平台:XC7Z020
由下图可见,MIO在BANK0和BANK1直接跟PS部分相连,EMIO在BANK2和BANK3和PL部分相连,除了BANK1是22bit之外,其他BANK都是32bit。所以在EMIO部分,有64个引脚可以供我们使用,而使用EMIO的好处就是,当MIO不够用时候,PS可以通过EMIO控制PL部分的引脚。
vivado 2017.4 -------->Create Block Design -------->ZYNQ7 Processing System大致配置与MIO相同,这里勾EMIO,我有4个IO控制的LED,就勾了宽度为4。
Generate the Output Products------>Create HDL wrapper以后,IP如下。
双击生成好的顶层文件以后,可以看到。PL部分EMIO接口名字已经有了。
接下来添加硬件管脚约束部分,创建个Constraints,添加代码如下。J16、K16、G15、H15分别是我4个LED的管脚。大括号里的名字要注意一定要跟上图的接口对应。
set_property PACKAGE_PIN J16 [get_ports {EMIO_0_tri_io[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {EMIO_0_tri_io[0]}]
set_property PACKAGE_PIN K16 [get_ports {EMIO_0_tri_io[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {EMIO_0_tri_io[1]}]
set_property PACKAGE_PIN G15 [get_ports {EMIO_0_tri_io[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {EMIO_0_tri_io[2]}]
set_property PACKAGE_PIN H15 [get_ports {EMIO_0_tri_io[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {EMIO_0_tri_io[3]}]
生成bit stream文件、export hardware,然后导入SDK。new 一个 application。添加main部分代码如下。
#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;
}
SDK程序部分大体上与MIO相同,都是
通过XGpioPs_LookupConfig函数,找到所设备的基址------------>
通过XGpioPs_CfgInitialize函数,初始化设备配置------------>
通过XGpioPs_SetDirectionPin函数,设置GPIO引脚方向------------>
通过XGpioPs_SetOutputEnablePin函数,使能GPIO输出------------>
通过XGpioPs_WritePin函数,设置GPIO输出高低电平。
至于这里PIN脚号为什么是从54~57,妈耶,最开始的说明和图上标的很清楚,MIO部分是从0:53一共54个腿,那EMIO部分当然是从54开始,我用了4个,肯定是54~57咯。晚安,爱你。