ISR(Interrupt Service Routine)中断服务函数是为硬件中断服务的子程序。NIOS II处理器支持32个硬件中断,每一个使能了的硬件中断都应该有一个ISR与之对应。中断发生时,硬件中断处理器会根据检测到的有效中断级别,调用相应的ISR为其进行中断服务。

要完成硬件中断工作,我们需要做两件事:

      第一, 注册中断函数ISR,它的函数原型如下所示:

int alt_irq_register(alt_u32 id, void* context, void(*handler) (void*,alt_u32));

  id:中断优先级,即所注册的ISR是为哪个中断优先级的中断服务的。中断优先级在SOPC Builder中分配的,在第一节中我们提起过,不知道大家是否记得,我们来回忆一下,如下图所示,通过这一步我们来完成中断的自动分配

context,为所注册的ISR传递参数,可以是NULL;

   handler,中断服务函数ISR的指针。

返回值是0时,表示中断注册成功;返回为负数,表明中断注册失败。

如果handler不是NULL,则该优先级中断在注册成功后将自动使能,也即是说,只要我们在handler处有相应的ISR,我们就不需要再进行使能处理了。说完第一,我们来说说第二。

      第二, 编写ISR函数,这个函数有我们自己来写,而不是HAL系统提供的。它跟一般的函数定义没什么区别,只是对ISR的函数原型有特定的要求:

void ISR_handler(void* context, alt_u32 id);

context: 传给ISR的形参,可以是NULL;

id: 中断优先级。

      OK,只要这两步我们就可以完成中断函数的处理了。废话少说,我们来点实际的吧,跟我来。

想要实现沿中断,需要把红圈1(Synchronously capture)处选中,下面包括3种方式,大家可以根据自己的要求选择。完成上面工作以后,点击Finish,完成PIO构建。

NIOS 中断的好处 nios中断优先级_初始化

图中有一个地方需要注意,由于电平中断时,NIOS只对高电平敏感,所以如果想实现低电平敏感需要加一个非门

NIOS 中断的好处 nios中断优先级_初始化_02

          

NIOS 中断的好处 nios中断优先级_NIOS 中断的好处_03

二、sopc.h程序解析

  

NIOS 中断的好处 nios中断优先级_主函数_04

  我们对main.c函数进行更改,整体程序如下图所示,这个程序没有对按键进行防抖处理,只是为了展示外部中断处理的操作过程,如想作为项目中应用必须加入按键防抖处理,在此不具体说明。这个函数通过外部按键来产生中断,因为我们设置的是低电平产生中断,所以当按键按下时,就会产生了一个低电平,这时就会进入中断函数。在中断函数中,我们对key_flag进行取反。而在主函数中,我们不断地进行查询,当key_flag为1时,LED->DATA置1,也就是让外部发光二极管亮;当key_flag为0时,LED->DATA置0,这时,发光二极管不亮。

NIOS 中断的好处 nios中断优先级_主函数_05

使能中断位,上一节我已经讲过了,PIO模块对应的结构体中的INTERRUPT_MASK是中断控制寄存器的内存映射,当该位置1时,允许中断,否则,禁止中断。再说红圈2处的语句,我们前面已经见过这个语句了,用它来完成中断的注册,KEY_IRQ来自system.h,ISR_key是ISR函数。用return返回为了在主函数中判断注册是否成功,如果成功返回0,非0表示注册失败。

NIOS 中断的好处 nios中断优先级_主函数_06

  下面来看看ISR_key函数,如下图所示,只有一条语句,其中,key_flag是一个全局变量,这条语句的意思,每进一次中断,就将key_flag取反。

NIOS 中断的好处 nios中断优先级_初始化_07

  下面是主函数,红圈1处部分是判断初始化是否成功,如果init_key()函数返回值是0,说明注册成功,打印register successfully!\n,可以再观察栏中看到它,否则打印Error: register failure!\n。红圈2处是判断标志位key_flag,如果它为1,则对LED->DATA 置1,也就是让让对应的LED亮,否则LED不亮。

NIOS 中断的好处 nios中断优先级_主函数_08