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);
}

 

posted @ 2014-03-22 16:46  玩电毁一生  阅读(9046)  评论(0编辑  收藏  举报