STM32F10x之NVIC

1 异常类型

Cortex-M3内核具有强大的异常响应系统,它把能够打断当前代码执行流程的事件分为异常(exception)和中断(interrupt),并把它们用一个表管理起来,编号为0~15的称为内核异常,而16以上的则称为外部中断,这个表就称为中断向量表。

CM3 内核总共支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256级的可编程中断设置。除了个别异常的优先级固定外, 其它异常的优先级都是可编程的,这里及下文不在严格区分异常和中断。异常类型如下表所示:

偏移 异常类型 优先级 描述
0 - - 复位时加载向量表中第一项作为栈顶地址
1 Reset -3 (最高) 电源开启或热复位时调用,在执行第一条指令时,优先级下降到最低(Thread模式),异步故障
2 NMI -2 除了复位,它不能被其他任何中断抢占,异步故障
3 Hard Fault -1 如果故障由于优先级或可配置的故障处理程序被禁止而不能激活时,此时所有这些故障均为硬故障,同步故障
4 Memory Management 可编程 存储包含单元(MPU)不匹配,包括不可访问和不匹配,同步故障;也用于MPU不可用或不存在的情况,已至此默认存储映射的从不执行区域
5 Bus Fault 可编程 预取出错,存储器访问错误,以及其它地址/存储器相关的错误;当为精确的总线故障时是同步故障,不精确时为异步故障
6 Usage Fault 可编程 应用错误,如果执行未定义的指令或试图进行非法的状态转换,同步故障
7-10 保留 - 保留
11 SVCall 可编程 使用SVC指令进行系统服务调用,同步故障
12 Debug Monitor 可编程 调试监视异常(当没有停止时),同步故障,但只在允许时有效;如果它的优先级比当前激活的处理程序优先级更低,则它不激活
13 保留 - 保留
14 PendSV 可编程 系统服务科挂起请求,异步故障,只能由软件挂起
15 PendSV 可编程 用于系统滴答定时器,异步故障
16及以上 External Interrupt 可编程 有核外发出的中断,传递给NVIC,都为异步故障

2 中断优先级

STM32中有两种优先级:抢占式优先级和响应优先级(也有成“副优先级”或“亚优先级”的)。所有可编程中断都需要指定这两种优先级。高抢占式优先级的中断可以中断低抢占式优先级的中断处理,即中断嵌套,或者说高抢占式优先级的中断可以嵌套于低抢占式优先级的中断中。当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。可以总结为:抢占优先级决定是否可以产生中断嵌套,响应优先级决定了中断响应顺序,如果两种优先级一样看偏移,中断向量表中偏移小的优先执行。

由于每个中断源都需要被指定抢占优先级和响应优先级,那么就需要有相应的寄存器记录每个中断的优先级,在Cortex-M3中定义了8个比特位用于设置中断源的优先级,这8个比特位可以有8种分配方式,如下:

  1. 所有8位用于指定响应优先级
  2. 最高1位用于指定抢占式优先级,最低7位用于指定响应优先级
  3. 最高2位用于指定抢占式优先级,最低6位用于指定响应优先级
  4. 最高3位用于指定抢占式优先级,最低5位用于指定响应优先级
  5. 最高4位用于指定抢占式优先级,最低4位用于指定响应优先级
  6. 最高5位用于指定抢占式优先级,最低3位用于指定响应优先级
  7. 最高6位用于指定抢占式优先级,最低2位用于指定响应优先级
  8. 最高7位用于指定抢占式优先级,最低1位用于指定响应优先级

以上即为Cortex-M3优先级分组方式,但是Cortex-M3也允许在具有较少中断源时使用较少的寄存器位指定中断源的优先级。STM32并没有使用Cortex-M3内核嵌套向量中断的全套东西,而是使用了它的一部分,STM32有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程的中断优先级。我们最常用的是68个可屏蔽中断,但是STM32的68个可屏蔽中断,只有在STM32F107系列才有68个,其他只有60个。

STM32对中断进行了编号,编号为负的为系统异常,标号为正的外部中断,有些未定义中断号(复位Reset,不可屏蔽中断NMI和硬错误中断Hand Fault和一些保留的中断)的系统异常是不能被设置优先级的,其他中断的优先级都是用户可以配置的。STM32中指定中断优先级的寄存器有效位为4位,因此有一下5种分组方式:
第0组:所有4位用于指定响应优先级(16种)
第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级(8种)
第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级(4种)
第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级(2种)
第4组:所有4位用于指定抢占式优先级

STM32的分组可以使用标准库函数void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)设置,这个函数在中断配置前优先调用以配置中断优先级分组,该函数的可选参数对应以上5种分组:

  • NVIC_PriorityGroup_0: 选择第0组
  • NVIC_PriorityGroup_1: 选择第1组
  • NVIC_PriorityGroup_2:选择第2组
  • NVIC_PriorityGroup_3:选择第3组
  • NVIC_PriorityGroup_4:选择第4组

3 函数库

3.1 数据结构

typedef struct
{
  uint8_t NVIC_IRQChannel;                      /*!< 指定中断号 */
  uint8_t NVIC_IRQChannelPreemptionPriority;    /*!< 指定中断抢占优先级 */
  uint8_t NVIC_IRQChannelSubPriority;           /*!< 指定中断响应优先级 */
  FunctionalState NVIC_IRQChannelCmd;           /*!< 指定中断是否使能 */   
} NVIC_InitTypeDef;

3.2 库函数

函数名 描述
NVIC_SetPriorityGrouping 设置中断优先级分组(内核提供)
NVIC_GetPriorityGrouping 获取中断优先级分组(内核提供)
NVIC_EnableIRQ 使能外部中断(内核提供)
NVIC_DisableIRQ 失能外部中断(内核提供)
NVIC_GetPendingIRQ 获取指定中断是否挂起(内核提供)
NVIC_SetPendingIRQ 设置指定中断挂起位(内核提供)
NVIC_ClearPendingIRQ 清除指定挂起中断(内核提供)
NVIC_GetActive 获取指定中断激活状态(内核提供)
NVIC_SetPriority 设置指定中断优先级(内核提供)
NVIC_GetPriority 获取指定中断优先级(内核提供)
NVIC_EncodePriority 编码优先级(内核提供)
NVIC_DecodePriority 解码优先级(内核提供)
NVIC_SystemReset 系统复位(内核提供)
NVIC_PriorityGroupConfig 配置中断优先级分组(STM32提供)
NVIC_Init 中断初始化(STM32提供)
NVIC_SetVectorTable 设置中断向量表位置和偏移(STM32提供)
NVIC_SystemLPConfig 选择系统进入低功耗模式的条件(STM32提供)

注意 :上表中,加粗的函数为常用库函数。

4 示例说明

void NVIC_Config(void)
{
  NVIC_InitTypeDef  NVIC_InitStructure;

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);               /*!< 中断分组 */
 
  NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;           /*!< 指定中断号 */
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;   /*!< 配置抢占优先级 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;          /*!< 配置响应优先级 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;               /*!< 使能中断*/
  NVIC_Init(&NVIC_InitStructure);                               /*!< 初始化指定中断 */

  NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;           /*!< 指定中断号 */
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x1;   /*!< 配置抢占优先级 */
  NVIC_Init(&NVIC_InitStructure);                               /*!< 初始化指定中断 */
}

说明: 示例中,CAN2的抢占优先级高于CAN1的抢占优先级,则CAN2中断可以嵌套CAN1中断即当CAN1产生接收中断时,CAN2中断可以打断CAN1中断执行。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 1.STM32中断概述 中断优先级 在使用中断式按键之前,我们先去了解一下STM32的中断。关于这方面可以参考《S...
    东方未曦阅读 3,471评论 1 10
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,849评论 6 13
  • 首先让我们来看一下关于控制定时器中断的文件timer.c中的源码: 前两行是头文件的声明,这里我们不去理会,我们今...
    Jane_123阅读 11,194评论 0 5
  • 今天是母亲节,早上,我第一时间给老美女打去了慰问电话,祝她节日快乐。老美女问我中午回不回家(我们住在一个城市),我...
    岳小乖么么哒阅读 522评论 0 0