历史上的今天
今天是:2025年03月24日(星期一)
2019年03月24日 | STM32 NVIC简化理解
2019-03-24 来源:eefocus
一、STM32 (Cortex-M3) 中的优先级概念
STM32(Cortex-M3)中有两个优先级的概念:抢占式优先级和副优先级,也把响应优先级称作“亚优先级”或“响应优先级”,每个中断源都需要被指定这两种优先级。(数字小的优先级高)
1. 何为抢占式优先级(pre-emption priority)
抢占式优先级的中断事件会打断当前的主程序/中断程序运行—抢断式优先响应(后者俗称中断嵌套)。
2. 何为副优先级(subpriority)
在抢占式优先级相同的情况下,高的副优先级的中断优先被响应;
在抢占式优先级相同的情况下,如果有低副优先级中断正在执行, 高副优先级的中断要等待已被响应的低副优先级中断执行结束后才能得到响应——非抢断式响应不能嵌套。
二、Cortex-M3中对中断优先级的定义(先看下面标题三的内容)
既然每个中断源都需要被指定这两种优先级,就需要有相应的寄存器位记录每个中断的优先级;在Cortex-M3中定义了8个比特位用于设置中断源的优先级,这8个比特位可以有8种分配方式,如下:
所有8位用于指定响应优先级
最高1位用于指定抢占式优先级,最低7位用于指定响应优先级
最高2位用于指定抢占式优先级,最低6位用于指定响应优先级
最高3位用于指定抢占式优先级,最低5位用于指定响应优先级
最高4位用于指定抢占式优先级,最低4位用于指定响应优先级
最高5位用于指定抢占式优先级,最低3位用于指定响应优先级
最高6位用于指定抢占式优先级,最低2位用于指定响应优先级
最高7位用于指定抢占式优先级,最低1位用于指定响应优先级
这就是优先级分组的概念。
三、stm32中对中断优先级的定义
Cortex-M3允许具有较少中断源时使用较少的寄存器位指定中断源的优先级,因此STM32把指定中断优先级的寄存器位减少到4位,这4个寄存器位的分组方式如下:
第0组:所有4位用于指定副优先级(可以设置16级)
第1组:最高1位用于指定抢占式优先级(2级),最低3位用于指定副优先级(8级)
第2组:最高2位用于指定抢占式优先级(4级),最低2位用于指定副优先级(4级)
第3组:最高3位用于指定抢占式优先级(8级),最低1位用于指定副优先级(2级)
第4组:所有4位用于指定抢占式优先级(16级)
四、举例
接下来就是指定中断源的优先级,下面以一个简单的例子说明如何指定中断源的抢占式优先级和副优先级:
// 选择使用优先级分组第1组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
// 使能EXTI0中断
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 指定抢占式优先级别1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定副优先级别0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
要注意的几点是:
1、在一个系统中,通常只使用上面5种分配情况的一种。
2、 如果指定的抢占式优先级别或响应优先级别超出了选定的优先级分组所限定的范围,将可能得到意想不到的结果。
3、 如果某个中断源被指定为某个抢占式优先级别,又没有其它中断源处于同一个抢占式优先级别,则可以为这个中断源指定任意有效的响应优先级别。
五、补充:开关总中断
在STM32/Cortex-M3中是通过改变CPU的当前优先级来允许或禁止中断。
PRIMASK位:只允许NMI和hard fault异常,其他中断/异常都被屏蔽(当前CPU优先级=0)。
FAULTMASK位:只允许NMI,其他所有中断/异常都被屏蔽(当前CPU优先级=-1)。
在STM32固件库中(stm32f10x_nvic.c和stm32f10x_nvic.h) 定义了四个函数操作PRIMASK位和FAULTMASK位,改变CPU的当前优先级,从而达到控制所有中断的目的。
例如:
第一种方法:
NVIC_SETPRIMASK(); //关闭总中断
NVIC_RESETPRIMASK();//开放总中断
第二种方法:
NVIC_SETFAULTMASK(); //关闭总中断
NVIC_RESETFAULTMASK();//开放总中断
常常使用:
NVIC_SETPRIMASK(); // Disable Interrupts
NVIC_RESETPRIMASK(); // Enable Interrupts
可以用:
#define CLI() __set_PRIMASK(1)
#define SEI() __set_PRIMASK(0)
来实现开关总中断的功能。
史海拾趣
|
@@MAX7132学习板电路图完整版 https://bbs.eeworld.com.cn/thread-50800-1-1.html@@ @@EP2C学习板原理图 https://bbs.eeworld.com.cn/thread-72861-1-4.html@@ @@ ...… 查看全部问答> |
|
【转】电子设计竞赛经验汇总(11楼以后更新获奖团队的成功感言) 本帖最后由 paulhyde 于 2014-9-15 03:22 编辑 竞赛时应该注意的问题: 1、软件与硬件电路最好是同时做,不要前几天都在搞软件,等到最后才来焊板,到时如果出问题都没时间改了,我参加时就是遇到了这种情况。要么也可以在面包板实践下,有人可 ...… 查看全部问答> |
|
再好几个论坛发帖,没人鸟窝 首先说明一下问题 我用的是ad 08 在画一个BGA封装的FPGA板子,看到别人在管脚中间放置焊盘,我也试着做,但是放置好以后,无法布线,老是连不上线,也不知道是什么问题,搜了半天,也没结果,就问问大家,谢谢… 查看全部问答> |
|
各位, 我在6410上调试三星opengl es的例子。 1.1 和2.0的 exe文件都可以正常运行,但调试三星带的源码时,初始化全部成功,但一运行到glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);时串口就会输出如下错误信息: Exception \' ...… 查看全部问答> |
|
高级软件开发工程师/软件QA. 职位要求: 1、计算机或相关专业本科及以上学历; 2、必需精通C/C++编程; 3、熟悉嵌入式软件开发原则,设计模式及调试技巧; 4、掌握嵌入式操作系统(如Linux, WinCE)平台上的系统及应用程序开发; 5、3年以上嵌 ...… 查看全部问答> |
|
7.在有限的IO中扩展按键数量 前面我们讲到两种多按键的处理方法,仔细观察可以发现,这两种处理方法都是基于多个IO的,也就是说有多少个IO我们就能扩展出多少个按键。如果我只有6个可用的IO,那么能不能实现多于6个按键呢?答案是肯 ...… 查看全部问答> |
|
我用的是5510的一块开发板,上面的codec用的是tlv320aic23,我的程序需要对外界输入的电压值进行判断,如果大于某幅度就怎样,这时候程序该怎样写这个判断语句,不知道模拟电压经codec转换后对应的关系 高手帮忙,不胜感激… 查看全部问答> |




