第六章 ZYNQ-MIZ701 GPIO使用之MIO


 

6.0 本章難度系數★★☆☆☆☆☆

6.1 GPIO簡介

Zynq7000系列芯片有54個MIO(multiuse I/O),它們分配在 GPIO 的Bank0 和Bank1隸屬於PS部分,這些IO與PS直接相連。不需要添加引腳約束,MIO信號對PL部分是透明的,不可見。所以對MIO的操作可以看作是純PS的操作。

GPIO的控制和狀態寄存器基地址為:0xE000_A000,我們SDK下軟件操作底層都是對於內存地址空間的操作。

wps237A.tmp

Bank0:MI0[31:0]

Bank1:MI0[52:53]

Bank2:EMI0[31:0]

Bank3:EMI0[63:32]

6.1.1 GPIO的控制寄存器地址空間

我們在SDK下操作的時候底層都是對這些寄存器的操作,具體的相關參數請參考技術手冊ug585-Zynq-7000-TRM.pdf

wps237B.tmpwps237C.tmp

wps237D.tmp

6.1.2MIO內部構造分析

wps238D.tmp

DATA_RO: 此寄存器使能軟件觀察PIN腳,當GPIO被配置成輸出的時候,這個寄存器的值會反應輸出的PIN腳情況。

DATA:此寄存器控制輸出到GPIO的值,讀這個寄存器的值可以讀到最后一次寫入該寄存器的值。 

MASK_DATA_LSW:位操作寄存器,寫入GPIO 低16bit 其他沒有改變的位置保存原先的狀態

MASK_DATA_MSW:位操作寄存器,寫入GPIO 高16bit 其他沒有改變的位置保存原先的狀態

DIRM:此寄存器控制輸出的開關,當DIRM[x]==0時候,禁止輸出

OEN: 輸出使能,當OEN[x]==0 的時候輸出關閉,PIN腳處於三態

因此,如果要讀IO狀態就得讀DATA_RO的值,如果是對某一位進行操作就是寫MASK_DATA_LSW/MASK_DATA_MSW

具體的相關參數請參考技術手冊ug585-Zynq-7000-TRM.pdf

6.1.3 EMIO的特性

與MIO大部分類似但是一下幾點需要注意下

• EMIO在PL部分,輸入與OEN寄存器無關,當DIRM設置為0的時候設置為輸入可以讀DATA_RO寄存器獲取數據。

• 輸出不能設置成三態,當DIRM設置為1的時候為輸出,寫入DATA寄存器或者MASK_DATA_LSW/MASK_DATA_MSW寄存器

• EMIOGPIOTN[x]=DIRM[x] & OEN[x],實現輸出的控制。

具體的相關參數請參考技術手冊ug585-Zynq-7000-TRM.pdf

6.2 電路分析及實驗預期

在MiZ702的開發板上有一個MIO是與開發板上的一個LD9相連的,這個MIO就是MIO7。實驗通過操作該MIO來實現LD9的閃爍。

6.3 ZYNQ核的添加及配置

Step1:新建一個名為為Miz701_sys的工程

wps238E.tmp

Step2:選擇RTL Project 勾選Do not specify source at this time

wps238F.tmp

Step3:選擇芯片xc7z010clg400-1。

wps2390.tmp

Step4:單擊Finish

wps2391.tmp

6.4使用IP Integrator創建硬件系統

Step1:單擊Create Block Design

Step2:輸入system

wps2392.tmp

Step3:單擊下圖中wps2393.tmp添加IP按鈕

wps23A4.tmp

Step4:搜素單詞z選擇ZYNQ7 Processing System,然后雙擊

wps23A5.tmp

Step5:添加進來了ZYNQ CPU IP,雙擊ZYNQ7 Processing System。

wps23A6.tmp
Step6: 修改時鍾輸入為50MHZ,可以看到ARM時鍾為650MHZ DDR為525MHZ(1050MHZ),並且修改FCLK_CLK0 為100MHZ。

wps23A7.tmp

Step7: 修改MIO的配置 修改IO電壓,增加ENT0 和UART1接口,在這個實驗中將會使用到MIO7確保勾選(默認勾選)單擊OK退出.

wps23A8.tmp

wps23A9.tmp

wps23AA.tmp

Step8:修改內存型號為MT41K256M16RE-125 M。

wps23BB.tmp

Step9:單機Run Block Automation 進行自動連線,VIVADO軟件會根據信號的命名規則智能連線。

wps23BC.tmp

Step10:勾選如下,直接單機OK

wps23BD.tmp

Step11:在你點擊了OK后,你會發現DDR以及FICED_IO自勱的延伸出來,然后把時鍾FCLK_CLK0和M_AXI_GPI0_ACLK連接。方法:當把鼠標靠近的時候會自動連接。

wps23BE.tmp

Step12:為了讓以太網PHY RTL8211E-VL可以工作,必須讓其復位PIN腳設置為1,只要簡單添加一個常量IP並且映射到PL部分的PIN腳(復位腳在FPGA 部分(PL)),和添加CPU方法一樣

wps23BF.tmp

Step13:雙擊設置常量為1

wps23C0.tmp

Step14:右擊PIN腳選擇Make External

wps23C1.tmp

wps23C2.tmp

Step15:取個有意義的名字如下圖,只要單擊相應的模塊就可以在右手邊修改

wps23D2.tmp

Step16: 右擊 system.bd, 單擊Generate Output Products

wps23D3.tmp

Step17:支部操作會產生執行、仿真、綜合的文件,可以看出來最后的硬件設計步驟還是回到了我們前面的FPGA開發上來了。

wps23D4.tmp

Step18:右擊system.bd 選擇 Create HDL Wrapper 這步的作用是產生頂層的HDL文件

wps23D5.tmp

Step19:選擇Leave Let Vivado manager wrapper and auto-update 然后單擊OK

wps23D6.tmp

Step20:單機Add Sources。

wps23D7.tmp

Step21:選擇Add or create constraints

wps23D8.tmp

Step22:選擇Create File

wps23E9.tmp

Step23:輸入zynq_pin。

wps23EA.tmp

Step24:如圖,單擊Finish

wps23EB.tmp

Step25:雙擊打開zynq_pin.xdc文件,添加PIN腳約束

wps23EC.tmp

wps23ED.tmp

Step26:執行->產生bit文件wps23EE.tmp

6.5導出SOC硬件到SDK

Step1:File->Export->Export Hardware

wps23EF.tmp

Step2:勾選Include bitstream 直接單擊OK

wps23F0.tmp

Step3:File->Launch SDK加載到SDK

wps23F1.tmp

Step4:單擊OK

wps2401.tmp

6.6 新建LED_Flash SDK工程

Step1:在SDK界面中,新建一個名為LED_Flash的工程,單擊Next。

wps2402.tmp

Step2:建立一個空的工程

wps2403.tmp

Step3:新建一個C的源文件

wps2404.tmp

Step4:取名為LED_Flash.c

wps2405.tmp

Step5:取名為LED_Flash.c

接下來就向LED_Flash.c中添加內容了,之前講過,其中MIO7接到了LD9這個燈上,接下來我們利用程序讓他閃起來。

#include "xgpiops.h"

#include "sleep.h"

int main()

{

static XGpioPs psGpioInstancePtr;

XGpioPs_Config* GpioConfigPtr;

int iPinNumber= 7; //LD9連接的是MIO7

u32 uPinDirection = 0x1; //1表示輸出,0表示輸入

int xStatus;

//--MIO的初始化

    GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);

if(GpioConfigPtr == NULL)

return XST_FAILURE;

xStatus = XGpioPs_CfgInitialize(&psGpioInstancePtr,GpioConfigPtr, GpioConfigPtr->BaseAddr);

if(XST_SUCCESS != xStatus)

print(" PS GPIO INIT FAILED \n\r");

//--MIO的輸入輸出操作

     XGpioPs_SetDirectionPin(&psGpioInstancePtr, iPinNumber,uPinDirection);//配置MIO輸出方向

XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, iPinNumber,1);//配置MIO的第7位輸出

while(1)

{

XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 1);//點亮MIO的第7位輸出1

sleep(1); //延時

XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 0);//熄滅MIO的第7位輸出0

sleep(1); //延時

}

    return 0;

}

6.7 程序分析

具體內容請對照注釋說明,這里想說明的是iPinNumber這個參數,應為我們要操作的是MIO7,所以這里所以這里的iPinNumber等於7,在后一章的EMIO中也有這個參數,具體怎么算請參看下一節內容,這里就做個鋪墊吧。

6.8 IO寄存器直接輸出

實際上以上代碼的銷量是非常低的,因為封裝好的函數,里面有很多調用開銷,還有很多自動化的代碼,特別是當要求IO輸出速度很高的時候,差距會很明顯。筆者這里把IO部分的函數做一點小的改動,改為直接控制寄存器地址空間。

while(1)

{

//XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 1);//點亮MIO的第7位輸出1

Value = ~((u32)1 << (iPinNumber + 16U)) & ((1 << iPinNumber) | 0xFFFF0000U);

Xil_Out32(0xE000A000,Value);//直接寄存器操作

sleep(1); //延時

Value = ~((u32)1 << (iPinNumber + 16U)) & ((0 << iPinNumber) | 0xFFFF0000U);

Xil_Out32(0xE000A000,Value);//

//XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 0);//熄滅MIO的第7位輸出0

sleep(1); //延時

}

這個地址0xE000A000是不是很熟悉呢?沒錯這就是前面筆者貼出的一張表格,而且正是位控制 寄存器MASK_DATA_0_LSW

wps2406.tmp

6.9電平翻轉速度庫函數和寄存器對比

庫函數測試函數

XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 1);//點亮MIO的第7位輸出1

XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 0);//熄滅MIO的第7位輸出0

寄存器測試函數

while(1)

{

Value = ~((u32)1 << (iPinNumber + 16U)) & ((1 << iPinNumber) | 0xFFFF0000U);

Xil_Out32(0xE000A000,Value);//直接寄存器操作

Value = ~((u32)1 << (iPinNumber + 16U)) & ((0 << iPinNumber) | 0xFFFF0000U);

Xil_Out32(0xE000A000,Value);//

}

庫函數測試函數出來的頻率

wps2417.tmp

寄存器測試函數出來的頻率(由於示波器帶寬太低,波形已經變形)

wps2418.tmp

6.10 本章小結

本章講解了ZYNQ芯片的GPIO的一些知識,然后通過使用SDK進行編程點亮一個LED。同時分析了程序的代碼。測試結果說明了,庫函數使用方便,但是效率地下,寄存器效率高,但是使用不方便。因此在設計系統的時候如何優化是需要綜合考慮的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM