Zedboard学习(五):MIO与EMIO操作
MIO:
Zynq7000 系列芯片有 54 個 MIO(multiuse I/O), 它們分配在 GPIO 的 Bank0 和Bank1 隸屬于 PS 部分, 這些 IO 與 PS 直接相連。 不需要添加引腳約束, MIO 信號對 PL部分是透明的。 所以對 MIO 的操作可以看作是純PS 的操作。
EMIO:
同時Zynq可以配置多達63個EMIO引腳,這些引腳可以配置到PL部分,也可以配置為外設的引腳,不過需要添加約束文件指定封裝引腳。EMIO分配在Bank2和Bank3上。
資料鏈接
除了Bank1是22bit之外,其他三個Bank都是32bit,折算一下就是:
MIO——54bit;
EMIO——64bit。
使用上MIO和EMIO也較為近似,EMIO主要用于MIO不夠,擴展GPIO的場合。
MIO
1、新建工程。
2、跟前面的博文一樣,對zynq進行底層配置,搭建soc最小系統。(點擊打開鏈接)
3、產生比特流文件。
4、導出比特流文件。File–>Export–>Export Hardware。
5、打開SDK,進行PS部分的開發:File–>Launch SDK 。
在SDK下新建工程:File–>Launch SDK 。
6、工程模板選空工程就行。
7、準備自己編寫代碼,在新建的工程下,src右鍵–>New–>Source FIle 填上文件名字。
8、程序:
/** main.c** Created on: 2017年7月11日* Author: XHB*/#include "xgpiops.h" #include "sleep.h" #include "xparameters.h"int main() {XGpioPs gpioStruct;XGpioPs_Config *gpioConfig;int pinNum = 7;u32 pinDirection = 1; //1表示輸出, 0表示輸入s32 xStatus;//print("hello\n");//初始化MIO//通過gpio的device_ID獲取GPIO寄存器的基地址gpioConfig = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);if(gpioConfig == NULL) //若指針為空,說明沒有找到對應的設備或者FPGA底層未進行配置{print("Can not lookup gpioConfig!!!\n");return XST_FAILURE;}//初始化GPIOxStatus = XGpioPs_CfgInitialize(&gpioStruct, gpioConfig, gpioConfig->BaseAddr);if(xStatus != XST_SUCCESS){print("PS MIO GPIO Initialize failed!!!\n");}else{print("PS MIO GPIO Initialize successed!!!\n");}//設置GPIO的引腳以及輸入輸出模式XGpioPs_SetDirectionPin(&gpioStruct, pinNum, pinDirection);//設置GPIO的輸出使能XGpioPs_SetOutputEnablePin(&gpioStruct, pinNum, 1);while(1){XGpioPs_WritePin(&gpioStruct, pinNum, 1); //給高電平sleep(1); //延時1sXGpioPs_WritePin(&gpioStruct, pinNum, 0); //給低電平sleep(1); //延時1s}return 0; }9、程序說明:
頭文件:
xgpiops.h:定義了與GPIO初始化、操作等有關的函數和參數;
sleep.h:定義了延時函數,用來控制延時;
xparameters.h:與底層配置有關,定義了ps端的外設的Device ID、基地址等等信息。
結構體:
主要用到兩個結構體:
XGpioPs_Config類型結構體:包含有GPIO初始化信息。
XGpioPs類型結構體:用于對GPIO進行相關配置,調用庫函數對其成員變量賦值,實質上是映射到寄存器上,對寄存器進行操作。跟當初學習stm32的庫函數時的原理一樣。
/*** The XGpioPs driver instance data. The user is required to allocate a* variable of this type for the GPIO device in the system. A pointer* to a variable of this type is then passed to the driver API functions.*/ typedef struct {XGpioPs_Config GpioConfig; /**< Device configuration */u32 IsReady; /**< Device is initialized and ready */XGpioPs_Handler Handler; /**< Status handlers for all banks */void *CallBackRef; /**< Callback ref for bank handlers */u32 Platform; /**< Platform data */u32 MaxPinNum; /**< Max pins in the GPIO device */u8 MaxBanks; /**< Max banks in a GPIO device */ } XGpioPs;幾個庫函數:
可以跟蹤到定義看他們詳細的代碼,這里簡單介紹一下。使用時都是些套路。
a、通過gpio的device_ID獲取GPIO寄存器的基地址,返回值是一個XGpioPs_Config指針類型結構體,deviceID可以到xparameters.h找到我們底層的GPIO的ID。
b、初始化GPIO。填入兩個結構體的指針,以及GPIO對應的基地址。
s32 XGpioPs_CfgInitialize(XGpioPs *InstancePtr, XGpioPs_Config *ConfigPtr,u32 EffectiveAddr)c、設置GPIO輸入\輸出模式。InstancePtr是前面初始化時設置了的結構體,Pin是MIO的引腳號,Direction若是1表示輸出,若是0表示輸入。
void XGpioPs_SetDirectionPin(XGpioPs *InstancePtr, u32 Pin, u32 Direction)d、GPIO輸出使能。InstancePtr是前面初始化過的結構體,pin是引腳號,OpEnable若是1使能引腳,允許輸出;若是0,禁止輸出。
void XGpioPs_SetOutputEnablePin(XGpioPs *InstancePtr, u32 Pin, u32 OpEnable)e、向MIO的某個引腳寫入數據,輸出1或0。InstancePtr和Pin跟前面一樣,Data為1或0,對應高電平和低電平。
void XGpioPs_WritePin(XGpioPs *InstancePtr, u32 Pin, u32 Data)f、GPIO相關的函數都可以在xgpiops.h找到。
10、SDK下運行程序,就可以看到MIO7對應的LED等閃爍了。
其實這里可以不用配置FPGA的比特流文件,因為MIO是不依托FPGA的PL部分的,是直接掛在PS部分的,所以直接下載進去也可以運行的。
如果直接在sdk下載,會彈出警告說沒有配置底層,忽視直接下載即可。
EMIO:
1、vivado下新建工程。
2、跟前面的博文一樣,對zynq進行底層配置,搭建soc最小系統。(點擊打開鏈接)
3、雙擊zynq,手動更改zynq7處理器的配置。
在emio那里打鉤,添加EMIO外設。
只添加8個EMIO,所以位數選8。
4、完成更改,回到block design中看看,發現多出了GPIO_0。選中他,按CTRL+T將引腳引出。這里的GPIO_0對應EMIO。
5、保存當前的block design,回到工程視圖,產生仿真文件。
6、創建頂層文件。
打開新建的Verilog文件,可以看到新加的接口:gpio_tri_io_0。
7、由于EMIO是PL部分新添加的外設,還需要進行引腳約束。
添加引腳約束文件。
8、創建一個xdc文件。
9、創建完成后,對新建的xdc文件編輯。
輸入代碼:
10、產生比特流文件,之后導出并啟動sdk。同前面MIO的步驟一樣,新建一個空工程輸入代碼:
/** main.c** Created on: 2017年7月12日* Author: XHB*/#include "xgpiops.h" #include "sleep.h" #include "xparameters.h"int main() {XGpioPs gpioStruct;XGpioPs_Config *gpioConfig;int pinNum = 54;u32 pinDirection = 1; //1表示輸出, 0表示輸入s32 xStatus;print("hello\n");//初始化MIO//通過gpio的device_ID獲取GPIO寄存器的基地址gpioConfig = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);if(gpioConfig == NULL) //若指針為空,說明沒有找到對應的設備或者FPGA底層未進行配置{print("Can not lookup gpioConfig!!!\n");return XST_FAILURE;}//初始化GPIOxStatus = XGpioPs_CfgInitialize(&gpioStruct, gpioConfig, gpioConfig->BaseAddr);if(xStatus != XST_SUCCESS){print("PS MIO GPIO Initialize failed!!!\n");}else{print("PS MIO GPIO Initialize successed!!!\n");}//設置GPIO的引腳以及輸入輸出模式XGpioPs_SetDirectionPin(&gpioStruct, pinNum, pinDirection);//設置GPIO的輸出使能XGpioPs_SetOutputEnablePin(&gpioStruct, pinNum, 1);while(1){XGpioPs_WritePin(&gpioStruct, pinNum, 1); //給高電平sleep(1); //延時1sXGpioPs_WritePin(&gpioStruct, pinNum, 0); //給低電平sleep(1); //延時1s}return 0; }好的,你應該看出來了,跟MIO部分的其實基本都一樣了,只是引腳號變成了54,而MIO部分的是7。
最開始算了一下,MIO總共有54個,0~53;EMIO有64個。所以54就是第一個EMIO了。
11、下載程序前,一定要先把工程的比特流文件下載一下。因為EMIO是依托于PL的,需要FPGA底層配置后,才可在PS端使用。下載后會看到LED閃爍。
這里選用的GPIO的引腳號是54,對應第一個EMIO,也就是之前引腳約束時分配的第一個LED對應的引腳;總共分配了8個EMIO,更改這個引腳號,也同樣可以控制其他幾個LED。
總結
以上是生活随笔為你收集整理的Zedboard学习(五):MIO与EMIO操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 调用face++平台api进行人脸识别
- 下一篇: Zedboard学习(六):XADC读取