STM32开关总中断
引用 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不常用的中断,如何添加, 比如timer10 timer11等
- RTC时钟和BKP的配置stm32
- stm32中使用cubemx配置freertos的信号量大小
- stm32-IIC读写EEPROM—时序说明
- stm32学习笔记——外部中断的使用
- 移植freertos到stm32 f103 的基本流程和总结
- (3)STM32使用HAL库操作外部中断——实战操作
- stm32中断初识与实践(下)
- STM32应用实例六:与MS5837压力传感器的I2C通讯
- STM32 一直进入串口接收中断
- stm32----定时器中断实现按键的长按,短按效果
- STM32开启和关闭总中断的方法
- stm32工程和算法分享(12)--精准闪烁灯[定时中断]
- stm32工程和算法分享(4)--单击按键之传统方式消抖
- 【正点原子STM32连载】 第二十八章 硬件随机数实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1
- 【正点原子STM32连载】第十三章 跑马灯实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1
- 【正点原子Linux连载】第十一章模仿STM32驱动开发格式实验--摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0
- STM32 硬件IIC OLED
- STM32 EXTI(外部中断)
- STM32震动感应灯
- STM32物联网项目-回调函数