學會Zynq(5)GPIO中EMIO的使用方法
之前的Hello World和MIO使用都算是純PS部分,也就是把Zynq單純地當作ARM使用。很多人都是因為FPGA+ARM架構才使用的Zynq,有兩個關鍵問題容易引起初學者的興趣:(1).如何用PS控制PL;(2).如何完成PS與PL之間的資料通訊。本系列會介紹解決這兩個問題的各種方法。
EMIO就是PS控制PL資源的簡單例子。EMIO就是可擴充套件的MIO,當與PS直接相連的MIO不夠用時,可以使用EMIO做“擴充套件”。使用體會上,感覺就是ARM直接控制了PL部分的管腳。GPIO的bank2和bank3就是通過EMIO介面與PL相連的,本文將先通過PS控制PL部分流水燈的例項感受下EMIO的使用,然後再介紹EMIO相關的基本概念。
Zynq設計與程式碼詳解
建立一個工程,配置好Zynq的時鐘和DDR後,需要在MIO Configuration->I/O Peripherals->GPIO中選中EMIO GPIO。控制4個LED的流水,則EMIO GPIO(Width)選擇4,相當於擴充套件了4個GPIO。
IP Integrator中選中GPIO_0,右鍵->Make External建立埠,如下圖。
如果想修改新增埠名稱,單擊選中,在External Interface Properties視窗中修改(白板的中是不能修改的):
由於我們使用了PL中的管腳,所以必須要進行管腳約束。開啟任一設計階段的I/O Planning檢視,在I/O Ports視窗中可以看到4個EMIO埠(都是inout雙向埠)。根據硬體情況設定管腳號和電平標準,儲存為XDC檔案(當然也可以直接編輯XDC檔案)。
生成bit流後匯入到SDK中。SDK中新建工程,新增原始檔,程式碼清單如下:
#include "xgpiops.h"
#include "sleep.h"
XGpioPs GpioPs_Init()
{
XGpioPs_Config* GpioConfigPtr;
XGpioPs psGpioInstancePtr;
GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
XGpioPs_CfgInitialize(&psGpioInstancePtr, GpioConfigPtr, GpioConfigPtr->BaseAddr);
return psGpioInstancePtr;
}
int main()
{
static XGpioPs psGpioInstancePtr;
psGpioInstancePtr = GpioPs_Init(psGpioInstancePtr); //GPIO初始化
//EMIO配置為輸出
XGpioPs_SetDirectionPin(&psGpioInstancePtr, 54,1);
XGpioPs_SetDirectionPin(&psGpioInstancePtr, 55,1);
XGpioPs_SetDirectionPin(&psGpioInstancePtr, 56,1);
XGpioPs_SetDirectionPin(&psGpioInstancePtr, 57,1);
//使能EMIO輸出
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 54,1);
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 55,1);
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 56,1);
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 57,1);
while(1)
{
XGpioPs_WritePin(&psGpioInstancePtr, 54, 1);//EMIO的第0位輸出1
usleep(200000); //延時
XGpioPs_WritePin(&psGpioInstancePtr, 54, 0);//EMIO的第0位輸出0
usleep(200000); //延時
XGpioPs_WritePin(&psGpioInstancePtr, 55, 1);//EMIO的第1位輸出1
usleep(200000); //延時
XGpioPs_WritePin(&psGpioInstancePtr, 55, 0);//EMIO的第1位輸出0
usleep(200000); //延時
XGpioPs_WritePin(&psGpioInstancePtr, 56, 1);//EMIO的第2位輸出1
usleep(200000); //延時
XGpioPs_WritePin(&psGpioInstancePtr, 56, 0);//EMIO的第2位輸出0
usleep(200000); //延時
XGpioPs_WritePin(&psGpioInstancePtr, 57, 1);//EMIO的第3位輸出1
usleep(200000); //延時
XGpioPs_WritePin(&psGpioInstancePtr, 57, 0);//EMIO的第3位輸出0
usleep(200000); //延時
}
return 0;
}
用到的API函式與上一篇MIO的完全相同,不再贅述。不過注意54個MIO佔用的管腳號為053;64個EMIO佔用的管腳號為54117。這次用的延時函式為usleep,該函式輸入引數為long型,延時以微妙為單位。
EMIO介紹
關於GPIO的相關概念已經在上一篇中講述。EMIO只是GPIO訊號的bank2、bank3與PL部分連線的介面,使用的暫存器介面與MIO的完全相同。這裡對有差別的相關操作進行補充說明。
- 輸入是來自PL的連線,與輸出值或OEN暫存器無關。若DIRM設定為0,可以從DATA_RO暫存器中讀取輸入值。
- 輸出不支援三態,因此不受OEN暫存器的控制。輸出時將DIRM設定為1,使用DATA、MASK_DATA_LSW、MASK_DATA_MSK暫存器配置輸出值。
- 輸出使能線由PS輸出到PL,這些使能線受到DIRM和OEN暫存器的控制,如EMIOGPIOTN[x]=DIRM[X]&OEN[X]。
EMIO的I/O不能與MIO的I/O連線在一起的:EMIO的輸入不能與MIO的輸出接在一起;MIO的輸入也不能與EMIO的輸出結在一起。這是因為它們對應的GPIO屬於不同的bank,每個bank都是獨立的。
總結
本系列4-5篇介紹了Zynq中GPIO的使用,包括MIO和EMIO。UG585中還詳細介紹了GPIO的各種操作流程和示例,但在SDK中實際程式設計時,已經有了封裝好的庫函式,一般學習這些函式的用法即可。此外,每個GPIO都可以使用中斷功能,這部分內容在後面用到時再做介紹。
相關文章
- ZYNQ 中PS端GPIO EMIO使用
- 學會Zynq(4)GPIO中MIO的使用方法
- Xilinx ZYNQ 7000+Vivado2015.2系列(四)之GPIO的三種方式:MIO、EMIO、AXI_GPIO
- 學會Zynq(8)PL中斷示例(SPI)
- ZYNQ的gpio的硬體驅動庫知識
- 學會Zynq(7)中斷系統簡介
- 學會Zynq(3)Zynq的軟體開發基礎知識
- 學會Zynq(2)Zynq-7000處理器的配置詳解
- 有關GPIO的使用方法教程
- 學會Zynq(10)lwIP簡介
- 學會Zynq(1)搭建Zynq-7000 AP SoC處理器
- 學會Zynq(12)lwIP 1.4.1庫的配置與使用
- 學會Zynq(9)定時器使用示例(PPI)定時器
- 學會Zynq(11)RAW API的TCP和UDP程式設計APITCPUDP程式設計
- FPGADesigner《學會Zynq》系列目錄與傳送門FPGA
- 學會Zynq(6)固化程式到SD卡或QSPI FlashSD卡
- baremetal GPIO中斷REM
- Xilinx-ZYNQ7000系列-學習筆記(7):解決ZYNQ IP核自動佈線後會更改原有配置的問題筆記
- filezilla使用,4步學會filezilla使用方法
- 遠端會議的使用方法
- 3.外設GPIO、中斷
- 立創泰山派學習03--GPIO的控制
- STM32學習筆記——GPIO筆記
- 學會分享,學會生活,分享5款簡單易用的軟體。
- java中json的使用方法JavaJSON
- react中hooks的使用方法ReactHook
- Linux 中 ranger 的使用方法LinuxRanger
- YogaKit中 position 的使用方法
- jquery 中 $.map 的使用方法jQuery
- 【PyQt5】QListWidget 使用方法QT
- [PyQt5] QListWidget 使用方法QT
- 5分鐘學會 gRPCRPC
- GPIO模式模式
- 5S在非製造單位中的使用方法,拿走不謝!
- Java中try()catch{}的使用方法Java
- Go 中 io 包的使用方法Go
- SpringAop中JoinPoint物件的使用方法Spring物件
- 004:ZYNQ_AXI匯流排學習筆記(1)筆記