原创 (转载)Cortex-M0/M0+屏蔽优先级低于BASEPRI设定的中断

2020-7-23 10:44 2444 24 24 分类: MCU/ 嵌入式 文集: STM32应用

Cortex-M3/M4/M7有BASEPRI特殊功能寄存器可以屏蔽优先级低于BASEPRI设定值的中断,但Cortex-M0/M0+没有BASEPRI寄存器,不过仍然可以实现相识的功能。

mingdu.zheng at gmail dot com
http://blog.csdn.net/zoomdy/article/details/79316998

实现方法

虽然Cortex-M0/M0+没有BASEPRI寄存器,但是仍然有NVIC,而且M0/M0+最多只有32个中断源,因此操作一个寄存器就可以影响所有中断源。假设使用了8个中断源,其中1、17中断优先级值为0x00(最高优先级),18、19中断优先级值为0x40,14、25中断优先级值为0x80,8、31中断优先级值为0xC0(最低优先级)。

中断号优先级值优先级
10x00最高
170x00最高
180x40
190x40
140x80
250x80
80xc0最低
310xc0最低
1、定义优先级分组宏
#define BASEPRI_0x40 ((1 << 1) | (1 << 17)) 
#define BASEPRI_0x80 (BASEPRI_0x40 | (1 << 18) | (1 << 19)) 
#define BASEPRI_0xc0 (BASEPRI_0x80 | (1 << 14) | (1 << 25))
#define BASEPRI_0x00 (BASEPRI_0xc0 | (1 << 8) | (1 << 31))
2、定义中断使能控制宏
// 仅使能优先级值小于0x40的中断源(最高优先级中断源) 
// 相当于 BASEPRI = 0x40
#define SET_BASEPRI_40 NVIC->ICER = 0xffffffff;  NVIC->ISER = BASEPRI_0x40

// 使能优先级值小于0x80的中断源
/ 相当于 BASEPRI = 0x80 
#define SET_BASEPRI_80 NVIC->ICER = 0xffffffff; NVIC->ISER = BASEPRI_0x80

// 使能优先级值小于0xc0的中断源 
// 相当于 BASEPRI = 0xc0 
#define SET_BASEPRI_C0 NVIC->ICER = 0xffffffff; NVIC->ISER = BASEPRI_0xc0

// 使能所有中断源 
// 相当于 BASEPRI = 0x00 
#define SET_BASEPRI_00 NVIC->ICER = 0xffffffff; NVIC->ISER = BASEPRI_0xff

3、使用
// 这里只能使能最高优先级 
SET_BASEPRI_40;
 ... 
// 现在可以使能全部中断了
SET_BASEPRI_00; 
... 
// 就是这样用

4、优化

封装成和CMSIS-CORE API一样的实现,这样看起来就像真的在操作BASEPRI了。

static inline void __set_BASEPRI(uint32_t value)
{
    if(value == 0) {
        SET_BASEPRI_00;
    } else if(value <= 0x40) {
        SET_BASEPRI_40;
    } else if(vlaue <= 0x80) {
        SET_BASEPRI_80;
    } else {
        SET_BASEPRI_c0;
    } 
}
缺陷

SVCall、PendSV和SysTick中断的使能不是NVIC_ISER控制的,因此这里的方法没有办法处理这三个中断。

文章评论0条评论)

登录后参与讨论
我要评论
0
24
关闭 站长推荐上一条 /2 下一条