學習硬件平台,第一件事不是GPIO就是串口,第二件事差不多就是中斷了。
查了網上資料MicroBlaze中斷的基本都是基於PLB總線的,畢竟PLB總線用的久。
於是就自己折騰着學習AXI的中斷使用。
其實基於PLB和基於AXI中斷的使用並沒有什么區別,我本人也是對照着PLB總線的源代碼學習的AXI中斷的使用。
首先,需要搭建一個硬件平台,使用EDK,添加GPIO和INTC的IP,我本人使用的是Digilent Atyls Board,就直接用官方提供的一些資料了。
但其他板子其實也差不多。
首先,GPIO要使用中斷,並將中斷信號連接到INTC模塊,同時INTC的信號還要連接到MicroBlaze的Interrupt,如下圖:
其他步驟不再贅述,做好這些后 Export Design。
打開SDK,
這時我遇到一個問題,就是在編輯源代碼時,我#include "xintc.h",居然提示找不到xintc這個文件,我搜索了以下ISE的安裝目錄,發現這個文件是有的。
而且在xparameters.h 中居然找不到和intc相關的宏定義,這就奇了大怪了。
我后來經過多方嘗試,發現可以這樣解決。
首先,我目前mss文件顯示了一個奇怪的地方:
其他的外設驅動都顯示,只有intc是空白。
嘗試着點擊左上角的“Modify this BSP file”,
然后如下修改:
點擊 none處,選擇intc,然后選擇符合的版本號。點擊“OK”后,SDK會自動重新編譯工程。
此時關掉mss文件再打開會發現有如下變化
現在intc的驅動正常了,打開xparameters.h也發現和intc相關的宏都有了。
以下是代碼部分,代碼是參照plb總線的寫的,不過我用硬件嘗試過,是完全可用的。
代碼可從此鏈接下載:(函數名較長,就沒有做注釋了。)
主要代碼摘抄如下:
#include <stdio.h> #include "platform.h" #include "xparameters.h" #include "xgpio.h" #include "xil_io.h" #include "mb_interface.h" #include "xintc.h" #define BTN_BASEADDR XPAR_PUSH_BUTTONS_5BITS_BASEADDR #define BTN_DEVICE_ID XPAR_PUSH_BUTTONS_5BITS_DEVICE_ID #define INTC_DEVICE_ID XPAR_AXI_INTC_0_DEVICE_ID #define BTN_IRTP_ID XPAR_AXI_INTC_0_PUSH_BUTTONS_5BITS_IP2INTC_IRPT_INTR XGpio pshBtns; XIntc intCtrl; XGpio led; char str[100]; void print(char *str); void PushButtonHandle(void *pshButton); int main() { init_platform(); print("Hello World\n\r"); XGpio_Initialize(&pshBtns, BTN_DEVICE_ID); XIntc_Initialize(&intCtrl, INTC_DEVICE_ID); XIntc_Connect(&intCtrl, BTN_IRTP_ID, PushButtonHandle, &pshBtns); XIntc_Enable(&intCtrl, BTN_IRTP_ID); microblaze_register_handler(XIntc_DeviceInterruptHandler, INTC_DEVICE_ID); microblaze_enable_interrupts(); XIntc_Start(&intCtrl, XIN_REAL_MODE); XGpio_InterruptEnable(&pshBtns, 1); XGpio_InterruptGlobalEnable(&pshBtns); XGpio_Initialize(&led, XPAR_LEDS_8BITS_DEVICE_ID); XGpio_SetDataDirection(&led, 1, 0xff); XGpio_DiscreteWrite(&led, 1, 0x01); while(1) { } return 0; } void PushButtonHandle(void *pshButton) { XGpio* PushButton = (XGpio*) pshButton; u32 btnState = XGpio_DiscreteRead(PushButton, 1); sprintf(str,"Button: %X \r\n", btnState); print(str); XGpio_InterruptClear(PushButton, 0xff); }