【stm32f0】stm32 总中断的打开与关闭

原文:https://blog.csdn.net/u014647208/article/details/77498863
https://blog.csdn.net/sagitta_zl/article/details/51318507

问题: 对于基于ARM Cortex M0内核的STM32芯片各类应用开发时,有的时候需要进行总的中断的开、关处理,那就究竟有没有开、关总的中断的函数或者指令呢?

回答: 随着Cortex Mn各种内核的MCU的芯片越来越多和相关编译工具的升级换代,编译工具在有关内核指令操作的文档安排以及函数书写等方面可能发生了细微的变化。所以即使用过STM32 F1系列产品的工程师,在使用晚推出的STM32 F0芯片开发时,发现那些跟内核操作有关的指令或函数不知道哪里去找了。以STM32各系列的标准固件库为例,与内核相关的指令及函数都可以在…\libraries\cmsis…后面目录的相关文件里找到。于不同系列的标准库中对应的子目录以及相关文件名会略微有差异。
一般来讲我们是不需要做总的中断的关闭操作,或许个别情况真的需要。当然也不排除部分人出于之前使用MCU开发习惯或者好奇怎么用。
对于开、关STM32芯片总的中断,是针对ARM CortexM内核的操作指令。在各类的ARM内核的编程手册上一定可以找到,但是STM32芯片相关手册上是找不到的。开、关总中断的汇编指令分别就是CPSIE i、CPSID i,对于各个ARM Cortex系列MCU芯片来说,都是一样的,操作中断屏蔽寄存器。

CPSID i; // Disable all interrupts except NMI(includes a non-maskable interrupt).set PRIMASK
CPSIE i; // Enable interrupts.clear PRIMASK

CPS(Change Processor State)改变的是PRIMASK(Interrupt mask register)寄存器值。CPSID通过PRIMASK置1中断disable,CPSID通过PRIMASK清0操作中断enable。
内在函数 操作码 PRIMASK FAULTMASK
__enable_irq CPSIE i 0
__disable_irq CPSIE i 1
__enable_fiq CPSIE i 0
__disable_fiq CPSIE i 1

(PRIMASK这个寄存器只有一个位,置1后,将关闭所有可屏蔽中断的异常,只剩NMI和硬fault,默认值为0;FAULTMASK这个寄存器也只有一位,置1后,屏蔽除NMI外的所有异常(包括硬fault),默认值为0 。PS:BASEPRI这个寄存器有9位,它定义了被屏蔽优先级的阈值;当它被设定为某个值后,所有优先级号大于等于此值得中断都被关闭,若设为0,则不关闭任何中断,默认值为0)

PRIMASK 操作指令
MRS R0, PRIMASK ; R0=PRIMASK
MSR PRIMASK, R0 ; PRIMASK=R0
CPSID I ; PRIMASK=0
CPSIE I ; PRIMASK=1

FAULTMASK 操作指令
MRS R0, FAULTMASK ; R0=FAULTMASK
MSR FAULTMASK, R0 ; FAULTMASK=R0
CPSID F ; FAULTMASK=0
CPSIE F ; FAULTMASK=1

BASEPRI 操作指令
MRS R0, BASEPRI ; R0=BASEPRI
MSR BASEPRI, R0 ; BASEPRI=R0

目前各编译工具都把与内核相关ARM指令根据指令功能将其中某一条或几条汇编指令封装为C函数,函数名相对更为直观、好记,方便用户需要时拿来使用。比方在ARM MDK环境下,上面两个开关总中断的指令封装成如下2个内嵌函数。

关闭总中断的指令函数:
attribute( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
{
__ASM volatile (“cpsid i” : : : “memory”);
}
打开总中断的指令函数:
attribute( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
{
__ASM volatile (“cpsie i” : : : “memory”);
}

需要关闭总中断时,用户代码里直接放置__disable_irq()
需要开启总的中断时,用户代码里直接放置__enable_irq()

你可能感兴趣的:(stm32)