zynq板zedboard+SDK设计(三)AXI GPIO软核

0.前言

通过一个简单的工程,实现对axi_gpio核基本功能的介绍

1.AXI GPIO简介

AXI GPIO IP 核为 AXI 接口提供了一个通用的输入/输出接口。与 PS 端的 GPIO 不同,AXI GPIO 是一个软核(Soft IP),即 ZYNQ 芯片在出厂时并不存在这样的一个硬件电路,而是由用户通过配置 PL 端的逻辑资源来实现的一个功能模块。而 PS 端的 GPIO 是一个硬核(Hard IP),它是一个生产时在硅片中实现的功能电路。

AXI GPIO 可以配置成单通道或者双通道,每个通道的位宽可以单独设置。另外通过打开或者关闭三态缓冲器,AXI GPIO 的端口还可以被动态地配置成输入或者输出接口。其顶层模块的框图如下所示:

模块的左侧实现了一个 32 位的 AXI4-Lite 从接口,用于主机访问 AXI GPIO 内部各通道的寄存器。当右侧接口输入的信号发生变化时,模块还能向主机产生中断信号。不过只有在配置IP 核时选择“使能中断”,才会启用模块的中断控制功能。

 2.PL端设置

新建工程打开bd,首先添加zynq核并设置zedboard预设

添加axi_gpio核 

 axi_gpio核配置界面如下,首先是可以通过勾选all inputs或all outputs来设置axi_gpio核的方向,也可以不勾选,通过ps进行方向的设置,设置方式和gpio硬核相似,建议在这里勾选设置好方向,这样我们在ps端就可以直接通过Xil_In或是Xil_Out进行读写,方便很多。

然后是设置位宽和默认的一个输出值。

勾选enable dual channel后可以使能第二路gpio端口,设置方法与第一路相同

最后下面还有一个中断的使能接口,勾选之后就会出现一个中断的接口

3.通过Xil_In或是Xil_Out对AXI GPIO进行读写

我们添加两个axi_gpio,分别设为输入和输出,都为8位宽

 有的时候可能出现GPIO的位宽无法设置或是在自动连续后改变了的情况出现,此时需要注意一下在设置界面中board interface要选择custom

 添加一个设计模块,将输入的值加1后输出

`timescale 1ns / 1ps

module plus1(
input clk,
input [7:0] data_i,
output [7:0] data_o
    );

reg [7:0] data;

always@(posedge clk)begin
data = data_i + 1;
end

assign data_o = data;

endmodule

最终连接好后bd如图

两个gpio核地址

SDK部分

打开SDK创建工程,main函数代码如下,这里需要注意的是,Xil_In和Xil_Out函数需要与前面设置的gpio的输入输出对应,比如我们前面设置的gpio1是输出,因此,需要用Xil_Out去对gpio1进行输出数据,gpio0是输入,因此,要用Xil_In通过gpio0进行读取数据,读写用反的话就无法实现相应功能。

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xil_io.h"


int main()
{
    init_platform();
    UINTPTR addr;
    u32 data;

    addr = 0x41210000;
    data = 0x10;
    Xil_Out8(addr,data);
    printf("data_o = 0x%x\n",data);

    addr = 0x41200000;
	data = Xil_In8(addr);
	printf("data_i = 0x%x\n",data);

    cleanup_platform();
    return 0;
}

最后,我们可以看见terminal和memory内的数据,输出的数据加1后返回,对应的地址内也有相应的数据,此次实验完成

4.通过AXI GPIO读写函数进行读写

 BD的设计采样一个AXI GPIO双通道的形式

其中自建RTL也是简单实现对输入加一后输出的功能

`timescale 1ns / 1ps

module axi_gpio_test(
    input clk,
    input rst,
    input [31:0] din,
    output wire [31:0] dout
);
    
reg [31:0] data;

always @(posedge clk)begin
    if(rst)
        data <= 0;
    else
        data <= din + 1;
end

assign dout = data;
    
endmodule

 生成比特流后导出硬件平台

 SDK部分

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xgpio.h"
#include "xparameters.h"
#include "xil_io.h"

#define channel_1 1U
#define channel_2 2U    

XGpio axiGpio0;

int main()
{
    XGpio_Initialize(&axiGpio0,XPAR_GPIO_0_DEVICE_ID);

    XGpio_SetDataDirection(&axiGpio0,channel_1,0);        //通道1设置为输出,即第三个参数1为输入,0为输出
    XGpio_SetDataDirection(&axiGpio0,channel_2,0xFFFFFFFF);    //通道2设置为输入,0xFFFFFFFF表示32为全部设置为输入

    u32 ReadData,i;

    for(i=0;i<10;i++)
    {
    	XGpio_DiscreteWrite(&axiGpio0,channel_1,i);    //这里用gpio写函数,实现的功能与下面的Xil_Out32(0x41200000,i)相同。
    	//Xil_Out32(0x41200000,i);
    	ReadData = XGpio_DiscreteRead(&axiGpio0,channel_2);
    	printf("read data = %d \n",ReadData);
    }

    return 0;
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值