版本:Vivado2020.2(Vitis)
任務:使用 AXI GPIO IP 核實現按鍵 KEY 控制 LED 亮滅(兩個都在PL端)
一、介紹
????????AXI GPIO (Advanced eXtensible Interface General Purpose Input/Output) 是 Xilinx 提供的一個可配置的通用輸入輸出 IP 核(通過 PL 資源實現的 GPIO,不同于 GPIO (E)MIO 是硬件固有的),用于在基于 AXI 總線的系統中實現 GPIO 功能。
主要特性:
-
雙通道設計:通常提供兩個獨立的GPIO通道(Channel 1和Channel 2)
-
可配置數據寬度:每個通道的數據寬度可獨立配置(1-32位)
-
輸入/輸出方向:每個位可獨立配置為輸入或輸出
-
中斷支持:可配置中斷生成功能
二、硬件設計
????????(1)配置ZYNQ 需要注意 AXI GPIO 使用了 AXI協議接口,所以 AXI接口、PL端時鐘接口、復位接口都需要保留,此外的一些配置如Bank電壓、UART串口配置(用于debug)、去掉未使用端口等等不再贅述。注意雖然使用了PL端按鍵,因為是通過AXI GPIO實現的不需要配置EMIO。
????????(2)KEY 和 LED 都單獨用一個 AXI GPIO IP(也可以只用一個,只不過分開方便區分),兩者配置相同以 KEY 為例配置界面如圖所示:
1.后面通過軟件設置io的輸入輸出方向(不勾選All In/Outputs)
2.各只用了1個引腳,故設置1通道(不勾選Enable Dual Channel)、位寬1位(GPIO Width?)
3.沒有使用中斷(不勾選Enable Interruput)
? ? ? ?(3)IP都配置好后點擊上面的自動運行和連接,同時會自動補全其他的所需的IP
????????(4)最后整體 bd 設計部分如圖所示:設計檢查、Generate Output Products、 Create HDL Wrapper、管腳約束、Gnerate Bitstream、Export Hardware(包含比特流文件)、啟動Vitis
三、軟件設計
? ? ? ? AXI GPIO 軟件設計相對來說比 MIO、EMIO簡單一點,因為是PL端資源實現,輸出直接通過拉高引腳電平和清零實現的,不過配置細節上還是有一些區別
? ? ? ? 此外AXI GPIO器件ID需要與硬件設計相對應,可以CTRL+左鍵器件ID跳轉到 xparameters.h 查看器件對應情況(或者直接CTRL+左鍵 xparameters.h 再去翻)
#include "stdio.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"
#include "sleep.h"//AXI GPIO是軟核的gpio所以不用定義管腳,是通過所在通道和掩碼來確定控制AXI GPIO哪一位的,通過軟件進行置位輸出與讀取//======================用戶自定義宏======================//#define KEY_AXI_GPIO_ID XPAR_GPIO_0_DEVICE_ID //宏定義KEY AXI GPIO 器件ID
#define KEY_CHANNEL 1 //宏定義KEY所在的axi gpio通道
#define KEY_MASK 0x01 //宏定義KEY所在通道掩碼(用哪位就置0,這里掩碼為了直觀取反了,這里表示啟用第0位)#define LED_AXI_GPIO_ID XPAR_GPIO_1_DEVICE_ID //宏定義LED AXI GPIO 器件ID
#define LED_CHANNEL 1 //宏定義LED所在的axi gpio通道
#define LED_MASK 0x01 //宏定義LED所在通道掩碼(用哪位就置0,這里掩碼為了直觀取反了,這里表示啟用第0位)//======================實例化======================//XGpio LED_AXI_GPIO; //定義LED AXI GPIO驅動實例
XGpio KEY_AXI_GPIO; //定義KEY AXI GPIO驅動實例//======================函數聲明======================//static int AXI_Gpio_Init(); //聲明AXI GPIO初始化函數//======================主函數======================//
int main()
{print("AXI GPIO Test\r\n");AXI_Gpio_Init();while(1){if (XGpio_DiscreteRead(&KEY_AXI_GPIO, KEY_CHANNEL)) //如果按鍵按下(讀取鍵值){ //寫1XGpio_DiscreteWrite(&LED_AXI_GPIO, LED_CHANNEL, 0x01);}else{//清0XGpio_DiscreteClear(&LED_AXI_GPIO, LED_CHANNEL, 0x01);}}return 0;
}//======================AXI GPIO初始化函數======================//
int AXI_Gpio_Init()
{//初始化器件驅動XGpio_Initialize(&LED_AXI_GPIO, LED_AXI_GPIO_ID);XGpio_Initialize(&KEY_AXI_GPIO, KEY_AXI_GPIO_ID);//GPIO方向設置(不同于GPIO (E)MIO , AXI GPIO是 0輸出/1輸入)XGpio_SetDataDirection(&LED_AXI_GPIO, LED_CHANNEL, ~LED_MASK);XGpio_SetDataDirection(&KEY_AXI_GPIO, KEY_CHANNEL, KEY_MASK);return 0;
}