引用 http://www.amobbs.com/forum.php?mod=viewthread&tid=5397451

在 STM32/Cortex-M3 中是通过改变 CPU 的当前优先级来允许或禁止中断。
   
PRIMASK 位:只允许 NMI 和 hard  fault 异常,其他中断/  异常都被屏蔽(当前 CPU 优先级=0)。
  
FAULTMASK 位:只允许 NMI,其他所有中断/异常都被屏蔽(当前 CPU 优先级=-1)。

在 STM32 固件库中(stm32f10x_nvic.c 和 stm32f10x_nvic.h) 定义了四个函数操作 PRIMASK 位和

FAULTMASK 位,改变 CPU 的当前优先级,从而达到控制所有中断的目的。

下面两个函数等效于关闭总中断:  
void NVIC_SETPRIMASK(void);   
void NVIC_SETFAULTMASK(void);

下面两个函数等效于开放总中断:  
void NVIC_RESETPRIMASK(void);   
void NVIC_RESETFAULTMASK(void);

上面两组函数要成对使用,不能交叉使用。

例如:

第一种方法:  
NVIC_SETPRIMASK();         //关闭总中断  
NVIC_RESETPRIMASK();       //开放总中断

第二种方法:  
NVIC_SETFAULTMASK();      //关闭总中断  
NVIC_RESETFAULTMASK();    //开放总中断

常常使用

NVIC_SETPRIMASK();                       // Disable Interrupts  
NVIC_RESETPRIMASK();                     // Enable Interrupts

1 在CORE_CM3.H中根据不同编译器有不同的语句

#if defined ( __CC_ARM   ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */

#define __enable_fault_irq                __enable_fiq
#define __disable_fault_irq               __disable_fiq

#define __NOP                             __nop
#define __WFI                             __wfi

/*IAR ICC Compiler*/

__disable_irq() ;
__enable_irq() ;

/*IAR ICC Compiler*/

#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */

static __INLINE void __enable_irq()               { __ASM volatile ("cpsie i"); }

二 其它

__asm void INT_DIS(void)
{
  CPSID f
  BX r14 /*LR*/

}
/*************开启中断************************/
__asm void INT_EN(void)
{
  CPSIE f
  BX r14/*LR*/
}

cpsid i 关中断,但是不关硬fault 和NMI
cpsid f 连硬fault也关了,只剩下NMI/*MCU上电初始化读取参数期间尝试关闭ALL中断,所以用的F,读取参数完成后再开启中断,进入主程序不用再用F中断*/

MDK的话可以直接书写(好像不对这是对应IAR):
__disable_irq();  相当于 CPSID I
__enable_irq();   相当于 CPSIE I
__disable_fiq();  相当于 CPSID F
__enable_fiq();   相当于 CPSIE F

其实最正规的做法是用CMSIS库里面的(跨平台)
void __set_FAULTMASK(uint32_t faultMask);
void __set_PRIMASK(uint32_t priMask);

STM32在使用时有时需要禁用全局中断,比如MCU在升级过程中需禁用外部中断,防止升级过程中外部中断触发导致升级失败。
ARM MDK中提供了如下两个接口来禁用和开启总中断:
__disable_irq();   // 关闭总中断
__enable_irq();    // 开启总中断

测试发现这样一个问题,在关闭总中断后,如果有中断触发,虽然此时不会引发中断,但在调用__enable_irq()开启总中断后,MCU会立即处理之前触发的中断。这说明__disable_irq()只是禁止CPU去响应中断,没有真正的去屏蔽中断的触发,中断发生后,相应的寄存器会将中断标志置位,在__enable_irq()开启中断后,由于相应的中断标志没有清空,因而还会触发中断。所以要想禁止所有中断,必须对逐个模块的中断进行Disable操作,由于每个模块中断源有很多,对逐个中断Disable的话比较复杂,较为简单的方法是通过XXX_ClearITPendingBit()清除中断标志或者直接通过XXX_DeInit()来清除寄存器的状态。这样在__enable_irq()开启总中断后,MCU就不会响应之前触发的中断了。

软件重启MCU与半主机调试
/* ##################################    Reset function  ############################################ */

/**
 * @brief  Initiate a system reset request.
 *
 * Initiate a system reset request to reset the MCU
 */
static __INLINE void NVIC_SystemReset(void)

/* ##################################### Debug In/Output function ########################################### */
static __INLINE void __disable_irq()              { __ASM volatile ("cpsid i"); }

static __INLINE void __enable_fault_irq()         { __ASM volatile ("cpsie f"); }
static __INLINE void __disable_fault_irq()        { __ASM volatile ("cpsid f"); }

在NVIC中

STM32开关总中断的更多相关文章

  1. 【转】STM32 - 程序跳转、中断、开关总中断

    程序跳转注意: 1.如果跳转之前的程序A里有些中断没有关,在跳转之后程序B的中断触发,但程序B里没有定义中断响应函数,找不到地址会导致死机. 2.程序跳转前关总中断,程序跳转后开总中断(关总中断,只是 ...

  2. STM32关总中断的语句

    __set_PRIMASK();//关总中断 /************ **********/ __set_PRIMASK();//开总中断

  3. STM32 禁用或开启总中断

    今天把之前自己的一些在中断方面所产生的疑惑把具体的解决办法给大家分享一下,希望能够帮到大家. STM32在使用时有时需要禁用全局中断,比如MCU在升级过程中需禁用外部中断,防止升级过程中外部中断触发导 ...

  4. 编写一个stm32 svc关中断函数

    做到了让stm32触发svc中断并传递进去参数然后切换到handler模式并修改特殊寄存器的值,从而达到关中断,但是其实这个程序直接就是特权级,故不进入handler模式也可以修改特殊寄存器..... ...

  5. STM32的外部中断配置及使用

    STM32的外部中断配置及使用 配置1:GPIO: 配置外部中断为输入模式: 配置2:EXTI: 配置外部中断线和触发模式: 配置3:NVIC: 配置外部中断源和中断优先级: 需要注意的是:RCC_A ...

  6. STM32的RTC中断标志只能手动清除

    背景: 最近在做一个stm32的项目,其中用到RTC的实时时钟功能.时钟源采用外部32.768K晶振,时钟预分频设置为32767,目的是为了产生1秒的中断,然后在中断处理函数中更新实时年月日时分秒. ...

  7. STM32的USART中断死循环,形成死机。

    作者:观海  QQ:531622 直接说重点:我用的是 STM32F103 芯片 USART2_IRQHandler 总是中断,程序死循环. 1.出现问题: 原程序的中断处理程序是: void USA ...

  8. STM32 GPIO外部中断总结

    一.STM32中断分组: STM32 的每一个GPIO都能配置成一个外部中断触发源,这点也是 STM32 的强大之处.STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组,比如:PA0,PB ...

  9. STM32之外部中断控制

    一.STM32外部中断 1.STM32外部中断结构图 如上图所示:主要包括四个环节,GPIO.AFIO.EXTI.NVIC.以STM32F103VE(100脚)为例说明硬件模块的数量: GPIO:   ...

随机推荐

  1. Listen81

    Nut-Cracking Chimps Demonstrate Cultural Differences One family generally dines on Chinese takeout w ...

  2. 1111 Online Map (30)(30 分)

    Input our current position and a destination, an online map can recommend several paths. Now your jo ...

  3. boobmarklet

    bookmarklet ,一般都称呼为小书签.它是一段 JavaScript 脚本,一般网络上的小书签都是一个链接,它的安装非常简单,只需要把链接拖到你的收藏夹里. 利用它,可以实现一些页面优化.性能 ...

  4. python--面向对象(最全讲解)

    http://www.cnblogs.com/Eva-J/articles/7293890.html 阅读目录 楔子 面向过程vs面向对象 初识面向对象 类的相关知识 对象的相关知识 对象之间的交互 ...

  5. linux正则表达式基础

    linux中awk,sed,grep等 命令使用区别正则表达式基础 在最简单的情况下,一个正则表达式看上去就是一个普通的查找串.例如,正则表达式"testing"中没有包含任何元字 ...

  6. phpstrom添加monokai-sublime主题

    phpstrom默认的主题看起来不是特别舒服,sublime的主题却相当养眼,搜索之后,大为惊喜. 下载地址:https://github.com/sumiaowen/jetbrains-monoka ...

  7. 正则表达式/i,/g,/ig,/gi,/m的含义

    正则表达式中/i,/g,/ig,/gi,/m的区别和含义 /i (忽略大小写)/g (全文查找出现的所有匹配字符)/m (多行查找)/gi(全文查找.忽略大小写)/ig(全文查找.忽略大小写)

  8. Oracle(1)

    PL/SQL -- 表示注释 ||''|| 拼接字符串 别名 null值和所有数值计算结果都为null 空置值转换函数: nvl(列,所要转换的数) in 相当于用 or 链接. not in 相当于 ...

  9. 2014年第五届蓝桥杯国赛 Log大侠(区间合并+Java递归效率分析)

    1678: Log大侠 java 时间限制: 2 Sec  内存限制: 256 MB提交: 20  解决: 1 题目描述     atm参加了速算训练班,经过刻苦修炼,对以2为底的对数算得飞快,人称L ...

  10. 327. Count of Range Sum(inplace_marge)

    Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Ra ...