这里写目录标题
简介
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。
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设计
因为这里不涉及到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;但是一直运行的卡住,不知道什么情况,我实例化指针不行么,搞了好久才发现这个情况,有大神懂得也可以指导下我。