两个星期没有更新了,入手板子一段时间以来发现难度还是挺大的,但是心急吃不了热豆腐,所以打算还是从基础的一步一步来,实现对GPIO操作。
ZYNQ7000上GPIO分为2类MIO和EMIO,MIO和常见的CPU管脚功能是一样的和很多外设是复用的,在使用前需要进行PIN Assignment.MIO共54个管脚分布在BANK0和BANK1 ,BANK1有32个,BANK2有22个每个BANK可以设置不同的电压等级.MIO控制寄存器对应的基地址是0xE000A000但是在编译生成硬件包装时要对ps进行设置,不然MIO对应的引脚没有映射出硬件地址
在ZYNQ里面到处SDK生成硬件地址文件System.hdf
而EMIO(全称是Extendable MIO,即可扩展的MIO)是从PL侧扩展出的GPIO管脚(就像当于传统的FPGA提供了几个内存影射的寄存器,这些寄存器可用控制这些FPGA的官脚,同时这些寄存器地址对PS可直接访问。
在xparameters.h文件里生成的对应硬件地址为两个,分别配置对应的GPIO:
API函数接口只能去赛灵思官网找手册
GPIO外设提供的API函数实质就是把Xil_Out这样的函数封装了罢了
#define RTC_IP_mWriteReg(BaseAddress, RegOffset, Data) \
Xil_Out32((BaseAddress) + (RegOffset), (u32)(Data))
void Xil_Out32(INTPTR Addr, u32 Value)
{
u32 *LocalAddr = (u32 *)Addr;
*LocalAddr = Value;
}
最后分别使用了PL端核PS端的GPIO驱动导致灯。
#include "xgpiops.h"
#include "xgpio.h"
#include "sleep.h"
#include "platform.h"
int main()
{
init_platform();
u32 Delay;
u32 Ledwidth;
static XGpioPs psGpioInstancePtr;
XGpioPs_Config* GpioConfigPtr;
XGpio GpioOutput;
int iPinNumber= 0; //LD9连接的是MIO0
int iPinNumber1= 13; //LD9连接的是MIO0
u32 uPinDirection = 0x1; //1表示输出,0表示输入
int xStatus,status;
//--MIO的初始化
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");
//--MIO的输入输出操作
XGpioPs_SetDirectionPin(&psGpioInstancePtr, iPinNumber,uPinDirection);//配置MIO输出方向
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, iPinNumber,1);//配置MIO的第7位输出
XGpioPs_SetDirectionPin(&psGpioInstancePtr, iPinNumber1,uPinDirection);//配置MIO输出方向
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, iPinNumber1,1);//配置MIO的第7位输出
//EMIO
status=XGpio_Initialize(&GpioOutput, XPAR_AXI_GPIO_0_DEVICE_ID); //initialize GPIO IP
if(status != XST_SUCCESS) return XST_FAILURE;
XGpio_SetDataDirection(&GpioOutput, 1, 0x0); //set GPIO as output
XGpio_DiscreteWrite(&GpioOutput, 1, 0x0); //set GPIO output value to 0
while(1)
{
XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 1);//点亮MIO的第7位输出1
XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber1, 1);//点亮MIO的第7位输出1
for (Ledwidth = 0x0; Ledwidth < 4; Ledwidth++)
{
XGpio_DiscreteWrite(&GpioOutput, 1, 1 << Ledwidth);
for (Delay = 0; Delay < 8000000; Delay++);
XGpio_DiscreteClear(&GpioOutput, 1, 1 << Ledwidth);
}
sleep(1); //延时
XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 0);//熄灭MIO的第7位输出0
XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber1, 0);//熄灭MIO的第7位输出0
sleep(1); //延时
}
init_platform();
return 0;
}