学习硬件平台,第一件事不是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#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_INTRXGpio 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);}