FPGA—ZYNQ学习GPIO-EMIO,MIO,AXIGPIO(五)
通过zynq实现mio以及EMIO和axigpio去控制外部设备。
对GPIO 以及库文件进行讲解
emio 和mio都是通过ps端控制的,mio是ps通过gpio口直接连接到输出管脚,这里是直接从ps端口直接到输出管脚。emio是ps通过gpio到pl侧在连接到输出管脚需要再PL测进行引脚分配。 axigpio是通过PL侧进行生成一个gpio,然后分配管脚
GPIO 这个能够控制emio和mio
都可以用这个管脚进行分配

打开板级支持包,打开函数库看

gpio初始化 pin脚 ,以及pin脚写入,输入还是输出,输入输出使能
查看示例工程,进行模仿示例工程编写
点击SYSTEM.MSS

点击导入示例

打开示例工程,然后看到函数库,这个是需要用到的库函数

例化的库函数共五个以及功能

#includexparameters.h
可以看到一些地址基址


#includexstatus.h
看到返回到的状态

对于需要用到某个设备的时候需要去找ID号,进行操作也就是用哪个就找哪个
代码讲解

这个代码的意思就是定义一个结构体类型的指针,configptr是一个结构体,里面有一些配置信息。寻找需要配置gpio的设备ID,给configptr 一个地址,该地址就是用到了哪个gpio口的地址。就相当于这个结构体是有地址的了,里面一些变量类型本来都是有基址的也是偏移地址,加上CONFIGptr的地址,就能具体知道这个结构体以及里面变量的具体地址了。
然后要引入结构体实例gpio它是程序用来代表和控制底层硬件GPIO控制器的一个“句柄”或“代理”。
XGpioPs Gpio; // 声明一个XGpioPs类型的结构体变量
XGpioPs是Xilinx软件开发工具包(SDK或Vitis)中定义的一个结构体类型。这个结构体内包含了很多成员变量,用于记录一个GPIO控制器的所有软件和状态信息,例如:•指向配置信息的指针(
ConfigPtr)。控制器的基地址(
BaseAddr)。各个引脚的方向(输入/输出)。
中断相关的配置和状态。
一个标志位(
IsReady),用于指示该驱动实例是否已经初始化完成。
把这个实例的地址送到初始化函数里,就是告诉这个函数需要对gpio进行初始化了,这个gpio结构体里面有很多相关信息。有这个实例再把configptr的地址送进去,以及CONFIGPTR的其中变量名baseaddr的地址。进行初始化。
主函数main.c
/*main 通过zynq实现mio以及EMIO和axigpio去控制外部设备 这是主函数 需要例化库文件进行函数的调用
库函数里面是例化的各个函数头。*/#include "main.h"
#include "gpio.h"XGpioPs ZYNQ_GPIO; //GPIO控制器结构体
XGpio AXI_GPIO;int main()
{int key_status = 0; //按键状态xil_printf("start\r\n"); //通过串口打印startGpioInit(&ZYNQ_GPIO,XPAR_PS7_GPIO_0_DEVICE_ID); //初始化GPIOGpioInputSet(&ZYNQ_GPIO,KEY); //将GPIO的方向设置为输入GpioOutputSet(&ZYNQ_GPIO,LED); //将LED设置为输出AxiGpioInit(&AXI_GPIO,XPAR_AXI_GPIO_0_DEVICE_ID); //初始化AXI_GPIOAxiGpioOutputSet(&AXI_GPIO,1); //将AXI GPIO的1通道设置为输出while(1) //程序运行的死循环{key_status = GpioReadData(&ZYNQ_GPIO,KEY); //读取按键引脚电平状态xil_printf("key:%d\r\n",key_status); //打印按键引脚电平状态GpioOutData(&ZYNQ_GPIO,LED,key_status); //将按键的状态输出给LEDAxiGpioWriteData(&AXI_GPIO,1,key_status); //将按键的状态输出给AXI GPIO}return 0;
}主函数的库文件main.h
/*#main.h*/
#ifndef SRC_MAIN_H_
#define SRC_MAIN_H_#include "xparameters.h"
#include "xgpiops.h"
#include "xstatus.h"
#include "xplatform_info.h"
#include <xil_printf.h>#define KEY 0
#define LED 54#endif /* SRC_MAIN_H_ */
gpio的函数文件gpio.c
/*gpio.c*/#include "gpio.h"int GpioInit(XGpioPs *Gpio,u16 DeviceId)
{int Status;XGpioPs_Config *ConfigPtr;ConfigPtr = XGpioPs_LookupConfig(DeviceId);Status = XGpioPs_CfgInitialize(Gpio, ConfigPtr,ConfigPtr->BaseAddr);if(Status != XST_SUCCESS){return XST_FAILURE;}return XST_SUCCESS;
}int GpioOutputSet(XGpioPs *Gpio,int pin)
{XGpioPs_SetDirectionPin(Gpio, pin, 1);XGpioPs_SetOutputEnablePin(Gpio, pin, 1);return XST_SUCCESS;
}int GpioInputSet(XGpioPs *Gpio,int pin)
{XGpioPs_SetDirectionPin(Gpio, pin, 0);return XST_SUCCESS;
}void GpioOutData(XGpioPs *Gpio,int pin,int data)
{XGpioPs_WritePin(Gpio, pin, data);
}int GpioReadData(XGpioPs *Gpio,int pin)
{return XGpioPs_ReadPin(Gpio, pin);
}int AxiGpioInit(XGpio *AxiGpio,u16 DeviceId)
{int Status;Status = XGpio_Initialize(AxiGpio,DeviceId);if (Status != XST_SUCCESS) {return XST_FAILURE;}return XST_SUCCESS;
}void AxiGpioOutputSet(XGpio *AxiGpio,int pin)
{XGpio_SetDataDirection(AxiGpio, pin,0);
}void AxiGpioInputSet(XGpio *AxiGpio,int pin)
{XGpio_SetDataDirection(AxiGpio, pin,1);
}void AxiGpioWriteData(XGpio *AxiGpio,int pin,int data)
{XGpio_DiscreteWrite(AxiGpio,pin,data);
}int AxiGpioReadData(XGpio *AxiGpio,int pin)
{return XGpio_DiscreteRead(AxiGpio,pin);
}gpio的库文件gpio.h
/* gpio.h 这里面的头文件是官方的库文件,下面的函数是.c文件的函数头文件,需要写出来在库文件中*/ #ifndef SRC_GPIO_H_
#define SRC_GPIO_H_#include "xparameters.h"
#include "xgpiops.h"
#include "xgpio.h"
#include "xstatus.h"
#include "xplatform_info.h"
#include <xil_printf.h>int GpioInit(XGpioPs *Gpio,u16 DeviceId);
int GpioOutputSet(XGpioPs *Gpio,int pin);
int GpioInputSet(XGpioPs *Gpio,int pin);
void GpioOutData(XGpioPs *Gpio,int pin,int data);
int GpioReadData(XGpioPs *Gpio,int pin);int AxiGpioInit(XGpio *AxiGpio,u16 DeviceId);
void AxiGpioOutputSet(XGpio *AxiGpio,int pin);
void AxiGpioInputSet(XGpio *AxiGpio,int pin);
void AxiGpioWriteData(XGpio *AxiGpio,int pin,int data);
int AxiGpioReadData(XGpio *AxiGpio,int pin);#endif /* SRC_GPIO_H_ */
