MIO实验的主要目的包括以下:
1、掌握利用VIVADO,添加GPIO
2、掌握SDK库函数控制输出GPIO
3、掌握SDK直接操作寄存器控制GPIO输出
然后有关于第一节中提到的那本修炼秘籍,确实挺好用的,看书肯定是要比看视频快的,所以,之后会以书籍资料为主,视频资料为辅。书籍资料的相关资源如下:https://download.csdn.net/download/iatkotw1998/10868176。
1.1、54个MIO分配在GPIO的Bank0~1隶属PS部分,这些IO与PS直接相连,不需要添加引脚约束,MIO信号对PL部分是透明的。所以对MIO的操作可以看作是纯PS的操作。
1.2、我们在SDK下软件操作底层都是对于内存地址空间的操作,因此需要找到GPIO的控制和状态寄存器基地址。
2.1、为了操作简单,完全可以把上一节的工程粘贴过来,这样就不需要重建了。当然,名字的话就还是和以前一样的没法改了。还有就是最好把SDK删掉。
2.2、在GPIO设置中,如果前面使用到了相应的MIO,那么已有的数目会相应减少。
因为前面勾选上了SD,所以会相应的减少很多的MIO
2.3、要记得保存后进行 Validate Design ,检查设计是否有问题。
2.4、注意 generate output produce 是在 .bd 文件处进行右键选择的。所以如果在对 block design 进行修改之后要重新 generate 相关文件。
2.5、代码分析(但其实我挺好奇的,怎么向一个管脚里写入非0或者1的值?之后再试试看吧)
/*
* main.c
*
* Created on: 2018年12月21日
* Author: Tiputer
*/
#include "xgpiops.h"
#include "sleep.h"
int main()
{
static XGpioPs psGpioInstancePtr;
XGpioPs_Config* GpioConfigPtr;
int iPinNumber= 7; //LD9连接的是MIO7
u32 uPinDirection = 0x1; //1表示输出, 0表示输入
int xStatus;
/*--MIO的初始化,XGpiops_Lookupconfig()这个函数是一个 xilinx 官方提供的 GPIO
的查找配置的函数, 程序的参数为要查找的 GPIO 的基地址。这段话的整体意思就是查找 GPIO 的配
置, 然后判断其是否为空, 若为空则返回查找失败。*/
GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
if(GpioConfigPtr == NULL)
return XST_FAILURE;
//完成的是 gpio 配置的初始化工作
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输出方向,包括寻找bank号以及设置方向寄存器DIRM
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, iPinNumber,1);
//配置MIO的第7位输出,设置的原理是一样的
while(1)
{
XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 1);//点亮MIO的第7位输出1
usleep(500000); //延时
XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 0);//熄灭MIO的第7位输出0
usleep(500000); //延时
}
/*这一段和前面那一段本质上是一致的,XGpioPs_WritePin()底层调用的本来也就是XGpioPs_WriteReg(),但显然的一点是,后面的这种方式速度会更快,少了很多重复的工作*/
/****************************************************************
while(1)
{
XGpioPs_WriteReg(0xE000A000,0x00000000, 0xFF7FFFFF&0xFFFF0080);
usleep(500000); //延时
XGpioPs_WriteReg(0xE000A000,0x00000000, 0xFF7FFFFF&0xFFFF0000);
usleep(500000); //延时
} *
*****************************************************************/
return 0;
}
2.5.1 解释前面提出的问题,如果非0和1怎么办?如果继续往底层看,里面有一行代码“ DataVar &= (u32)0x01; ”。很显然这里也就限制其对应的值只能是0或者1了。
2.6 进一步分析,因为xilinx没有对应的函数手册,所以我们要自己学会查找基地址和相应的参数。
2.6.1 例如LD9对应的MIO7,学会上电路原理图查找。
2.6.2 再如GPIO的基地址以及相关寄存器偏移地址的查询(https://www.xilinx.com/support/documentation/user_guides/ug585-Zynq-7000-TRM.pdf)
ps部分的基地址都是定义好的
然后下图的部分便是GPIO的偏移地址了
2.6.3 再者就是要注意某一个寄存器或者官方代码中给出的一些完全没有概念的量,要学会自己去查找。
2.6.4 那么,写MIO的步骤其实就是先找到对应的MIO所在的bank中的对应PinNumber。然后需要独立更改值,所以需要两个16位的寄存器,判断大于16还是小于16,使用对应的寄存器。然后前16位和后16位分别决定使能和写入0还是1。
---------------------------------------完,欢迎指正,互相学习,很多学习资料分享请关注前几节的博客--------------------------------------