如何在stm32f107芯片上禁用/启用中断?

时间:2012-12-04 22:26:41

标签: c gcc assembly embedded iar

我有一个ARM stm32f107芯片。我正在将项目从IAR移植到GCC

IAR提供以下功能来启用和禁用中断:

#define __disable_interrupt() ...
#define __enable_interrupt() ...

如何使用GCC启用/禁用芯片中断?

3 个答案:

答案 0 :(得分:4)

在为STM32开发时,RM0008是您最好的朋友。从第199页的第10.2.4节:

  

要生成中断,应配置中断线   启用。这是通过编程两个触发寄存器来完成的   期望的边沿检测以及通过启用中断请求   将“1”写入中断屏蔽寄存器中的相应位。

因此,您需要在适当的寄存器中设置适当的掩码位。对于外部中断,这是EXTI_IMR和EXTI_EMR寄存器。还有很多其他的。

EXTI registers

答案 1 :(得分:2)

我不能回答ARM,但Coldfire中的相同功能归结为设置/清除CPU中的中断优先级屏蔽寄存器。将其设置为最高编号会禁用/忽略所有但不可屏蔽的,将其设置为0将启用所有(YMMV)。

值得注意的是,当“禁用”时回读值并在“启用”时确保堆叠中断不会相互破坏是很方便的:

ipl = DisableInts(); // Remember what the IPL was
<"Risky" code happens here>
EnableInts(ipl); // Restore value

这在使用中断掩码时很有用,这可能会导致虚假中断,或者做一些不应该中断的事情。

功能如下:

uint8 DisableInts(void)
{
    return(asm_set_ipl(7));
}

uint8 EnableInts(uint8 ipl)
{
    return(asm_set_ipl(ipl));
}

两者都映射到此asm:

asm_set_ipl:
_asm_set_ipl:
/* Modified for CW7.2! */
    link    A6,#-8
    movem.l D6-D7,(SP)

    move.l  D0,D6           /* save argument                 */

    move.w  SR,D7           /* current sr                    */

    move.l  D7,D0           /* prepare return value          */
    andi.l  #0x0700,D0      /* mask out IPL                  */
    lsr.l   #8,D0           /* IPL                           */

    andi.l  #0x07,D6        /* least significant three bits  */
    lsl.l   #8,D6           /* move over to make mask        */

    andi.l  #0x0000F8FF,D7  /* zero out current IPL          */
    or.l    D6,D7           /* place new IPL in sr           */
    move.w  D7,SR

    movem.l (SP),D6-D7
    //lea     8(SP),SP
    unlk    A6
    rts

答案 2 :(得分:0)

ARM Documentation表示_enable_irq();编译为“CPSIE I”,即“清除所有面具”。另一方面,_disable_irq();编译为Set Mask。