目录
实验任务
本实验通过使用AXI GPIO IP,实现对LED灯的控制。
实验框图
实验框图如下,相比较之前的 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。

配置 IP
打开 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。

#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 实验
【Xilinx AX7103 MicroBalze学习笔记3】MicroBlaze 利用 AXI GPIO 控制 LED 灯
【Xilinx AX7103 MicroBalze学习笔记4】MicroBlaze 按键中断实验
【Xilinx AX7103 MicroBalze学习笔记5】MicroBlaze 串口中断实验