1. LED流水灯控制

任务目标

在Zynq-7000系列芯片上,通过ARM Cortex-A9核配置FPGA侧的AXI GPIO IP核,控制4个LED实现流水灯效果。本案例将完成硬件工程搭建(Vivado)、软件工程编写(Vitis)及开发板验证,帮助掌握PS-PL间AXI接口的基本使用流程。

硬件设计(Vivado)

使用Vivado创建Block Design,添加Zynq PS核与AXI GPIO IP,完成PL侧LED引脚约束。

  1. 创建工程,器件选择xc7z020clg400-1(以Zynq-7020为例)
  2. 添加Zynq7 Processing System IP,运行Block Automation自动配置(UART、DDR等默认即可)
  3. 添加AXI GPIO IP,双击配置:
    - GPIO Width:4
    - 取消勾选All Outputs(默认输出即可)
    - 勾选Enable Dual Channel(不需要,保持默认单通道)
  4. 运行Connection Automation,将S_AXI连接到PS的M_AXI_GP0
  5. 右键点击GPIO引脚,选择Make External,重命名为led_tri_io
  6. 创建约束文件,添加引脚约束:
set_property PACKAGE_PIN M14 [get_ports {led_tri_io_tri_o[0]}]
set_property PACKAGE_PIN M15 [get_ports {led_tri_io_tri_o[1]}]
set_property PACKAGE_PIN K16 [get_ports {led_tri_io_tri_o[2]}]
set_property PACKAGE_PIN J16 [get_ports {led_tri_io_tri_o[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_tri_io_tri_o[*]}]

生成比特流后导出硬件(File → Export Hardware,勾选Include bitstream),启动Vitis。

软件设计(Vitis)

创建Application Project,平台选择导出的硬件。以下是完整C代码:

#include "xgpio.h"
#include "xparameters.h"
#include "sleep.h"

#define GPIO_DEVICE_ID  XPAR_AXI_GPIO_0_DEVICE_ID
#define LED_CHANNEL     1
#define LED_BLINK_MS    200

static XGpio gpio;

int main(void)
{
    u32 led_pattern = 0x01;  // 初始点亮LED0
    int status;

    // 初始化GPIO
    status = XGpio_Initialize(&gpio, GPIO_DEVICE_ID);
    if (status != XST_SUCCESS) {
        return XST_FAILURE;
    }

    // 设置GPIO方向为输出
    XGpio_SetDataDirection(&gpio, LED_CHANNEL, 0x0);

    while (1) {
        // 输出当前流水灯模式
        XGpio_DiscreteWrite(&gpio, LED_CHANNEL, led_pattern);

        // 移位实现流水效果:LED0→LED1→LED2→LED3→LED0
        led_pattern = (led_pattern << 1);
        if (led_pattern > 0x08) {
            led_pattern = 0x01;  // 循环回到LED0
        }

        usleep(LED_BLINK_MS * 1000);
    }

    return 0;
}

运行与验证

运行步骤:

  1. 将比特流下载到开发板(Program FPGA)
  2. 在Vitis中右键点击工程,选择Run As → Launch on Hardware
  3. 观察开发板4个LED状态

通过标准:4个LED按LED0→LED1→LED2→LED3顺序依次点亮,每个LED亮200ms后熄灭并点亮下一个,循环往复。若观察到该流水效果,说明ARM通过AXI接口成功控制FPGA侧GPIO,案例验证通过。

常见问题

  • LED不亮:检查约束文件中引脚编号是否与开发板原理图一致,确认比特流已正确下载
  • 编译报错:确认Vitis平台选择的是导出的硬件文件(.xsa),而非默认空平台
  • 流水速度异常:usleep参数单位为微秒,200ms对应200000,代码中已正确换算
ARM Cortex-A9 PS 处理系统 GPIO 驱动代码 AXI 总线 M_AXI_GP0 FPGA 可编程逻辑 PL 逻辑 AXI GPIO IP核 GPIO宽度: 4 LED 指示 0 1 2 3 数据写入 0x01→0x02→0x04→0x08 数据流向:ARM核通过AXI总线向FPGA侧GPIO寄存器写入模式值,GPIO输出引脚驱动LED