介绍
使用microblaze软核搭建处理器,实现中断
其中microblaze_0为microbalze内核,外接128Kb的local memory、利用JTAG调试的mdm内核、中断管理器axi_intc以及uatr外设和GPIO外设。
GPIO中断的实现利用vio IP核实现,16位的VIO接到GPIO作为输入来模拟按键输入。
UART中断外接串口调试助手或者直接利用SDK terminal实现。
concat IP核将多个中断源合成一条总线提供给中断管理器。
实验结果
jtag调试段循环输出hello word
ILA抓取的GPIO_o实现0000——FFFF的转换
GPIO_t为0xffff,说明16个gpio全为输入,至于GPIO_o为什么会实现数据转换,这是因为此时的信号还没有经过三态门的转换,在进过三态门转换后16个gpio全为输入
利用vio改变GPIO的输入,使GPIO控制器产生中断,这时候程序进入GPIO的中断处理函数,在调试端打印“gpio interrupt”.
利用串口调试助手,输入一段16进制的数字,会看到相同数字的返回值,这是调用中断返回的值,串口调试助手发送了3个8bit的数值,产生了四个中断,其中前三个中断为接收中断,最后一个为发送中断
c程序
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"
#include "xuartlite.h"
#include "xuartlite_l.h"
#include "xintc.h"
#include "xil_io.h"
#include "sleep.h"
#define GPIO_EXAMPLE_DEVICE_ID XPAR_GPIO_0_DEVICE_ID
#define UART_DEVICE_ID XPAR_UARTLITE_0_DEVICE_ID //串口器件ID
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID //中断控制器ID
#define AXI_GPIO_INTR_ID XPAR_INTC_0_GPIO_0_VEC_ID //AXI GPIO中断ID
#define UART_INTR_ID XPAR_INTC_0_UARTLITE_0_VEC_ID //串口中断ID
#define EXCEPTION_ID XIL_EXCEPTION_ID_INT //中断异常ID
#define RX_NOEMPTY XUL_SR_RX_FIFO_VALID_DATA // 接收 FIFO 非空
static XGpio Gpio; /* The Instance of the GPIO Driver */
static XIntc Intc; //中断控制器实例
static XUartLite Uart; //串口实例
void GpioHandler(void *CallbackRef);
void uart_handler(void *CallbackRef);
int main()
{
init_platform();
print("Hello World\n\r");
//设备初始化
XGpio_Initialize(&Gpio, GPIO_EXAMPLE_DEVICE_ID);
XGpio_SetDataDirection(&Gpio, 1, 0xffff);
XUartLite_Initialize(&Uart , UART_DEVICE_ID);
//初始化中断控制器
XIntc_Initialize(&Intc, INTC_DEVICE_ID);
//关联中断ID和中断服务函数
//中断服务函数是需要我们自己编写的, 用于响应和处理 AXI GPIO 中断的函数
XIntc_Connect(&Intc,AXI_GPIO_INTR_ID,(Xil_ExceptionHandler)GpioHandler,&Gpio );
XIntc_Connect(&Intc, UART_INTR_ID,(XInterruptHandler)uart_handler,&Uart);
//外设中断 使能
//使能GPIO中断
XGpio_InterruptEnable(&Gpio, 1);
//使能GPIO全局中断
XGpio_InterruptGlobalEnable(&Gpio);
//使能串口中断
XUartLite_EnableInterrupt(&Uart);
//启用外设对应的中断向量
XIntc_Enable(&Intc,AXI_GPIO_INTR_ID);
XIntc_Enable(&Intc,UART_INTR_ID);
//启动中断控制器
XIntc_Start(&Intc, XIN_REAL_MODE);
//设置并打开中断异常处理
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(EXCEPTION_ID,
(Xil_ExceptionHandler)XIntc_InterruptHandler,&Intc);
Xil_ExceptionEnable();
for(;1;){
Xil_Out32(0x40000000 , 0xffff);
sleep(1);
Xil_Out32(0x40000000 , 0x0000);
sleep(1);
print("Hello\n\r");
xil_printf("word\n\r");
sleep(1);
}
cleanup_platform();
return 0;
}
void GpioHandler(void *CallbackRef){
XGpio *GpioPtr = (XGpio *)CallbackRef;
print("gpio interrupt\n\r");
XGpio_InterruptDisable(GpioPtr, 1); //关闭中断
XGpio_InterruptClear(GpioPtr, 1); //清除中断
XGpio_InterruptEnable(GpioPtr, 1); //使能中断
}
void uart_handler(void *CallbackRef)//中断处理函数
{
u8 Read_data;
u32 isr_status;
XUartLite *InstancePtr= (XUartLite *)CallbackRef;
//读取状态寄存器
isr_status = XUartLite_ReadReg(InstancePtr->RegBaseAddress ,
XUL_STATUS_REG_OFFSET);
if(isr_status & RX_NOEMPTY){ //接收 FIFO 中有数据
//读取数据
Read_data=XUartLite_ReadReg(InstancePtr->RegBaseAddress ,
XUL_RX_FIFO_OFFSET);
//发送数据
XUartLite_WriteReg(InstancePtr->RegBaseAddress ,
XUL_TX_FIFO_OFFSET, Read_data);
xil_printf("%x\n",Read_data);
print("\n\r");
}
print("uart interrupt\n\r");
}