ZYNQ学习之旅--PS_MIO

这里写目录标题

简介

Zynq-7000 系列芯片有 54 个 MIO(Multiplexed I/O),个别芯片除外如 7z007s 只有 32 个。图 是GPIO 的框图,从中我们可以看到 GPIO 分为 4 个 Bank,注意这里不包括 AXI_GPIO。除 Bank1 之外的 Bank 都具有 32bit,Bank1 只具有 22bit 是因为总共只有 54 个 MIO,其中 32bit 的Bank0 控制了 MIO[0~31],剩下的 MIO[31~53]就由 22bit 的 Bank1 控制。Bank2 和 Bank3 用于控制扩展的MIO 即 EMIO,也就是说总共可以有 32+32=64 个 EMIO。
ZYNQ学习之旅--PS_MIO
PS 所有的外设都可以通过 MIO 访问,这些外设也是与 MIO 进行连接,每个 MIO 虽然可以独立控制,
以及独立驱动单个引脚的外设,但对于 QSPI、USB、以太网等这些外设,其于 MIO 的连接有着特殊的要求,如图 所示,(图中灰色框表示在 CLG225 封装的芯片中不可用)对于以太网而言,其只能与 MIO16~27和 MIO28~39 引脚连接,而且以太网与 MIO28 连接的引脚只能作为以太网的 tx_clk 使用,可见当其作为以太网的接口引脚时,相应的 MIO 的功能就已经确定下来了。MIO 还有一特点,如 MIO28~39 引脚即可以与以太网进行连接,也可以作为USB以及其它外设的接口引脚,所以当我们设计PS的外设时要合理分配MIO。从图中 MIO 一览表中我们可以看到 MIO 一但选定,引脚位置就已经确定下来了,不需要添加引脚约束。

试验任务

本次的实验任务是使用 PS 的 MIO 控制 LED 的亮灭。

BD设计

ZYNQ学习之旅--PS_MIO
因为这里不涉及到PL端的资源,只用到了PS端的资源,所以只需要对PS端的资源进行配置就好了。

软件设计

/*
 * main.c
 *  Created on: 2020年6月26日
 */
#include "xparameters.h"
#include "xgpiops.h"
#include "xstatus.h"
#include "xplatform_info.h"
#include <xil_printf.h>
#include <xil_types.h>
#include "platform.h"
#define printf			xil_printf	/* Smalller foot-print printf */
//PS_GPIO ID号定义
#define GPIO_DEVICE_ID  XPAR_XGPIOPS_0_DEVICE_ID
//定义管脚输入还是输出
#define 	input 		0
#define 	output 		1
//定义使能
#define		enable		1
#define		disable		0
//定义管脚
#define 	PS_LED1 	50
#define 	PS_LED2 	51
#define 	PS_KEY1 	0
#define 	PS_KEY2 	47

XGpioPs gpio_inst;	//实例化的时候为什么不能直接实例化指针呢?

int main()
{
	init_platform();
	//对PS端的GPIO进行查找和初始化
	XGpioPs_Config *ps_config;
	int status;
	u32 data1,data2;
	printf("PS_GPIO test\n");
	ps_config = XGpioPs_LookupConfig(XPAR_XGPIOPS_0_DEVICE_ID);
	printf("hh\n");
	status = XGpioPs_CfgInitialize(&gpio_inst, ps_config,ps_config->BaseAddr);
	printf("%d",status);
	if(status!=XST_SUCCESS){
		print("初始化失败\n");
		return XST_FAILURE;
	}
	printf("success initialize\n");
	//对PS_GPIO自检
	status = XGpioPs_SelfTest(&gpio_inst);
	if(status!=XST_SUCCESS){
		printf("selftest failed\n");
		return XST_FAILURE;
	}
	printf("success selftest\n");
	//定义key为输入的方向
	XGpioPs_SetDirectionPin(&gpio_inst,PS_KEY1,input);
	XGpioPs_SetDirectionPin(&gpio_inst,PS_KEY2,input);
	//定义LED为输出方向
	XGpioPs_SetDirectionPin(&gpio_inst,PS_LED1,output);
	XGpioPs_SetDirectionPin(&gpio_inst,PS_LED2,output);
	//输出管脚使能
	XGpioPs_SetOutputEnablePin(&gpio_inst, PS_LED1, enable);
	XGpioPs_SetOutputEnablePin(&gpio_inst, PS_LED2, enable);
	//死循环,不断读取按键状态,并赋值给led
	while(1){
		//读管脚
		data1 = XGpioPs_ReadPin(&gpio_inst, PS_KEY1);
		data2 = XGpioPs_ReadPin(&gpio_inst, PS_KEY2);
		//写管脚
		XGpioPs_WritePin(&gpio_inst, PS_LED1, data1);
		XGpioPs_WritePin(&gpio_inst, PS_LED2, data2);
	}
	return 0;
}

这里有个问题,我开始的时候定义的是XGpioPs *gpio_inst;但是一直运行的卡住,不知道什么情况,我实例化指针不行么,搞了好久才发现这个情况,有大神懂得也可以指导下我。

上一篇:ZYNQ裸板简单实战—IO篇


下一篇:关于Xilinx FPGA/ZYNQ的引脚定义