目录
实验任务
本实验通过使用 AXI GPIO IP,实现对 LED 灯的控制。
本实验基于 Vivado 2018.2 实现
实验框图
实验框图如下,相比较之前的 Hello World 的实验工程框图,这个实验只是多了AXI GPIO这个IP核。AXI GPIO 和 AXI UART 都通过 AXI Interconnect 模块与 MicroBlaze 互联,Microblaze 处理器输出 LED 灯的控制信号,通过 AXI Interconnect 互联模块传输到 AXI GPIO 模块,AXI GPIO 模块根据 AXI4-Lite 协议将 LED 灯控制信号解析出来,输出到 FPGA 的 LED 引脚,从而实现控制 LED 灯。
硬件设计(Vivado部分)
新建工程
由于大部分的操作和 Hello World 的实验操作类似,所以一些不重要的步骤就简化掉。
以 Hello World 的实验为基础,点击 File->Project->Save As,将工程重命名为 axi_gpio_led。
搭建Block Design
打开 Block Design,添加 AXI GPIO 模块,并对其进行配置。
将GPIO的位宽配置成4,因为有4个 LED 灯需要控制,其余参数保持默认即可。
点击自动连线,系统会自动连线。
重新 “Generate Output Products” 和 “Create HDL Wrapper”
Generate Output Products 主要是把IP参数和连接信息更新到Project中,同时也会检查错误。
Create HDL Wrapper 的作用是将各个模块或者代码文件例化到顶层文件中。
添加约束信息
在这个工程中,需要额外对 LED 管脚进行绑定,以自己的开发板管脚约束绑定。
set_property PACKAGE_PIN T6 [get_ports reset_n]
set_property IOSTANDARD LVCMOS15 [get_ports reset_n]
set_property PACKAGE_PIN N15 [get_ports uart_txd]
set_property PACKAGE_PIN P20 [get_ports uart_rxd]
set_property IOSTANDARD LVCMOS33 [get_ports uart_rxd]
set_property IOSTANDARD LVCMOS33 [get_ports uart_txd]
set_property PACKAGE_PIN R4 [get_ports diff_clk_clk_p]
set_property IOSTANDARD DIFF_SSTL15 [get_ports diff_clk_clk_p]
create_clock -period 5.000 [get_ports diff_clk_clk_p]
set_property PACKAGE_PIN B13 [get_ports {LED_tri_io[0]}]
set_property PACKAGE_PIN C13 [get_ports {LED_tri_io[1]}]
set_property PACKAGE_PIN D14 [get_ports {LED_tri_io[2]}]
set_property PACKAGE_PIN D15 [get_ports {LED_tri_io[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED_tri_io[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED_tri_io[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED_tri_io[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED_tri_io[0]}]
最后生成比特流文件,导入到硬件中,启动SDK,进入软件部分的设计。
软件设计(SDK部分)
新建工程
同之前 Hello World 的实验工程一样,新建一个工程项目命名为 axi_gpio_led,并在 src 文件夹中添加新的代码文件,命名为 main.c。
代码部分
将实验的代码复制至 mian.c 中
#include "xparameters.h"
#include "xgpio.h"
#include "xil_printf.h"
#include "sleep.h"
#define GPIO_DEVICE_ID XPAR_GPIO_0_DEVICE_ID
#define LED_CHANNEL 1
#define LED_DELAY 50000000
XGpio Gpio;
int main(void)
{
int Status;
int i=0;
//初始化gpio
Status = XGpio_Initialize(&Gpio, GPIO_DEVICE_ID);
if (Status != XST_SUCCESS) {
xil_printf("Gpio Initialization Failed\r\n");
return XST_FAILURE;
}
//设置数据方向 0为输出 1为输入
XGpio_SetDataDirection(&Gpio, LED_CHANNEL, 0);
//循环闪烁LED
while (1) {
//向指定通道写入数据,LED每0.5秒流转一次
XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, 0x01 << i);
//循环计数,表示第几个灯亮
if(i == 3)
i = 0;
else
i = i + 1;
//延时0.5秒
usleep(500000);
}
return 0;
}
//代码来源于正点原子
代码设计流程为:
- 先对 GPIO 初始化
- 设置数据的方向,因为是用 GPIO 控制 LED,所以定义为输出
- 以一个无限循环,对通道进行写数据,让 LED 灯形成流水
板级验证
将程序烧录到板子中验证程序的正确性,可以看到 LED 灯呈现流水的形式进行闪烁。
总结
本实验相对于 Hello World 实验做了小小的改动,只添加了一个 AXI GPIO 模块来实现对 LED 的控制。
往期系列博客
【Xilinx AX7103 MicroBalze学习笔记1】MicroBlaze介绍
【Xilinx AX7103 MicroBalze学习笔记2】MicroBlaze 串口发送 Hello World 实验