OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5541|回复: 0
打印 上一主题 下一主题

[XILINX] 【正点原子FPGA连载】第三章 GPIO之EMIO按键控制LED实验--摘自【正点原子】领航者ZYNQ之嵌入式开发指南_V1.2

[复制链接]

1153

主题

1165

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4971
金钱
4971
注册时间
2019-5-8
在线时间
1259 小时
跳转到指定楼层
楼主
发表于 2020-8-31 17:49:56 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 正点原子01 于 2020-8-31 17:49 编辑

1)实验平台:正点原子领航者ZYNQ开发板
2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-301505-1-1.html
4)本章实例源码下载: GPIO之EMIO按键控制LED实验.zip (10.33 MB, 下载次数: 18)
5)对正点原子FPGA感兴趣的同学可以加群讨论:905624739 点击加入群聊
6)关注正点原子公众号,获取最新资料更新






第三章 GPIOEMIO按键控制LED实验

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


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


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


图 4.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,如下图所示:

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

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

图 4.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,如下图所示:

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

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

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

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

图 4.3.9 Make External
可以看到ZYNQ7 ProcessingSystem引出了一个名为GPIO_0_0的接口,如下图所示:

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

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

图 4.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”。如下图所示:

图 4.3.13 打开详细设计
在弹出的对话框中点击“OK”。如下图所示:

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

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

图 4.3.16 管脚分配
4-2设置完成后按快捷Ctrl+S保存管脚约束,在弹出的对话框输入文件名“Navigator”,最后点击“OK”,如下图所示:
图 4.3.17 保存约束
4-3在左侧Flow Navigator导航栏中找到PROGRAM AND DEBUG,点击该选项中的“Generate Bitstream”,然后在连续弹出的对话框中依次点击“YES”、“OK”。此时,Vivado工具开始对设计进行综合、实现、并生成Bitstream文件。
4-4 生成Bitstream完成后,在弹出的对话框中选择“Open ImplementedDesign”,如下图所示:

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

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

图 4.3.20 资源使用总结报告
4-5 导出硬件。
在菜单栏中选择 File> Export > Export hardware。
在弹出的对话框中,勾选“Includebitstream”,然后点击“OK”按钮。如下图所示:

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

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

图 4.4.2 之前实验中的工程文件
上图中箭头所指示的文件夹是我们本次实验所导出的硬件设计文件。而红色方框里的是前一实验的工程文件,我们直接选中,然后按键盘上的Delete键将其删除。在弹出的删除对话框中,勾选“Delete projectcontents on disk”,然后点击“OK”按钮。
step5:在SDK中创建应用工程
5-1在菜单栏中选择File > New > Application Project, 新建一个SDK应用工程。
4.4.3 创建应用工程
5-2 在弹出的图2.4.4所示界面中,输入工程名“gpio_emio”。
在该页面中,我们需要确认HardwarePlatform一栏中选择的是本次实验新导出的硬件平台system_wrapper_hw_platform_0。如果我们没有删除前一实验的工程文件,那么此处就要选择图 3.4.2中箭头所指示的硬件平台system_wrapper_hw_platform_1。另外,在BoardSupport 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,如下图所示:

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

图 4.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. #define GPIOPS_ID XPAR_XGPIOPS_0_DEVICE_ID   //PS端 GPIO器件 ID

  5. #define MIO_LED0 7   //PS_LED0连接到 MIO7
  6. #define MIO_LED1 8   //PS_LED1连接到 MIO8
  7. #define MIO_LED2 0   //PS_LED2连接到 MIO0

  8. #define MIO_KEY0 12  //PS_KEY0 连接到 MIO7
  9. #define MIO_KEY1 11  //PS_KEY1 连接到 MIO8

  10. #define EMIO_KEY 54  //PL_KEY0 连接到EMIO0

  11. int main()
  12. {
  13.      printf("EMIOTEST!\n");

  14.      XGpioPs gpiops_inst;            //PS端 GPIO 驱动实例
  15.      XGpioPs_Config *gpiops_cfg_ptr; //PS端 GPIO 配置信息

  16.      //根据器件ID查找配置信息
  17.      gpiops_cfg_ptr = XGpioPs_LookupConfig(GPIOPS_ID);
  18.      //初始化器件驱动
  19.      XGpioPs_CfgInitialize(&gpiops_inst, gpiops_cfg_ptr, gpiops_cfg_ptr->BaseAddr);

  20.      //设置LED为输出
  21.      XGpioPs_SetDirectionPin(&gpiops_inst, MIO_LED0,1);
  22.      XGpioPs_SetDirectionPin(&gpiops_inst, MIO_LED1,1);
  23.      XGpioPs_SetDirectionPin(&gpiops_inst, MIO_LED2,1);
  24.      //使能LED输出
  25.      XGpioPs_SetOutputEnablePin(&gpiops_inst, MIO_LED0,1);
  26.      XGpioPs_SetOutputEnablePin(&gpiops_inst, MIO_LED1,1);
  27.      XGpioPs_SetOutputEnablePin(&gpiops_inst, MIO_LED2,1);

  28.      //设置KEY为输入
  29.      XGpioPs_SetDirectionPin(&gpiops_inst, MIO_KEY0,0);
  30.      XGpioPs_SetDirectionPin(&gpiops_inst, MIO_KEY1,0);
  31.      XGpioPs_SetDirectionPin(&gpiops_inst, EMIO_KEY,0);

  32.      //读取按键状态,用于控制LED亮灭
  33.      while(1){
  34.          XGpioPs_WritePin(&gpiops_inst, MIO_LED0,
  35.                  ~XGpioPs_ReadPin(&gpiops_inst, MIO_KEY0));

  36.          XGpioPs_WritePin(&gpiops_inst, MIO_LED1,
  37.                  ~XGpioPs_ReadPin(&gpiops_inst, MIO_KEY1));

  38.          XGpioPs_WritePin(&gpiops_inst, MIO_LED2,
  39.                  ~XGpioPs_ReadPin(&gpiops_inst, EMIO_KEY));
  40.      }

  41.      return 0;
  42. }
复制代码
在代码的第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”以打开该文件。在文本编辑界面的左侧空白边框处右击,然后选择“ShowLine Numbers”可以显示代码的行号。
在xgpiops.h文件第162行给出了ZYNQ器件GPIO最大的引脚数目,共118个,分别位于4个Bank中。在下面的注释中则分别列出了各Bank的引脚编号范围,同样可以看到Bank2的第一个引脚编号为54。

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

图 4.5.1 查看串口端口
串口的设置如下图所示:

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

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

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

图 4.5.5 下载验证






正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-25 13:12

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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