首页 » FPGA » 正文

zynq AXI GPIO使用

通用

如果需要GPIO中断,需要打开arm core中的pl-ps中断.如下图

API详情

xgpio函数

int XGpio_Initialize(XGpio * InstancePtr, u16 DeviceId)

名称 代码 解释
函数名 XGpio_Initialize 初始化GPIO
参数1 XGpio * InstancePtr 指向GPIO实例的指针
参数2 u16 DeviceId ID号,自动生成,在xparameters.h文件中定义
返回值 int 成功与否

void XGpio_SetDataDirection(XGpio *InstancePtr, unsigned Channel,u32 DirectionMask)

名称 代码 解释
函数名 XGpio_SetDataDirection 设置GPIO为输入/输出
参数1 XGpio * InstancePtr 指向GPIO实例的指针
参数2 unsigned Channel 待设置GPIO的通道(Vivado中设置gpio IP时的设置通道,为1或2)
参数3 u32 DirectionMask 方向设置。0:output;1:input

u32 XGpio_DiscreteRead(XGpio * InstancePtr, unsigned Channel)

名称 代码 解释
函数名 XGpio_DiscreteRead 读取GPIO的值
参数1 XGpio * InstancePtr 指向GPIO实例的指针
参数2 unsigned Channel 通道号,同上一函数
返回值 u32 最多32位的实际值

void XGpio_DiscreteWrite(XGpio * InstancePtr, unsigned Channel, u32 Data)

名称 代码 解释
函数名 XGpio_DiscreteWrite 写GPIO
参数1 XGpio * InstancePtr 指向GPIO实例的指针
参数2 unsigned Channel 通道号,同上一函数
参数3 u32 Data 需要写的值

简单操作

xparameters.h中相关宏定义

/* Definitions for peripheral LED */
#define XPAR_LED_BASEADDR 0x41200000
#define XPAR_LED_HIGHADDR 0x4120FFFF
#define XPAR_LED_DEVICE_ID 0  // 外设 设备ID
#define XPAR_LED_INTERRUPT_PRESENT 0
#define XPAR_LED_IS_DUAL 0

/* Definitions for peripheral SW */
#define XPAR_SW_BASEADDR 0x41210000
#define XPAR_SW_HIGHADDR 0x4121FFFF
#define XPAR_SW_DEVICE_ID 1          // 外设 设备ID
#define XPAR_SW_INTERRUPT_PRESENT 1  // 中断号
#define XPAR_SW_IS_DUAL 0

简单读写

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

int main() {
    int Status;
    XGpio Gpio_led, Gpio_sw;

    u32 swVal;

    init_platform();

    Status = XGpio_Initialize(&Gpio_led, XPAR_LED_DEVICE_ID);
    if (Status != XST_SUCCESS) {
        xil_printf("Gpio Initialization Failed\r\n");
        return XST_FAILURE;
    }

    Status = XGpio_Initialize(&Gpio_sw, XPAR_SW_DEVICE_ID);
    if (Status != XST_SUCCESS) {
        xil_printf("Gpio Initialization Failed\r\n");
        return XST_FAILURE;
    }

    XGpio_SetDataDirection(&Gpio_led, 1, 0x00);   // 全部为输出
    XGpio_SetDataDirection(&Gpio_sw, 1, 0xFF);    // 全部为输入

    while( 1 )
    {
        swVal = XGpio_DiscreteRead( &Gpio_sw, 1 );   // 读取 AXI_GPIO中第一个通道中的值
        XGpio_DiscreteWrite( &Gpio_led, 1, swVal );  // 不解释
    }

    cleanup_platform();
    return 0;
}

linux下操作方式

ls /sys/class/gpio/
export        gpiochip1019  gpiochip1023  gpiochip901   unexport

root@hello:# cat /sys/class/gpio/gpiochip1019/label
/amba_pl/gpio@41210000

可以看到有 三个GPIO控制器. 其中gpiochip1019的基址为41210000,根据基址可以找到对应的硬件GPIO是哪个.. 其中1019表示了该GPIO的端口号, 如果该控制器上存在多个IO,则1020表示该控制器第二个IO,1021表示第三个…..
简单写GPIO的方式如下:

int valuefd, exportfd, directionfd;

    // 打开控制器,创建gpio1020这个GPIO
    exportfd = open("/sys/class/gpio/export", O_WRONLY);
    if (exportfd < 0)
    {
        printf("Cannot open GPIO to export it\n");
        exit(1);
    }
    write(exportfd, "1020", 5);
    close(exportfd);

    // 配置方向
    directionfd = open("/sys/class/gpio/gpio1020/direction", O_RDWR);
    if (directionfd < 0)
    {
        printf("Cannot open GPIO direction it\n");
        exit(1);
    }

    write(directionfd, "out", 4);
    close(directionfd);

    // 写值
    valuefd = open("/sys/class/gpio/gpio1020/value", O_RDWR);
    if (valuefd < 0)
    {
        printf("Cannot open GPIO value\n");
        exit(1);
    }
    while (1)
    {
        sleep(1);
        write(valuefd,"3", 2);
        sleep(1);
        write(valuefd,"0", 2);
    }

发表评论