• [黑金笔记三]电平中断实验


      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,只要这两步我们就可以完成中断函数的处理了。废话少说,我们来点实际的吧,跟我来。

      中断分为两种,一种是电平(Level)中断,也就是高电平/低电平中断,还有一种就是沿中断,包括上升沿、下降沿。做过单片机的人应该都很熟悉,如果你想要实现沿中断,需要把红圈1(Synchronously capture)处选中,下面包括3种方式,大家可以根据自己的要求选择。完成上面工作以后,点击Finish,完成PIO构建。

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

              

    二、sopc.h程序解析

      

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

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

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

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

  • 相关阅读:
    转载:Python十分钟入门
    Think Python: How to Think Like a Computer Scientist
    LeetCode(34):搜索范围
    LeetCode(33):搜索旋转排序数组
    LeetCode(32):最长有效括号
    LeetCode(31): 下一个排列
    LeetCode(30):与所有单词相关联的字串
    LeetCode(29): 两数相除
    LeetCode(28): 实现strStr()
    LeetCode(27): 移除元素
  • 原文地址:https://www.cnblogs.com/spartan/p/2128446.html
Copyright © 2020-2023  润新知