赞
踩
中断是一种当满足要求的突发事件发生时通知处理器进行处理的信号。中断可以由硬件处理单元和外部设备产生,也可以由软件本身产生。
对硬件来说,中断信号是一个由某个处理单元产生的异步信号,用来引起处理器的注意。
对软件来说,中断还是一种异步事件,用来通知处理器需要改变代码的执行,不过轮询所产生的中断的过程是同步的。
AXI Interrupt Controller,为中断控制器IP,能将外围的多个中断输入,集中到单个中断输出,再将中断传输给系统处理器。AXI 规范的从属接口访问用于检查,启用和确认中断的寄存器。
AXI INTC(中断控制器)具有以下特点:
下图为 AXI INTC IP 核的顶层框图。 AXI INTC IP 核主要功能就是接收外部输入的中断信号,检测到中断后,输出一个中断请求信号,而且处理系统可以通过 AXI 接口对 AXI INTC IP 核进行配置。
下面简单介绍 AXI INTC IP 核的主要模块:
Irq Gen(Interrupt Generation 即中断生成)模块具有以下功能:
1、系统框图。
系统框图中,按键 KEY 作为 AXI GPIO 的输入, LED 作为 AXI GPIO 的输出。当 AXI GPIO 检测到按键状态发生变化时, AXI GPIO 就会产生一个中断信号传入中断控制器(AXI Interrupt Controller),中断控制器生成中断输出信号,传入 MicroBlaze 处理器, MicroBlaze 处理器通过接收到的中断信号控制 LED。中断控制器通过 AXI Interconnect 与 MicroBlaze 互联, MicroBlaze 可以通过 AXI 接口对中断控制器进行配置。
2、添加一个gpio模块。
注意,需要在左下角使能下gpio的中断。
3、添加INTC的IP模块。
Number of Peripheral Interrupts(Auto):外围中断设备数量。此选项允许选择外围中断输入的数量。在 IP Integrator 中,此值由连接中断信号的数量自动确定。
Enable Fast Interrupt Logic:使能快速中断逻辑。此选项使 AXI INTC 能够在快速中断模式下工作。在这种模式下,AXI INTC 使用 interrupt_address 信号提供中断向量地址,处理器通过 processor_ack 信号确认中断。当选择单信号中断输出时,不可用快速中断模式。。
Peripheral Interrupts Type:外部设备中断类型,该选项用于设置输入的中断信号。
Interrupts type - Edge or Level:中断类型-边缘或电平。此选项用于将输入中断设置为边缘或电平类型。0 表示电平类型, 1 表示边缘类型。
Level type - High or Low:电平类型-高电平或低电平。0 表示低电平,1 表示高电平。
Edge type - Rising or Falling:边缘类型-上升沿或下降沿。0 表示下降沿,1 表示上升沿。
需要注意的是 Interrupts type - Edge or Level、 Level type - High or Low 和 Edge type - Rising or Falling 的值通常由连接的中断信号自动确定,但在必要时也可以手动设置。因此本实验中我们没有对 AXI GPIO IP 核进行配置。
Processor Interrupt Type and Connection:处理器中断类型和连接。该目录用于设置中断控制器的输出信号。在该目录可以设置中断类型为电平或边缘类型,以及触发方式。 Interrupt Output Connection(中断输出连接)选项用于设置中断控制器输出的中断信号是单信号还是总线类型的信号。
将 AXI Interrupt Controller 的输出信号“interrupt”接口与 MicroBlaze 的“INTERRUPT”接口相连,将新添加的 AXI GPIO 的“ip2intc_irpt”接口与 AXI Interrupt Controller 的 intr[0:0]接口相连。
4、系统连接。
双击 AXI Interrupt Controller IP 核打开配置页面我们可以看到,AXI Interrupt Controller IP 核的中断输入已经设置为了高电平敏感,这是因为 AXI GPIO 产生的中断信号是一个高电平信号。
5、SDK进行代码解读。
#include "xparameters.h" #include "xintc.h" #include "xgpio.h" #include "sleep.h" #define KEY_DEV_ID XPAR_AXI_GPIO_1_DEVICE_ID //按键 AXI GPIO ID #define LED_DEV_ID XPAR_AXI_GPIO_0_DEVICE_ID //LED AXI GPIO ID #define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID //中断控制器ID // 中断异常ID是一个适配所有处理器的宏定义 #define EXCEPTION_ID XIL_EXCEPTION_ID_INT //中断异常ID // 中断源就是指连接按键的 AXI GPIO 输出到中断控制器的中断信号 #define AXI_GPIO_INTR_ID XPAR_INTC_0_GPIO_1_VEC_ID //AXI GPIO中断ID static XIntc Intc; //中断控制器实例 static XGpio KEY_Gpio; //GPIO中断实例 按键 static XGpio LED_Gpio; //GPIO实例 int led_value; //LED值 int key_value; //按键值 int Intr_times = 0; //有效中断计数 int key_intr_flag = 0; //中断标志 void GpioHandler(void *CallbackRef); // 在主函数部分可以分为器件初始化、设置输入输出、设置中断系统和中断异常处理四部分 int main(){ xil_printf("AXI GPIO INTERRUPT TEST!\r\n"); //AXI_GPIO器件初始化 XGpio_Initialize(&KEY_Gpio, KEY_DEV_ID); XGpio_Initialize(&LED_Gpio, LED_DEV_ID); //为指定的GPIO信道设置所有独立信号的输入/输出方向 XGpio_SetDataDirection(&LED_Gpio, 1, 0); //设置LED初始值 XGpio_DiscreteWrite(&LED_Gpio, 1, 0x0f); XGpio_SetDataDirection(&KEY_Gpio, 1, 1); //初始化中断控制器 XIntc_Initialize(&Intc, INTC_DEVICE_ID); //关联中断ID和中断服务函数 //中断服务函数是需要我们自己编写的, 用于响应和处理 AXI GPIO 中断的函数 XIntc_Connect(&Intc,AXI_GPIO_INTR_ID,(Xil_ExceptionHandler)GpioHandler,&KEY_Gpio ); //使能中断 XGpio_InterruptEnable(&KEY_Gpio, 1); //使能全局中断 XGpio_InterruptGlobalEnable(&KEY_Gpio); //在中断控制器上启用中断向量 XIntc_Enable(&Intc,AXI_GPIO_INTR_ID); //启动中断控制器 XIntc_Start(&Intc, XIN_REAL_MODE); //设置并打开中断异常处理 Xil_ExceptionInit(); Xil_ExceptionRegisterHandler(EXCEPTION_ID, (Xil_ExceptionHandler)XIntc_InterruptHandler,&Intc); Xil_ExceptionEnable(); /* 在 while 语句部分,当检测到中断标志信号 key_intr_flag 拉高后,读取按键对应通道的值(key_value), 当 key_value 为 0 时说明按键按下,此时中断计数 Intr_times 加 1;代码 55 到 62 行是根据 Intr_times 的值给 led_value 的赋值,由于开发板上只有四个 LED,所以我们将 Intr_times 的范围约束在 0 到 3 之间,如代码 66 行所示。当检测到按键按下时,就点亮 LED 灯并打印 Intr_times 的值,延迟 1 秒进行消抖,最后将中断 标志信号 key_intr_flag 清零,等待下次中断到来。 */ while(1){ if(key_intr_flag){ //检测中断标志信号有效 key_value = XGpio_DiscreteRead(&KEY_Gpio, 1); //读取按键值 if(key_value == 0){ //检测按键是否按下 if(Intr_times == 0) //根据有效中断数点亮LED led_value = 0x01; else if(Intr_times == 1) led_value = 0x02; else if(Intr_times == 2) led_value = 0x04; else led_value = 0x08; //按键按下后点亮对应LED灯 XGpio_DiscreteWrite(&LED_Gpio, 1, led_value); xil_printf("i = %d\r\n",Intr_times); //打印当前的Intr_times Intr_times = (Intr_times + 1)%4; //将计数值约束在0到3之间 //延迟1秒 sleep(1); } key_intr_flag = 0; //中断标志清零 } } return 0; } void GpioHandler(void *CallbackRef){ XGpio *GpioPtr = (XGpio *)CallbackRef; key_intr_flag = 1; //接收到中断,标志信号拉高 XGpio_InterruptDisable(GpioPtr, 1); //关闭中断 XGpio_InterruptClear(GpioPtr, 1); //清除中断 XGpio_InterruptEnable(GpioPtr, 1); //使能中断 }
1、串口打印。
2、每按一下按键,LED灯也会发生变化。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。