1、ZYNQ PS中的外设通过MIO连接到PS端引脚;通过EMIO连接到PL端引脚。
2、Zynq-7000有54个MIO,有64个EMIO。
3、GPIO分为4个Bank,其中Bank0和Bank1连接到MIO;Bank2和Bank3连接到EMIO。
4、Bank1--22bit;Bank0--32bit;Bank1--32bit;Bank2--32bit
5、MIO7和MIO8只能作为输出IO使用
6、目的:使用GPIO通过MIO引脚控制PS端LED的亮灭
7、ZYNQ小系统板有2个GPIO_MIO连接到外设LED和KEY,这些GPIO_MIO使用来驱动外设LED和KEY,并且由于是PS端引脚,不需要再PL中进行引脚未知约束。
8、没有用到PL部分,无需生成Bitstream文件
9、编程步骤:
step1:先对GPIO控制器进行初始化
step2:对MIO引脚设置方向为输出并进行输出使能
step3:MIO引脚的高电平对应的LED灯亮,低电平灭

#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID
#define:这是一个预处理指令,用于定义一个宏。宏定义在编译时会被替换为指定的值。
GPIO_DEVICE_ID:这是定义的宏名称,表示 GPIO 设备的 ID。
XPAR_XGPIOPS_0_DEVICE_ID:这是宏的值,表示具体的 GPIO 设备 ID。这个值通常是 Xilinx 平台自动生成的参数,用于标识特定的 GPIO 外设。
XGpioPs Gpio; // GPIO设备的驱动程序实例
XGpioPs:这是 Xilinx 提供的一个结构体类型,用于表示 ZYNQ 平台上的 GPIO 外设驱动程序。它包含了与 GPIO 外设通信所需的所有寄存器定义、函数指针和其他相关成员。
Gpio:这是声明的变量名,表示 GPIO 设备的驱动程序实例。通过这个实例,可以调用相关的函数来控制和操作 GPIO 引脚。
XGpioPs结构体:
XGpioPs_Config *ConfigPtr;
XGpioPs_Config:这是一个结构体类型,通常由 Xilinx 提供,用于描述 GPIO 外设的配置信息。它包含了与 GPIO 外设相关的寄存器基地址、中断 ID 等信息。
*ConfigPtr:这表示 ConfigPtr 是一个指针,它指向的类型是 XGpioPs_Config。也就是说,ConfigPtr 存储的是一个 XGpioPs_Config 结构体实例的内存地址。
声明了一个指针变量 configPtr
,它指向一个 XGpioPs_Config
类型的结构体实例的地址
ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
ConfigPtr:这是一个指向 XGpioPs_Config 结构体的指针变量,用于存储 GPIO 设备的配置信息的地址。
XGpioPs_LookupConfig:这是 Xilinx 提供的一个函数,用于根据设备 ID 查找 GPIO 设备的配置信息。函数的返回值是一个指向 XGpioPs_Config 结构体的指针。
GPIO_DEVICE_ID:这是一个宏定义,表示 GPIO 设备的 ID,通常在 xparameters.h 文件中定义。
XGpioPs_LookupConfig()函数返回值是一个指向XGpioPs_Config 结构体的指针。
ConfigPtr
是一个指向 XGpioPs_Config
结构体的指针。这个指针存储了 XGpioPs_Config
结构体实例的内存地址。BaseAddr
是 XGpioPs_Config
结构体中的一个成员变量,通常表示 GPIO 设备的基地址。
Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
Status:这是一个变量,用于存储函数 XGpioPs_CfgInitialize 的返回值。返回值通常用于表示函数调用是否成功。
XGpioPs_CfgInitialize:这是 Xilinx 提供的一个函数,用于初始化 GPIO 驱动程序实例。
&Gpio:这是 GPIO 驱动程序实例的地址,表示要初始化的 GPIO 实例。
ConfigPtr:这是一个指向 XGpioPs_Config 结构体的指针,包含了 GPIO 设备的配置信息。
ConfigPtr->BaseAddr:这是 GPIO 设备的基地址,用于标识设备在内存映射中的位置。
函数作用:XGpioPs_CfgInitialize 函数的作用是使用提供的配置信息和基地址来初始化 GPIO 驱动程序实例。这个函数通常在获取到 GPIO 配置信息后调用,以确保 GPIO 设备能够正确地与软件进行交互
/*****************************************************************************/
/*
*
* This function initializes a XGpioPs instance/driver.
* All members of the XGpioPs instance structure are initialized and
* StubHandlers are assigned to the Bank Status Handlers.
*
* @param InstancePtr is a pointer to the XGpioPs instance.
* @param ConfigPtr points to the XGpioPs device configuration structure.
* @param EffectiveAddr is the device base address in the virtual memory
* address space. If the address translation is not used then the
* physical address should be passed.
* Unexpected errors may occur if the address mapping is changed
* after this function is invoked.
*
* @return XST_SUCCESS always.
*
* @note None.
*
******************************************************************************/
s32 XGpioPs_CfgInitialize(XGpioPs *InstancePtr, const XGpioPs_Config *ConfigPtr,
u32 EffectiveAddr)
{
s32 Status = XST_SUCCESS;
u8 i;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(ConfigPtr != NULL);
Xil_AssertNonvoid(EffectiveAddr != (u32)0);
/*
* Set some default values for instance data, don't indicate the device
* is ready to use until everything has been initialized successfully.
*/
InstancePtr->IsReady = 0U;
InstancePtr->GpioConfig.BaseAddr = EffectiveAddr;
InstancePtr->GpioConfig.DeviceId = ConfigPtr->DeviceId;
InstancePtr->Handler = (XGpioPs_Handler)StubHandler;
InstancePtr->Platform = XGetPlatform_Info();
/* Initialize the Bank data based on platform */
if (InstancePtr->Platform == (u32)XPLAT_ZYNQ_ULTRA_MP) {
/*
* Max pins in the ZynqMP GPIO device
* 0 - 25, Bank 0
* 26 - 51, Bank 1
* 52 - 77, Bank 2
* 78 - 109, Bank 3
* 110 - 141, Bank 4
* 142 - 173, Bank 5
*/
InstancePtr->MaxPinNum = (u32)174;
InstancePtr->MaxBanks = (u8)6;
}
else if (InstancePtr->Platform == (u32)XPLAT_VERSAL)
{
if(InstancePtr->PmcGpio == (u32)FALSE)
{
/* Max pins in the PS_GPIO devices
* 0 -25, Bank 0
* 26-57, Bank 3
*/
InstancePtr->MaxPinNum = (u32)58;
InstancePtr->MaxBanks = (u8)4;
}
else
{
/* Max pins in the PMC_GPIO devices
* 0 - 25,Bank 0
* 26 - 51,Bank 1
* 52 - 83,Bank 3
* 84 - 115, Bank 4
*/
InstancePtr->MaxPinNum = (u32)116;
InstancePtr->MaxBanks = (u8)5;
}
}
else {
/*
* Max pins in the GPIO device
* 0 - 31, Bank 0
* 32 - 53, Bank 1
* 54 - 85, Bank 2
* 86 - 117, Bank 3
*/
InstancePtr->MaxPinNum = (u32)118;
InstancePtr->MaxBanks = (u8)4;
}
/*
* By default, interrupts are not masked in GPIO. Disable
* interrupts for all pins in all the 4 banks.
*/
for (i=(u8)0U;i<InstancePtr->MaxBanks;i++) {
if (InstancePtr->Platform == XPLAT_VERSAL){
if(InstancePtr->PmcGpio == (u32)FALSE)
{
if((i== (u8)XGPIOPS_ONE)||(i== (u8)XGPIOPS_TWO))
{
continue;
}
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(i) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTDIS_OFFSET, 0xFFFFFFFFU);
}
else
{
if(i==(u32)XGPIOPS_TWO)
{
continue;
}
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(i) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTDIS_OFFSET, 0xFFFFFFFFU);
}
}
else
{
XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
((u32)(i) * XGPIOPS_REG_MASK_OFFSET) +
XGPIOPS_INTDIS_OFFSET, 0xFFFFFFFFU);
}
}
/* Indicate the component is now ready to use. */
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
return Status;
}
#include "xparameters.h" //器件参数信息
#include "xstatus.h"//包含XST_FAILURE 和XST_SUCCESS 的宏定义
#include "xil_printf.h" //包含 print()函数
#include "xgpiops.h" //包含PS GPIO 的函数
#include "sleep.h" //包含sleep()函数
//宏定义GPIO_DEVICE_ID
#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID
//连接到MIO的LED
#define MIOLED0 7 //连接到PS的MIO7引脚
XGpioPs Gpio;// GPIO设备的驱动程序实例
int main()
{
int Status;
XGpioPs_Config *ConfigPtr;
print("MIO Test ! \n\r");
ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID); //输入 ID,得到XGpioPs_Config实例的指针
Status = XGpioPs_CfgInitialize(&Gpio,ConfigPtr,ConfigPtr->BaseAddr);//初始化GPIO
if(Status != XST_SUCCESS){
return XST_FAILURE;
}
//设置指定引脚的方向:0输入,1输出
XGpioPs_SetDirectionPin(&Gpio,MIOLED0,1);
//使能指定引脚输出:0禁止输出使能,1使能输出
XGpioPs_SetOutputEnablePin(&Gpio,MIOLED0,1);
while(1){
XGpioPs_WritePin(&Gpio,MIOLED0,0x0); //0x0 灭
sleep(1);
XGpioPs_WritePin(&Gpio,MIOLED0,0x1); //0x1 亮
sleep(1);
}
return XST_SUCCESS; 向指定引脚写入数据
}