3_GPIO_EMIO 实验
硬件:PYNQ_Z2开发板
笔记
- 什么是EMIO?
EMIO是PS和PL之间的一个接口。
EMIO是扩展的MIO,当PS的引脚不够用的时候,可以通过EMIO来进行扩展,从而使用PL的引脚。
- 如何使用MIO的输入?
配置成输入
读DATA_RO寄存器
介绍
-
PS和外部设备之间的通信主要是通过复用的I/O实现的(Multiplexed Input/Output,MIO)。此外,PS还可以通过扩展的MIO(Extended MIO,EMIO)来实现与外部设备的连接。
-
ZYNQ GPIO 接口信号被分成四组,分别是从 BANK0 到 BANK3。其中 BANK0 和 BANK1 中共计 54 个信号通过 MIO 连接到 ZYNQ 器件的引脚上,这些引脚属于 PS 端;而 BANK2 和 BANK3 中共计 64 个信 号则通过 EMIO 连接到了 ZYNQ 器件的 PL 端。
- 在大多数情况下,PS 端经由 EMIO 引出的接口会直接连接到 PL 端的器件引脚上,通过 IO 管脚约束来 指定所连接 PL 引脚的位置。通过这种方式,EMIO 可以为 PS 端实现额外的 64 个输入引脚或 64 个带有输 出使能的输出引脚。EMIO 还有一种使用方式,就是用于连接 PL 内实现的功能模块(IP 核),此时 PL 端 的 IP 作为 PS 端的一个外部设备。
硬件连接(PYNQ_Z2)
PYNQ-Z2板包括2个三色led, 2个dip开关,4个按钮和4个连接到PL的独立led。
具体分布如下所示:
- 按键
当按下时,四个按钮在相应的PL引脚上产生逻辑高电平。
- LEDs
四个单独的LED通过330Ω电阻阳极连接到Zynq PL。高电平点亮LED。
实验过程
- 在Block Design 中,勾选EMIO GPIO,设置位宽为3(扩展3个PL引脚)。该设置将通过 EMIO 扩展一个 3位的 GPIO 接口信号,此信号将用于连接 PL 端的引脚。
- 我们通过EMIO扩展了一个GPIO的接口信号,需要将其分配到PL的D19引脚上(该引脚与BTN0相连接)。 另外,D19位于PYNQ芯片的BANK35内,该 BANK 的供电电压为 3.3V,因此 I/O Std 一列对应的电平也需要修改。
- 定义PL端口,PS可以直接操作的管教是54个,MIO0-MIO53;所以EMIO的扩展引脚编号就是54往后排序从GPIO0_tri_io 0 依次往后进行编号。(定义I/O Ports 与编写约束文件等同)
- 最后记得综合项目:Generate Bitstream. 我们的设计使用了 PL 的资源,比如使用了 PL 的引脚,或者在 PL 内实现了部分功能模块,那么我们就需要生成 Bitstream 文件,并在导出硬件的时候包含该文件。
代码
#include "stdio.h"
#include "xparameters.h"
#include "xgpiops.h"
#include "sleep.h"
//实现功能:按下BTN0,LED0亮 / 松开BTN0,LED0灭
//BTN1没有用到
#define GPIOPS_ID XPAR_XGPIOPS_0_DEVICE_ID //PS 端 GPIO 器件 ID
//PS可以直接操作的管教是54个,MIO0-MIO53;所以EMIO的扩展引脚编号就是54往后排序从GPIO0_tri_io 0 依次往后进行编号
#define BTN0 54
#define BTN1 55
#define LED0 56
XGpioPs_Config * gpiops_cfg_ptr;
XGpioPs gpiops_inst; /* The driver instance for GPIO Device. */
int main()
{
printf(" 123!\n\r");
//根据器件的ID,查找器件的配置信息
gpiops_cfg_ptr = XGpioPs_LookupConfig(GPIOPS_ID);
//初始化GPIO驱动
XGpioPs_CfgInitialize(&gpiops_inst, gpiops_cfg_ptr, gpiops_cfg_ptr->BaseAddr);
//设置LED为输出 ;把GPIO的方向设置为输出 (0:输入/ 1:输出)
XGpioPs_SetDirectionPin(&gpiops_inst, LED0, 1);
//设置LED输出使能(0:关闭/ 1:打开)
XGpioPs_SetOutputEnablePin(&gpiops_inst, LED0, 1);
//设置BTN为输入 ;把GPIO的方向设置为输入 (0:输入/ 1:输出)
XGpioPs_SetDirectionPin(&gpiops_inst, BTN0, 0);
XGpioPs_SetDirectionPin(&gpiops_inst, BTN1, 0);
XGpioPs_SetOutputEnablePin(&gpiops_inst, BTN0, 0);
XGpioPs_SetOutputEnablePin(&gpiops_inst, BTN1, 0);
printf("GPIO EMIO TEST!\n\r");
//读取按键状态,控制LED
while(1)
{
//写数据到GPIO的输出引脚(1点亮),这里参数为按键的返回值
XGpioPs_WritePin(&gpiops_inst , LED0, XGpioPs_ReadPin(&gpiops_inst, BTN0));
}
return 0;
}
注:
在原理图中找引脚编号时,PS端口的引脚可以很清楚地写MIOxx,但PL端的引脚却没有指明MIO。这是因为PL端的MIO需要我们自己定义,PS可以直接操作的管教是54个,MIO0-MIO53;所以EMIO的扩展引脚编号就是54往后排序。
在I/O Ports中,选择端口连接的引脚,和电压;该操作和FPGA中编写管脚约束文件效果相同。
如下面两个图
只需要完成一个,另一个就会自动生成。上图中,D19为MIO54,D20为MIO55,R14为MIO56.