概述:最近開始學習ZYNQ的嵌入式部分,在這裏對 GPIO,MIO,EMIO 做一個簡單整理,並做一個通過使用 GPIO 外設通過 MIO 控制 PS 端的 LED的簡單實驗,後面會補上AXI部分筆記。本文章參考了Xilinx官方用戶參考手冊:UG585。
注:學習之前建議先看一下ZYNQ_7000架構圖,這樣做可以對各個知識點有一個全局的概念。
1、GPIO是一個外設,用來對器件的引腳作觀測(input)以及控制(output)。
GPIO手冊簡介
2、MIO(Multiuse I/O),將來自PS外設和靜態存儲器接口的訪問多路複用到
PS的引腳上。
3、EMIO,是擴展的MIO,當PS的引腳不夠用的時候,可以通過EMIO來進行擴展,從而使用PL的引腳。(注1:EMIO是PS和PL之間的接口)(注2:並不是所有外設都可以通過EMIO連接到PL)
圖中圈中部分不能通過EMIO連接到PL端
4、GPIO可以獨立且動態地編程,作爲輸入/輸出以及中斷模式。
5、GPIO被分成4個Bank。Bank0/Bank1 通過MIO連接到PS的引腳,Bank2/Bank3 通過EMIO連接到PL。
6、軟件通過一組存儲映射的寄存器來控制GPIO。
7、寄存器組:(6個寄存器控制GPIO)PS端部分
DATA_RO,用來反映器件引腳的狀態。
DATA,在GPIO被配置成輸出的時候,該寄存器可以控制輸出的數值。
MASK_DATA_LSW,用於屏蔽DATA低16位
MASK_DATA_MSW,用於屏蔽DATA高16位
DIRM,用於控制I/O引腳是作爲輸入還是輸出。0:關閉輸出驅動;1:使能輸出驅動
OEN,當I/O被配置成輸出時,該寄存器用於打開/關閉輸出使能。0:關閉輸出使能;1:打開輸出使能。
MASK_MSW用法:1111_0000——1111_0000 (除了需要修改,其他用1屏蔽)
Data: 0000__1010——0000_0000
DATA:1010__0101——1010_0101_XXXX_XXXX_XXXX_XXXX
16個LED:亮滅亮滅——滅亮滅亮——亮滅亮滅——滅亮滅亮
DATA:1010__1010_1010_0101_XXXX_XXXX_XXXX_XXXX
16個LED:亮滅亮滅——亮滅亮滅——亮滅亮滅——滅亮滅亮
(1)先把DATA的值讀出來 (read)
(2)改變需要更換的數值 (modify)
(3)修改之後的數值寫在DATA裏(write)
8、MIO[8:7]在系統復位過程中作爲VMODE引腳(作爲輸入),用於配置MIO Bank的電壓。復位結束後,MIO[8:7]只能作爲輸出信號。
實驗內容:
使用PS端的MIO控制LED,實現LED閃爍的效果,並向串口發送GPIO MIO TEST!
#include"stdio.h"
#include"xparameters.h"
#include"xgpiops.h"
#include"sleep.h"
#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID
//核心板上PS端LED 爲增強程序可讀性,所以定義了名稱
#define MIO0_LED 0
XGpioPs_Config *ConfigPtr;
XGpioPs Gpio;
int main()
{
printf("GPIO MIO TEST!\n\r");
//根據器件的ID,查找器件的配置信息
ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
//初始化GPIO
XGpioPs_CfgInitialize(&Gpio, ConfigPtr,ConfigPtr->BaseAddr);
//把GPIO的方向設置爲輸出(0,輸入/ 1,輸出)
XGpioPs_SetDirectionPin(&Gpio,MIO0_LED, 1);
//設置輸出使能(0,關閉/ 1,打開)
XGpioPs_SetOutputEnablePin(&Gpio, MIO0_LED, 1);
//寫數據到GPIO的輸出引腳
XGpioPs_WritePin(&Gpio, MIO0_LED, 1);
while(1){
//點亮
XGpioPs_WritePin(&Gpio, MIO0_LED, 1);
//延時
sleep(1);
//熄滅
XGpioPs_WritePin(&Gpio, MIO0_LED, 0);
//延時
sleep(1);
}
return 0;
}