前面我们介绍过EMIO,但是不详细。MIO是PS的IO接口,这个M代表的是Multiuse,也就是多用途,在下图中我们可以看到54个MIO连接这么多东西,必须得复用,所以当我们开发的时候需要的功能配置上,不需要的去掉,防止IO口被占用。
板子用的是zc702。
下面我们双击ZYNQ核:
我们到MIO的配置里,把其他的勾都去掉,去GPIO里看看:
这些都是使用其默认连接的,比如说MIO[6...2]这些就是配置启动模式用的:
回头我们勾选上UART1,这个是我们打印消息的时候要用到,默认用的是48,49,当然用户是可以选择用哪些可用端口的:
我们再勾选一个以太网,发现这个功能可以用MIO连接上使用,也可以用EMIO连接上使用:
我们在勾选一个USB1试试,发现USB1用到的MIO和UART1冲突了,出现了红色报错,他俩都用到了一些相同的MIO口:
当然我们可以修改UART1用到的IO避免冲突。比如说我们把它改层8,9两个口:
这时候就不冲突了。
但是一个新的问题出现了,我们到GPIO里去看看:
这时候MIO8,9不见了,这两个被配置去实现UART了,那么原先它俩的默认连接就不可以用了:
MIO[8]是连接LED灯DS12的:
MIO[9]是配置CAN总线的:
现在我们对MIO有固定连接有了一个较清晰的认识,而且一些MIO是可以被重新配置干其他事情的,那么现在问题来了,PS想用一些PL外设,它们的数据交互比较简单,犯不着动用AXI总线,但是这些外设又没有一个MIO接口可以配置,比方说用户按键,或者说配置了好多外设了,MIO都用完了,这时EMIO就派上用场了,E代表的是Extendable,意思就是扩展MIO,它的作用就是MIO,不过不是PS上固定引脚,固定连接的,它们是PL上的引脚,连接到PS上,所以使用时PL,CPU资源都有消耗。既然是PL上的逻辑资源,它连接到什么设备当然要进行管教脚约束了。
现在我们进行一个简单的实验,感受一下MIO,EMIO的使用——用按键SW5去控制DS12.
通过前面的分析,我们知道,DS12是连接带MIO[8]上的,SW5没有MIO连接,我们将EMIO将它接到芯片上,这样CPU就可以跟SW5进行数据交互了。
PS的配置如下:
这里勾选UART1,主要是为了后面打印消息。
一个很简单的系统,master GP接口,PL时钟都可以去掉:
将GPIO接口引出来,sw5就要接在这个上面,最后就是这个样子:
约束:
好了,一切OK。加载到SDK。
在xparameters.h文件里,看看PS部分GPIO的信息:
MIO号0~53,EMIO号从54开始,
读取SW5的电平,将这个电平传给DS12,LED随按键亮灭(按下是1,松开是0):
各个函数的信息可以按住Ctrl,然后把鼠标放上去点击进去看注释
#include
#include "xgpiops.h"
#include "xparameters.h"
int main()
{
XGpioPs_Config *GPIO_Config;//GPIO的配置信息
XGpioPs my_Gpio; // GPIO实例
int Status;
printf("hello ! MIO and EMIO !\n\r");
GPIO_Config = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
Status = XGpioPs_CfgInitialize(&my_Gpio,GPIO_Config,GPIO_Config->BaseAddr);
XGpioPs_SetDirectionPin(&my_Gpio, 8, 1); //MIO[8]和ds12连在一起,1代表输出
XGpioPs_SetDirectionPin(&my_Gpio, 54, 1);//EMIO[0]和sw5连在一起
XGpioPs_SetOutputEnablePin(&my_Gpio, 8, 1);
while(1)
{
Status = XGpioPs_ReadPin(&my_Gpio, 54); //按下是1,松开是0
XGpioPs_WritePin(&my_Gpio, 8, Status);
}
return 0;
}
这里我们是对具体的Pin操作,所以函数用的是带Pin的。
最终,实验是成功的。成功接出一个EMIO到PS上,此时就把这个GPIO看成是PS的了。