我有一個ARM stm32f107芯片。我移植從IAR項目GCC的如何禁用/啓用stm32f107芯片上的中斷?
IAR提供以下功能啓用和禁用中斷:
#define __disable_interrupt() ...
#define __enable_interrupt() ...
如何啓用使用GCC我的芯片/禁止中斷?
我有一個ARM stm32f107芯片。我移植從IAR項目GCC的如何禁用/啓用stm32f107芯片上的中斷?
IAR提供以下功能啓用和禁用中斷:
#define __disable_interrupt() ...
#define __enable_interrupt() ...
如何啓用使用GCC我的芯片/禁止中斷?
我無法回答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
只需添加 - 以上是全局中斷啓用/禁用。要啓用/禁用單箇中斷,您需要爲CPU的中斷寄存器提供RTFM,並旋轉正確的位 - 同樣,在CF中,這意味着在中斷屏蔽寄存器中設置一位以禁用該源。在操作過程中使用上面的代碼是一個好主意,可以防止操作期間發生虛假中斷。 –
當爲STM32開發,RM0008是你最好的朋友。從第199頁的第10.2.4節:
要生成中斷,應該配置中斷線並啓用 。這是通過對 所需的邊沿檢測編程兩個觸發寄存器並通過使能中斷請求 向中斷屏蔽寄存器中的相應位寫入1來完成的。
所以你需要在適當的寄存器中設置合適的掩碼位。對於外部中斷,這是EXTI_IMR和EXTI_EMR寄存器。還有很多其他的。
的ARM Documentation說_enable_irq();
編譯爲「CPSIE我」,這意味着清除所有面具。另一方面,_disable_irq();
編譯爲設置掩碼。
解決這個問題的最簡單方法是反彙編IAR生成的代碼,從那裏您將看到實際發生的事情,然後您可以編寫可移植代碼而不是編譯器特定的代碼。 (答案見infocenter.arm.com的體系結構參考手冊和/或體系結構和內核的技術參考手冊) –