本帖最后由 正点原子运营官 于 2021-1-11 15:13 编辑
1)实验平台:正点原子达芬奇FPGA开发板
2)购买链接:https://detail.tmall.com/item.htm?id=624335496505
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/fpga/zdyz_dafenqi.html
4) 正点原子官方B站:https://space.bilibili.com/394620890
5)对正点原子FPGA感兴趣的同学可以加群讨论:905624739
6)关注正点原子公众号,获取最新资料
在嵌入式系统中,经常需要控制许多结构简单的外部设备或者电路,这些设备有的需要通过CPU控制,有的需要CPU提供输入信号。嵌入式微处理器通常用GPIO控制这些设备,本次实验我们将通过AXI GPIO进行LED流水灯实验。
33.1 简介
3.2实验任务
3.3硬件设计
3.4程序设计
3.5下载验证
3.1简介
AXI GPIO IP核为AXI接口提供了一个通用的输入/输出接口。AXI GPIO是一个软核(Soft IP),是由用户通过配置芯片的逻辑资源来实现的一个功能模块。
AXI GPIO可以配置成单通道或者双通道,每个通道的位宽可以单独设置。另外通过打开或者关闭三态缓冲器,AXI GPIO的端口还可以被动态地配置成输入或者输出接口。其顶层模块的框图如下所示:
图 3.1.1 AXI GPIO框图
从图 3.1.1可以看到,模块的左侧实现了一个32位的AXI4-Lite从接口,用于主机访问AXI GPIO内部各通道的寄存器。当右侧接口输入的信号发生变化时,模块还能向主机产生中断信号。不过只有在配置IP核时选择“使能中断”,才会启用模块的中断控制功能。
3.2实验任务
本章的实验任务是通过调用AXI GPIO IP核,实现LED流水灯功能,并进行程序固化,实现程序上电自启动。
3.3硬件设计
根据实验任务我们可以画出实验系统框图:
图 3.3.1 系统框图
由系统框图可以看出,AXI GPIO和AXI UART都通过AXI Interconnect模块与MicroBlaze互联,Microblaze处理器输出LED灯的控制信号,通过AXI Interconnect互联模块传输到AXI GPIO模块,AXI GPIO模块根据AXI4-Lite协议将LED灯控制信号解析出来,输出到FPGA的LED引脚,从而控制LED灯。
step1:创建Vivado工程
本次实验硬件设计可以在《Hello World》实验的基础上进行,这里我们就没有必要重新创建工程了,此处顺便可以介绍下如何在先前工程的基础上继续实验而不破坏先前的工程。
我们先打开《Hello World》实验的Vivado工程,打开后依次点击菜单栏的“File->Project->Save As...”,如图 3.3.2所示:
图 3.3.2 选择另存为
在弹出的另存为界面中可以输入新的工程名或更改保存位置,此处我们输入新的工程名“axi_gpio_led”,工程位置可以选择,保持默认即可,然后点击“OK”按钮。如图 3.3.3所示:
图 3.3.3 另存为工程为axi_gpio_led
之后,如果我们打开工程所在目录G:/vitis_pro/axi_gpio_led,就会看到如下的目录结构:
图 3.3.4 axi_gpio_led工程目录
至此,在原工程的基础上成功创建了一个新的工程而没有破坏原来的工程,也避免了重新创建工程或复制工程后修改的麻烦。
step2:使用IP Integrator创建Processing System
在Flow Navigator中,点击IP INTEGRATOR下的“Open Block Design”,如图 3.3.5所示:
图 3.3.5 打开Block Design
因为本次实验我们是要通过GPIO控制LED流水灯,因此我们需要添加AXI GPIO IP核。点击Diagram界面的“+”按钮,并在弹出的搜索框内输入“gpio”,双击AXI GPIO选项,如图 3.3.6所示:
图 3.3.6 添加AXI GPIO
双击AXI GPIO IP核进入配置页面,将AXI GPIO位宽配置为4,用于控制开发板上的四个LED灯,点击“OK”完成配置,如图 3.3.7所示:
图 3.3.7 AXI GPIO配置
All Inputs:将GPIO通道位设置为输入模式。All Outputs:将GPIO通道位设置为输出模式。这两项默认情况下是不勾选的,可由程序动态地将GPIO通道位配置成输入或者输出接口。
Default Outputs Value:设置GPIO通道所有启用位的默认值:默认情况下值为0x0。
Default Tri State Value:设置GPIO通道位默认情况下的输入模式或输出模式:值为0xFFFFFFFF时,表明GPIO所有通道位默认情况下为输入模式,如箭头1所指示。
另外勾选箭头2所指示的选项可以使能GPIO通道2。该通道独立可以配置位宽,GPIO2的配置方法与GPIO完全相同。如使用了该通道,AXI GPIO IP核就会生成一个GPIO2接口,可以连接独立的外设。该选项默认没有勾选,即该IP工作在单通道模式下。
图 3.3.8 连接AXI GPIO
自动连线:点击图 3.3.8红色箭头1所示按钮“Run Connection Automation”,在弹出的界面在左侧勾选“All Automation”,点击“OK”工具会自动连接AXI GPIO IP核的GPIO接口和S_AXI接口。
连接完成后,在Diagram窗口空白处右击,然后选择“Regenerate Layout”对设计进行重新布局,并将“gpio_rtl_0”接口改为“LED”,最终的界面如图 3.3.9所示:
图 3.3.9 重新布局后的设计界面
到这里我们的Block Design就设计完成了,在Diagram窗口空白处右击,然后选择“Validate Design”验证设计。验证完成后弹出对话框提示“Validation Successful”表明设计无误,点击“OK”确认。最后按快捷键“Ctrl + S”保存设计。
接下来在Source窗口中右键点击Block Design设计文件“system.bd”,然后依次执行“Generate Output Products”和“Create HDL Wrapper”。
接下来我们双击Source窗口下的“system_wrapper.xdc”文件夹,添加管脚约束文件,如图 3.3.10所示。
图 3.3.10 添加约束文件
添加管脚约束语句如下(可复制),然后“Ctrl+s”保存。(约束文件最后5行,本实验不要也可以,这些语句是用来压缩bit流文件和设置SPI位宽、时钟的约束语句,防止因文件过大而无法固化Flash。用户可根据需求自行决定是否需要这些语句)
- set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS33} [get_ports sys_clk]
- set_property -dict {PACKAGE_PIN U2 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]
- set_property -dict {PACKAGE_PIN U5 IOSTANDARD LVCMOS33} [get_ports UART_rxd]
- set_property -dict {PACKAGE_PIN T6 IOSTANDARD LVCMOS33} [get_ports UART_txd]
- set_property -dict {PACKAGE_PIN R2 IOSTANDARD LVCMOS33} [get_ports {LED_tri_io[0]}]
- set_property -dict {PACKAGE_PIN R3 IOSTANDARD LVCMOS33} [get_ports {LED_tri_io[1]}]
- set_property -dict {PACKAGE_PIN V2 IOSTANDARD LVCMOS33} [get_ports {LED_tri_io[2]}]
- set_property -dict {PACKAGE_PIN Y2 IOSTANDARD LVCMOS33} [get_ports {LED_tri_io[3]}]
- set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
- set_property CONFIG_VOLTAGE 3.3 [current_design]
- set_property CFGBVS VCCO [current_design]
- set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
- set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]
复制代码
最后在左侧Flow Navigator导航栏中找到PROGRAM AND DEBUG,点击该选项中的“Generate Bitstream”,对设计进行综合、实现、并生成Bitstream文件。
在生成Bitstream之后,在菜单栏中依次点击“File->Export->Export Hardware…”导出硬件,并在弹出的对话框中,勾选“Include bitstream”,在导出路径下加入“/vitis”,直接点击“OK”按钮。如图 3.3.11所示:
图 3.3.11 勾选Include bitstream
然后启动软件设计环境Vitis,在菜单栏依次点击“Tools->Launch Vitis”,在弹出的界面点击“Browse…”,选择上一步生成的vitis文件夹作为此后软件设计的工作空间,不勾选“Use this as the default and do not ask agian”,点击”Launch”,即启动软件设计环境Vitis。如图 3.3.12所示:
图 3.3.12 选择软件设计的工作空间
3.4软件设计
在硬件设计的最后,我们打开了Vitis开发环境,在菜单栏依次点击“File->New->Application Project”,新建一个Vitis应用工程。在弹出的对话框中,输入工程名“axi_gpio_led”,其他默认,点击“Next”。如下图所示:
图 3.4.1 创建工程
点击“Create a new platform hardware(XSA)”,软件提供了一些板卡的硬件平台以供选择,但对于我们自己的硬件平台需要手动添加,点击“+”,选择vitis文件夹下的“system_wrapper.xsa”,如图 3.4.2,即可成功添加我们自己的硬件平台,如图 3.4.3所示,点击“Next”。
图 3.4.2 添加硬件平台
图 3.4.3 新加硬件平台
CPU默认选择“microblaze_0”;OS 选择“standalone”;语言选择“C”;点击“Next”,如图 3.4.4所示:
图 3.4.4 硬件平台设置
选择工程模版“Empty Application”,本章将自行创建工程文件,故选择空模板,然后点击“Finish”按钮,如图 3.4.5所示:
图 3.4.5 选择工程模版Empty Application
双击硬件平台目录下的platform.spr文件,找到点击板级支持包“Board_Support_Package”,点击展开“Peripheral Drivers”,右侧有相关文档和示例。如图 3.4.6所示:
图 3.4.6 板级支持包
点击“Documentation”会在浏览器窗口打开GPIO_API文档,会展示关于GPIO的详细信息,想了解GPIO的,可以仔细浏览其中的信息。如图 3.4.7所示:
图 3.4.7 AXI GPIO的API文档
点击“Import Examples”,会弹出下图所示的导入示例界面,关于GPIO有四个示例。如图 3.4.8所示:
图 3.4.8 导入示例
这四个示例的介绍可以在刚才打开的API文档中看到。在API文档中点击左侧的“Examples”,右侧出现这四个示例的介绍信息,如图 3.4.9所示:
图 3.4.9 示例的介绍信息
从上面的介绍中,我们因为本实验是通过GPIO控制LED,所以我们选择xgpio_example示例。勾选图 3.4.8中示例后,点击“OK”按钮。
在Project Explorer中,新增了示例system_bsp _example_1目录,我们打开其src目录下的xgpio_example.c文件。如图 3.4.10所示:
图 3.4.10 打开xgpio_example.c文件
“xgpio_example.c”包含三个函数:“xparameters.h”、“xgpio.h”和“xil_printf.h”,按下Ctrl键的同时鼠标点击相应的函数即可进入函数中查看信息。“xparameters.h”定义了一些默认的参数,“xil_printf.h”是打印函数用来控制打印信息,“xgpio.h”文件包含Xilinx通用I/O(Xgpio)设备驱动程序的软件API定义。我们本次实验的软件程序部分就可以根据官方示例“xgpio_example.c”进行设计。
接下来先要创建源文件。在axi_gpio_led/src目录上右键,依次点击“New->File”,如图 3.4.11所示:
图 3.4.11新建源文件
在下图所示的弹出的添加源文件界面中,“File name”一栏我们输入文件名“main.c”,然后点击“Finish”按钮。
图 3.4.12源文件名称
我们在新建的main.c文件中输入以下代码:
- 1 #include "xparameters.h"
- 2 #include "xgpio.h"
- 3 #include "xil_printf.h"
- 4 #include "sleep.h"
- 5
- 6 #define LED_ID XPAR_GPIO_0_DEVICE_ID //led器件ID
- 7 #define LED_CHANNEL 1 //LED通道
- 8
- 9 XGpio Gpio; //GPIO实例
- 10
- 11 int main(void){
- 12 int i=0;
- 13
- 14 xil_printf("GPIO LED TESTnr");
- 15 //初始化GPIO
- 16 XGpio_Initialize(&Gpio, LED_ID);
- 17 //为指定的信道设置方向 ,0 输出 ,1输入
- 18 XGpio_SetDataDirection(&Gpio, LED_CHANNEL, 0);
- 19
- 20 while (1) {
- 21 //向指定通道写入数据,LED每0.5秒流转一次
- 22 XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, 0x01 << i);
- 23 //循环计数,表示第几个灯亮
- 24 if(i == 3)
- 25 i = 0;
- 26 else
- 27 i = i + 1;
- 28 //延时0.5秒
- 29 usleep(500000);
- 30 }
- 31 return 0;
- 32 }
复制代码
可以看到我们的程序比官方示例程序多了一个“sleep.h”的头文件,该头文件包含ARM CortexA53、A9、R5、Microblaze处理器特定的延迟API。调用该文件中的相关函数可以实现延迟处理。
代码第6行我们宏定义了LED_ID,使其为XPAR_GPIO_0_DEVICE_ID。如果在Vitis软件中,按住Ctrl键不放,将鼠标移动到XPAR_GPIO_0_DEVICE_ID上,当鼠标变成手指状时,单击鼠标左键,会自动跳转到xparameters.h文件中,该文件定义了各个外设的基地址、器件ID、中断等,我们这里重新宏定义XPAR_GPIO_0_DEVICE_ID是为了以后方便修改。
代码第7行,定义了LED的通道,这里我们指定通道1。
代码第16行是初始化GPIO通道,代码第17行是给指定的GPIO通道设置输入/输出方向,0表示输出,1表示输入。
代码第20到30行,是一个0.5秒的流水灯,代码第22行的“XGpio_DiscreteWrite”是一个向指定GPIO通道写入数据的函数。
代码第29行的usleep函数为微秒延时函数,延时m微秒就使用usleep(m)语句。还有一个秒延时函数sleep(m),延时m秒。
“Ctrl+s”保存main.c文件。选中应用工程axi_gpio_led_system,单击鼠标右键,在弹出的菜单中选择“Build Project”即可编译工程,如图 3.4.13所示:
图 3.4.13编译工程
工程编译结束后,在Binaries下成功生成axi_gpio_led.elf文件。
至此,硬件和软件设计部分均已完成。
注:如果导入的GPIO示例“system_bsp_example_1”不需要,可以将其删除。
3.5下载验证和固化
下载验证
完成了硬件设计和软件设计后,我们就可以进行板级验证了,也就是设计流程的最后一步。在进行板级验证之前,我们先将达芬奇开发板上的JTAG与电脑连接,然后使用USB连接线将USB UART接口与电脑连接,然后连接达芬奇开发板的电源,给开发板上电。
图 3.5.1 达芬奇开发板连接图
打开串口助手或具有串口功能的软件。串口助手是上位机中用于辅助串口调试的小工具,可以选择安装使用开发板随附资料中“6_软件资料/1_软件/串口调试助手/XCOM(ALIENTEK官方推荐)”的文件夹中提供的串口助手,也可从网上下载或选择自己常用的串口调试工具。这里我们使用Vitis软件自带的串口助手,其它串口助手的设置也是一样。
按照第二章图 2.5.4所示,将Vitis的Terminal窗口打开,打开后Terminal如图 3.5.2所示:
图 3.5.2 Vitis软件自带的串口助手
点击下图红框内图标,打开串口。
图 3.5.3 打开串口
按照下图对串口进行设置,选择串口“Serial Terminal”,COM口依据自己的电脑设置,设置的参数需要与硬件设计过程中配置的axi_uartlite_0保持一致,即波特率为“115200”,数据位为8位,停止位为1位。点击“OK”后,如图 3.5.5显示COM口和时间,证明串口连接成功。
图 3.5.4 设置UART
图 3.5.5串口连接成功
下载程序:在应用工程axi_gpio_led上右击,选择“Run As”,然后选择最后一项“Run Confagurations…”,如图 3.5.6所示。
图 3.5.6 Run Configuration
在Run Configuration页面点击“Debugger_axi_gpio-led-GDB”,点击“Target Setup”。其中,“Hardware Platform”为硬件平台,勾选“Reset entire system”(系统复位)和“Program FPGA”,然后点击“Run”开始下载程序,如图 3.5.7所示。
图 3.5.7 下载程序
在Vitis Terminal窗口可以看到上位机接收到的字符串,如图 3.5.8所示:
图 3.5.8 程序运行结果
程序成功打印出了“GPIO LED TEST”字符串,同时开发板上观察到流水灯现象,说明本次实验在开发板上面下载验证成功。开发板实验现象如图 3.5.9:
图 3.5.9 流水灯现象
2.5.2程序固化:
点击菜单栏“Xilinx”,选择“Program FPGA”,将硬件设计生成的bit文件和软件应用程序的elf文件,合成为一个download.bit文件,用于烧录到QSPI Flash芯片中。如图 3.5.10所示:
图 3.5.10 选择Program FPGA
在弹出界面Software Configuration下的microblaze_0栏,双击“Browse...”,选择工程的elf文件,该elf文件路径为G: vitis_proaxi_gpio_ledvitisaxi_gpio_ledDebugaxi_gpio_led.elf。选择工程的elf文件后,点击“Program”。如图 3.5.11所示:
图 3.5.11 选择elf文件
点击菜单栏“Xilinx”,选择“Program Flash”。如图 3.5.12所示:
图 3.5.12 选择Program Flash
在弹出界面的Image File栏,点击 “Browse...”,选择上一步生成的最终要固化的download.bit文件,路径为G:vitis_proaxi_gpio_ledvitisaxi_gpio_led_idebitstream。选择Flash器件“mt25ql128-spi_x1_x2_x4”。勾选“Verify after flash”。最后点击“Program”进行烧录。如图 3.5.13所示:
图 3.5.13 选择固化的文件和flash器件
烧录完成后,在Console栏打印信息:“Flash Operation Successful”,如图 3.5.14所示:
图 3.5.14 烧录完成
给开发板断电,拔掉JTAG连接线,重新上电启动即可观察到开发板呈现流水灯的现象。如图 3.5.15所示:
图 3.5.15 程序固化后流水灯现象
|