打印

IAR for arm 中断处理写法

[复制链接]
7673|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
machunshui|  楼主 | 2009-10-15 09:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 machunshui 于 2009-10-15 11:14 编辑

IAR for arm 中断处理写法

方法1:

启动文件中:(默认启动文件也是这样)

        org    0x18
        ldr    pc,[pc,#-0xFF0]    ; 直接跳转到用户中断处理函数

直接写用户中断函数
        __irq __arm void Tmr0_IntOnMR0_isr(void)
          {
                    ............
                   }

           __irq __arm void Tmr1_IntOnMR0_isr(void)
          {
                    ............
                   }


方法2.

启动文件中:(默认启动文件也是这样)

        org    0x18
        ldr    pc,=irq_handler        ;跳转到公共中断处理函数,再分支到具体功能的中断处理函数中


        __irq __arm void irq_handler (void)        //公共中断处理函数,检查VICVectAddr是否为空
        {
            void (*interrupt_function)();
            unsigned int vector;

              vector = VICVectAddr;     // Get interrupt vector.
              interrupt_function = (void(*)())vector;
             if(interrupt_function != NULL)
              {
                interrupt_function();  // Call vectored interrupt function.
              }
              else
              {
                VICVectAddr = 0;      // Clear interrupt in VIC.
              }
        }


具体功能的中断处理函数
         void Tmr0_IntOnMR0_isr(void)
          {
                    ............
                   }

           void Tmr1_IntOnMR0_isr(void)
          {
                    ............
                   }


方法3.

        使用#pragma vector不管启动文件如何写法,

        #define IRQV            0x18
        #pragma vector=IRQV
        __irq __arm void irq_handler (void)
        {
        void (*interrupt_function)();
        unsigned int vector;

          vector = VICVectAddr;     // Get interrupt vector.
          interrupt_function = (void(*)())vector;
          if(interrupt_function != NULL)
          {
            interrupt_function();  // Call vectored interrupt function.
          }
          else
          {
            VICVectAddr = 0;      // Clear interrupt in VIC.
          }
        }

        具体功能的中断处理函数
         void Tmr0_IntOnMR0_isr(void)
          {
                    ............
                   }

           void Tmr1_IntOnMR0_isr(void)
          {
                    ............
                   }

相关帖子

沙发
arm_fan168| | 2009-10-15 09:42 | 只看该作者
第一种方法应该需要自己构造文字池吧,经常看到编译器自己生成的启动代码是第一种那样的。楼主的第一种方法写的肯定不全面,能否再补充下?

使用特权

评论回复
板凳
machunshui|  楼主 | 2009-10-15 09:47 | 只看该作者
不明白2楼说的什么构造文字池?
和中断有什么关系?

使用特权

评论回复
地板
machunshui|  楼主 | 2009-10-15 09:49 | 只看该作者
第一种方法本质就是跳转到VICVectAddr所指向的中断处理函数,

没有问题。

使用特权

评论回复
5
arm_fan168| | 2009-10-15 09:57 | 只看该作者
ldr    pc, [pc,#24]就能跳转到VICVectAddr所指向的中断处理函数? [pc,#24]这个位置存储的数据是什么啊就加载到PC了

使用特权

评论回复
6
machunshui|  楼主 | 2009-10-15 10:05 | 只看该作者
org    0x18
        ldr    pc,/*[pc,#24]*/ [pc,#-0xFF0]    ; 直接跳转到用户中断处理函数

[pc,#-0xFF0],正是VICVectAddr

使用特权

评论回复
7
arm_fan168| | 2009-10-15 11:03 | 只看该作者
VICVectAddr是不是指的是LPC2xxx系列MCU的地址为0xFFFFFF00的寄存器啊?[pc,#-0xFF0]怎么算出来的等于这个寄存器的地址?我这块一直弄不太明白,请楼主指教一下。另外,“ldr    pc,/*[pc,#24]*/ [pc,#-0xFF0]    ;”这个写法很让人费解啊,呵呵

使用特权

评论回复
8
machunshui|  楼主 | 2009-10-15 11:13 | 只看该作者
ldr    pc,/*[pc,#24]*/ [pc,#-0xFF0]
是直接copy的,是不好看。
应该去掉注释,写成 ldr    pc,[pc,#-0xFF0]。

org    0x18
        ldr    pc, [pc,#-0xFF0]    ; 直接跳转到用户中断处理函数

此时PC = 0x18+8 = 0x20

0x20 - 0xff0 = 0xFFFFF030

0xFFFFF030 正是 VICVectAddr

使用特权

评论回复
9
arm_fan168| | 2009-10-15 13:26 | 只看该作者
仔细研究了一下,原来LPC2xxx系列的VICVectAddr寄存器地址不都是0xFFFFF030,LPC24xx系列的VICVectAddr地址是0xFFFFFF00。

使用特权

评论回复
10
machunshui|  楼主 | 2009-10-15 15:09 | 只看该作者
LPC23XX,LPC24XX的VICVectAddr地址是0xFFFFFF00 ,

也没关系,用
  org 0x18
        LDR     PC, [PC, #-0x0120]  ; Vector from VicVectAddr

道理是一样的:
(0x18+0x08)-0x0120  =  0x20 - 0x0120 =  0xFFFFFF00

使用特权

评论回复
11
rose8421| | 2009-10-26 14:21 | 只看该作者
1# machunshui

问一下楼主,如何在IAR下写FIQ函数呢,是否可以按照方法2来写

使用特权

评论回复
12
machunshui|  楼主 | 2009-10-27 08:07 | 只看该作者
可以。
__irq __arm void fiq_handler (void)里面直接处理快速中断即可

使用特权

评论回复
13
desert_hawk| | 2009-10-27 08:54 | 只看该作者
FIQ中断在IAR编译器里得使用__fiq关键字,见“EWARM_CompilerReference.pdf”的149页:
“__fiq This keyword declares a fast interrupt function. All interrupt functions must be compiled in ARM mode; use either the __arm keyword or the #pragma
type_attribute=__arm directive to alter the default behavior if needed.
A function declared __fiq does not accept parameters and does not have a return value.
Example
__fiq __arm void interrupt_function(void);”

使用特权

评论回复
14
machunshui|  楼主 | 2009-10-27 12:14 | 只看该作者
不好意思,关键字应该是__fiq。

__fiq__arm void fiq_handler (void)里面直接处理快速中断即可

使用特权

评论回复
15
xinjie1023| | 2009-11-15 14:17 | 只看该作者
学习,与ADS差不多

使用特权

评论回复
16
gtdnegyf01| | 2014-6-27 09:53 | 只看该作者
楼主是大神级别,膜拜!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

153

主题

3224

帖子

4

粉丝