发 帖  
原厂入驻New
[资料] 【正点原子FPGA连载】第三章EMIO按键控制LED实验-领航者 ZYNQ 之嵌入式开发指南
2020-8-29 16:20:36  135 正点原子FPGA
分享
1)实验平台:正点原子领航者ZYNQ开发板
2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/FPGA/zdyz_linhanz.html
4)对正点原子FPGA感兴趣的同学可以加群讨论:876744900
5)关注正点原子公众号,获取最新资料



第三章GPIO之EMIO按键控制LED实验

PS和外部设备之间的通信主要是通过复用的输入/输出(Multiplexed Input/Output,MIO)实现的。除此之外,PS还可以通过扩展的MIO(Extended MIO,EMIO)来实现与外部设备的连接。EMIO使用了PL的I/O资源,当PS需要扩展超过54个引脚的时候可以用EMIO,也可以用它来连接PL中实现的IP模块。
本章我们将学习GPIO中EMIO接口信号的使用。本章包括以下几个部分:
33.1简介
3.2实验任务
3.3硬件设计
3.4软件设计
3.5下载验证
3.1简介
ZYNQ GPIO接口信号被分成四组,分别是从BANK0到BANK3。其中BANK0和BANK1中共计54个信号通过MIO连接到ZYNQ器件的引脚上,这些引脚属于PS端;而BANK2和BANK3中共计64个信号则通过EMIO连接到了ZYNQ器件的PL端。如下图所示:



图 3.1.1 GPIO框图

在大多数情况下,PS端经由EMIO引出的接口会直接连接到PL端的器件引脚上,通过IO管脚约束来指定所连接PL引脚的位置。通过这种方式,EMIO可以为PS端实现额外的64个输入引脚或64个带有输出使能的输出引脚。EMIO还有一种使用方式,就是用于连接PL内实现的功能模块(IP核),此时PL端的IP作为PS端的一个外部设备。如图 3.1.2所示:



图 3.1.2 EMIO接口的使用方式

3.2实验任务
本章的实验任务是使用领航者ZYNQ底板上的三个用户按键分别控制PS端三个LED的亮灭。其中一个按键PL_KEY0连接到了PL端,需要通过EMIO进行扩展。
3.3硬件设计
根据实验任务我们可以画出本次实验的系统框图,如下图所示:



图 3.3.1 系统框图

与《GPIO之MIO控制LED实验》中的系统框图相比,图 5.3.1中的PS端多了EMIO模块。除此之外,因为EMIO使用了PL端的IO资源,所以图中增加了PL部分。PL端与按键PL_KEY0相连的引脚直接通过EMIO连接到PS端。
step1:创建Vivado工程
本次实验可以在前一个实验的基础上进行。
1-1 我们打开《GPIO之MIO控制LED实验》中的Vivado工程“gpio_mio”,打开后在菜单栏中选择File > Project > Save As,如下图所示:



图 3.3.2 选择另存为

1-2 在弹出的对话框中输入新的工程名,在Project name一栏输入工程名“gpio_emio”,工程位置保持默认即可,如下图所示:



图 3.3.3 工程另存为

点击“OK”按钮,原先的Vivado工程会关闭,并打开一个新的工程“gpio_emio”。
此时如果我们打开工程所在的路径,即F:\ZYNQ\Embedded_System\gpio_emio,可以看到如下图所示的文件目录:



图 3.3.4 gpio_emio工程目录

此时我们就在gpio_mio工程的基础上得到了一个新的工程gpio_emio,这样就省去了重新搭建硬件的过程。由于我们不需要原工程中的软件工程,因此将图 3.3.4中红色方框所指示的“gpio_emio.sdk”文件夹删除。
接下来我们将在《GPIO之MIO控制LED实验》中硬件设计的基础上搭建本次实验的硬件平台。
step2:使用IP Integrator创建Processing System
2-1在Flow Navigator中,点击IP INTEGRATOR下的Open Block Design,如下图所示:



图 3.3.5 打开Block Design

2-2 在Diagram窗口中,双击打开ZYNQ7 Processing System重定义窗口。



图 3.3.6 重定义ZYNQ7 Processing System

2-3 在下图所示的配置界面中,点击左侧的MIO Configuration。然后在右侧展开GPIO一栏,勾选EMIO GPIO,并设置位宽为1。该设置将通过EMIO扩展一个1位的GPIO接口信号,此信号将用于连接PL端的引脚。



图 3.3.7 勾选EMIO GPIO

完成配置后,点击右下角的“OK”按钮。然后在Diagram窗口中可以看到ZYNQ7 Processing System多了一个GPIO_0端口,如下图所示:



图 3.3.8 通过EMIO引出的GPIO接口

将光标移动到上图中箭头所指示的位置,会发现光标变成了铅笔的样式。点击选中该端口,然后点击鼠标右键,在弹出的列表中选择“Make External”。如下图所示:



图 3.3.9 Make External

可以看到ZYNQ7 Processing System引出了一个名为GPIO_0_0的接口,如下图所示:



图 3.3.10 引出的GPIO接口

点击选中该接口,在左侧External InteRFace Properties一栏中将该接口的名称修改为GPIO_EMIO_KEY。如下图所示:



图 3.3.11 修改接口名称

2-4 本次实验不需要添加其它的IP,按Ctrl+S快捷键保存设计。
step3:生成顶层HDL
3-1 在Sources窗口中展开Design Sources,然后右键点击sysetm_wrapper下的system.bd,在弹出的菜单中选择Generate Output Products,如下图所示:



图 3.3.12 选择Generate Output Products...

3-2 在弹出的对话框中选择“Generate”,然后等待Generate完成后点击“OK”。
3-3 创建顶层HDL Wrapper
在之前的实验中,我们创建顶层模块时选择了“Let Vivado manage wrapper and auto-update”选项,所以此处无需再创建顶层HDL Wrapper,Vivado会自动更新顶层HDL Wrapper。
step4:生成Bitstream文件并导出到SDK
4-1在左侧Flow Navigator导航栏中找到RTL ANALYSIS,点击该选项中的“Open Elaborated Design”。如下图所示:



图 3.3.13 打开详细设计

在弹出的对话框中点击“OK”。如下图所示:



图 3.3.14 Elaborate Design 对话框

在ELABORATED DESIGN界面下方找到I/O Ports窗口。如果没有找到I/O Ports一栏则通过在菜单栏中点击Layout,然后在下拉列表中选择I/O Planning。我们将在I/O Ports窗口中对PL部分的接口进行管脚分配。



图 3.3.15 I/O ports 窗口

在上图中,DDR_12642和FIXED_IO_12642里面是PS端的输入/输出接口,这部分接口不需要我们手动进行管脚分配。在图 3.3.12中选择“Generate Output Products”之后,Vivado工具会自动创建PS端的管脚约束文件。
在本次实验中,我们通过EMIO扩展了一个GPIO的接口信号,即上图中的GPIO_EMIO_KEY。我们需要将其分配到PL的L20引脚上,从原理图上可以看到,该引脚最终与领航者ZYNQ底板上的按键PL_KEY0相连接。另外L20位于ZYNQ7020芯片的BANK35内,该BANK的供电电压为3.3V,因此I/O Std一列对应的电平也需要修改。如下图所示:



图 3.3.16 管脚分配

4-2设置完成后按快捷Ctrl+S保存管脚约束,在弹出的对话框输入文件名“Navigator”,最后点击“OK”,如下图所示:



图 3.3.17 保存约束

4-3在左侧Flow Navigator导航栏中找到PROGRAM AND debug,点击该选项中的“Generate Bitstream”,然后在连续弹出的对话框中依次点击“YES”、“OK”。此时,Vivado工具开始对设计进行综合、实现、并生成Bitstream文件。
4-4 生成Bitstream完成后,在弹出的对话框中选择“Open Implemented Design”,如下图所示:



图 3.3.18 打开实现后的设计

点击“OK”,会弹出对话框提示关闭Elaborated Design,点击“YES”。
在IMPLEMENTED DESIGN界面我们可以查看设计对PL资源的使用情况。在左侧Flow Navigator导航栏中找到IMPLEMENTATION,点击该选项中的“Report Utilization”,然后在弹出的对话框中点击“OK”。如下图所示:



图 3.3.19 报告资源使用情况

在界面下方的Utilization标签页中,选择左侧的Summary,然后在右侧会以表格和柱状图两种方式显示当前PL资源的使用情况。在我们本次实验中,只消耗了PL端1个LUT和一个IO资源,这个IO就是PS通过EMIO扩展GPIO接口信号时所使用的PL引脚。如下图所示:



图 3.3.20 资源使用总结报告

4-5 导出硬件。
在菜单栏中选择 File > Export > Export hardware。
在弹出的对话框中,勾选“Include bitstream”,然后点击“OK”按钮。如下图所示:



图 3.3.21勾选“Include bitstream”

在此处需要注意,如果我们的设计使用了PL的资源,比如使用了PL的引脚,或者在PL内实现了部分功能模块,那么我们就需要生成Bitstream文件,并在导出硬件的时候包含该文件。
4-2 硬件导出完成后,在菜单栏选择File > Launch SDK,启动SDK开发环境。在弹出的对话框中,直接点击“OK”。
到这里我们的硬件设计部分已经结束,接下来的软件设计部分需要在SDK软件中进行。
3.4软件设计
在硬件设计的最后,我们打开了SDK开发环境,如下图所示:



图 3.4.1 SDK开发环境界面

图 3.4.1中红色方框所指示的文件夹是我们本次实验所导出的硬件设计文件。
需要注意的是,本次实验是在gpio_mio实验工程的基础上进行的,但是我们不需要之前工程中的SDK应用程序。因此在图 3.3.4所示的步骤中,我们要将工程文件夹中后缀为.sdk的文件夹删除,否则在上图中将会保留前一实验中的软件工程文件。如下图所示:



图 3.4.2 之前实验中的工程文件

上图中箭头所指示的文件夹是我们本次实验所导出的硬件设计文件。而红色方框里的是前一实验的工程文件,我们直接选中,然后按键盘上的Delete键将其删除。在弹出的删除对话框中,勾选“Delete project contents on disk”,然后点击“OK”按钮。
step5:在SDK中创建应用工程
5-1在菜单栏中选择File > New > Application Project, 新建一个SDK应用工程。



图 3.4.3 创建应用工程

5-2 在弹出的图 2.4.4所示界面中,输入工程名“gpio_emio”。
在该页面中,我们需要确认Hardware Platform一栏中选择的是本次实验新导出的硬件平台system_wrapper_hw_platform_0。如果我们没有删除前一实验的工程文件,那么此处就要选择图 3.4.2中箭头所指示的硬件平台system_wrapper_hw_platform_1。另外,在Board Support Package一栏选择“Create New”,其他选项保持默认。
5-3 在图 2.4.4中点击“Next”,然后选择工程模版Empty Application,然后点击“Finish”。
5-4 可以看到在左侧Project Explorer中创建了一个gpio_emio工程目录和gpio_emio_bsp工程目录。
5-5 新建源文件。在gpio_emio/src目录上右键点击,选择New > Source File,如下图所示:



图 3.4.4 新建源文件

在弹出的对话框中Source file一栏输入文件名“main.c”,然后点击“Finish”。



图 3.4.5 新建源文件

5-10 新建源文件之后,在左侧gpio_emio/src目录下可以看到main.c文件,同时在SDK主页面已经打开了该文件的文本编辑框。我们在新建的main.c文件中输入以下代码:

  • 1 #include "stdio.h"
  • 2 #include "xparameters.h"
  • 3 #include "xgpiops.h"
  • 4
  • 5 #define GPIOPS_ID XPAR_XGPIOPS_0_DEVICE_ID //PS端 GPIO器件 ID
  • 6
  • 7 #define MIO_LED0 7 //PS_LED0 连接到 MIO7
  • 8 #define MIO_LED1 8 //PS_LED1 连接到 MIO8
  • 9 #define MIO_LED2 0 //PS_LED2 连接到 MIO0
  • 10
  • 11 #define MIO_KEY0 12 //PS_KEY0 连接到 MIO7
  • 12 #define MIO_KEY1 11 //PS_KEY1 连接到 MIO8
  • 13
  • 14 #define EMIO_KEY 54 //PL_KEY0 连接到EMIO0
  • 15
  • 16 int main()
  • 17 {
  • 18 printf("EMIO TEST!\n");
  • 19
  • 20 XGpioPs gpiops_inst; //PS端 GPIO 驱动实例
  • 21 XGpioPs_Config *gpiops_cfg_ptr; //PS端 GPIO 配置信息
  • 22
  • 23 //根据器件ID查找配置信息
  • 24 gpiops_cfg_ptr = XGpioPs_LookupConfig(GPIOPS_ID);
  • 25 //初始化器件驱动
  • 26 XGpioPs_CfgInitialize(&gpiops_inst, gpiops_cfg_ptr, gpiops_cfg_ptr->BaseAddr);
  • 27
  • 28 //设置LED为输出
  • 29 XGpioPs_SetDirectionPin(&gpiops_inst, MIO_LED0, 1);
  • 30 XGpioPs_SetDirectionPin(&gpiops_inst, MIO_LED1, 1);
  • 31 XGpioPs_SetDirectionPin(&gpiops_inst, MIO_LED2, 1);
  • 32 //使能LED输出
  • 33 XGpioPs_SetOutputEnablePin(&gpiops_inst, MIO_LED0, 1);
  • 34 XGpioPs_SetOutputEnablePin(&gpiops_inst, MIO_LED1, 1);
  • 35 XGpioPs_SetOutputEnablePin(&gpiops_inst, MIO_LED2, 1);
  • 36
  • 37 //设置KEY为输入
  • 38 XGpioPs_SetDirectionPin(&gpiops_inst, MIO_KEY0, 0);
  • 39 XGpioPs_SetDirectionPin(&gpiops_inst, MIO_KEY1, 0);
  • 40 XGpioPs_SetDirectionPin(&gpiops_inst, EMIO_KEY, 0);
  • 41
  • 42 //读取按键状态,用于控制LED亮灭
  • 43 while(1){
  • 44 XGpioPs_WritePin(&gpiops_inst, MIO_LED0,
  • 45 ~XGpioPs_ReadPin(&gpiops_inst, MIO_KEY0));
  • 46
  • 47 XGpioPs_WritePin(&gpiops_inst, MIO_LED1,
  • 48 ~XGpioPs_ReadPin(&gpiops_inst, MIO_KEY1));
  • 49
  • 50 XGpioPs_WritePin(&gpiops_inst, MIO_LED2,
  • 51 ~XGpioPs_ReadPin(&gpiops_inst, EMIO_KEY));
  • 52 }
  • 53
  • 54 return 0;
  • 55 }
复制代码

在代码的第7至12行,我们指定了PS端的按键和LED所连接的MIO引脚编号,这些编号可以从领航者ZYNQ核心板和底板的原理图中查到。而在代码的第14行则指定了PL端的按键PL_KEY0连接到了GPIO的第54号引脚,那么这个54是怎么来的呢?
在本章的简介部分我们提到过,ZYNQ的GPIO被分成了4组,其中通过EMIO扩展的GPIO接口位于BANK2和BANK3中,如图 3.1.1所示。在本次实验中我们通过EMIO扩展了1个GPIO信号,即BANK2的EMIO0。由于GPIO的BANK0和BANK1分别有32和22个信号,所以BANK2的EMIO0编号为54(从0开始编号)。
我们按住Ctrl键,然后点击代码开头处所引用的头文件“xgpiops.h”以打开该文件。在文本编辑界面的左侧空白边框处右击,然后选择“Show Line Numbers”可以显示代码的行号。
在xgpiops.h文件第162行给出了ZYNQ器件GPIO最大的引脚数目,共118个,分别位于4个Bank中。在下面的注释中则分别列出了各Bank的引脚编号范围,同样可以看到Bank2的第一个引脚编号为54。



图 3.4.6 GPIO引脚编号

在程序的第42至52行,我们在一个死循环中不断读取各按键的状态,然后将读到的值取反后分别写入对应的LED中,从而实现按键控制LED的功能。从上面的程序中大家也可以看出,通过EMIO扩展的GPIO接口的使用方法和MIO没有任何区别。如果大家对GPIO的使用不熟悉的话,请参考《GPIO之MIO控制LED实验》。
5-6 我们按快捷键Ctrl+S保存main.c文件,工具会自动进行编译,编译过程可以在SDK下方的控制台(Console)中看到。编译完成后Console中会出现提示信息“Build Finished”,同时在gpio_emio的Binaries目录下可以看到生成的elf文件。如下图所示:



图 3.4.7 编译后生成的elf文件

3.5下载验证
首先我们将下载器与领航者底板上的JTAG接口连接,下载器另外一端与电脑连接。然后使用Mini USB连接线将开发板左侧的USB_UART接口与电脑连接,用于串口通信。最后连接开发板的电源,并打开电源开关
step6:板级验证
6-1在SDK软件下方的SDK Terminal窗口中点击右上角的加号连接串口,并在弹出的窗口中对串口进行设置。
需要注意的是,在设置端口(Port)时,在下拉列表中可能会看到多个可选端口。我们需要选择与领航者底板上的串口所连接的端口,具体的端口号可在计算机设备管理器中查看。因为底板上使用的USB转串口芯片型号为CH340,因此在设备管理器中找到USB-SERIAL CH340所对应的端口,在我这台电脑上该端口号为COM12。如下图所示:



图 3.5.1 查看串口端口

串口的设置如下图所示:



图 3.5.2 设置UART串口

6-2 下载程序。因为本次实验使用了PL内的资源,因此我们在下载软件编译生成的elf文件之前,需要先下载硬件设计过程中生成的bitstream文件,对PL部分进行配置。
在菜单栏中点击“xilinx”,然后选择“Program FPGA”。在弹出的对话框中Bitstream一栏,确认已经加载了本次实验硬件设计过程中所生成的BIT文件——“system_wrapper.bit”。最后点击右下角的“Program”,如下图所示:



图 3.5.3 配置PL

配置PL完成后,接下来我们要下载软件程序。在应用工程gpio_emio上右击,选择“Run As”,然后选择第一项“1 Launch on Hardware (System Debugger)”。
软件程序下载完成后,在下方的SDK Terminal中可以看到应用程序打印的信息“EMIO TEST!”,如下图所示:



图 3.5.4 串口终端中打印的信息

我们分别按下领航者底板上的两个PS端的用户按键PS_KEY0和PS_KEY1,可以看到底板上对应的两个PS端的LED灯在按键按下时点亮,释放后熄灭。
然后再按下底板上PL端的用户按键PL_KEY0,可以看到核心板上PS端的LED2(红色)在按键按下时点亮,释放后熄灭。说明我们通过EMIO扩展GPIO接口,使用PL端按键控制PS端LED的实验在领航者ZYNQ开发板上面下载验证成功。实验结果如下图所示:



图 3.5.5 下载验证


1
分享淘帖 显示全部楼层

评论

高级模式
您需要登录后才可以回帖 登录 | 注册

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
发资料
关闭

站长推荐 上一条 /7 下一条

快速回复 返回顶部 返回列表