MicroBlaze AXI總線 GPIO中斷使用(On Atyls Board)


學習硬件平台,第一件事不是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);
}

 


免責聲明!

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



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