STM32F10x之NVIC
转载自:https://www.jianshu.com/p/3aa5997fe794
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种分配方式,如下:
- 所有8位用于指定响应优先级
- 最高1位用于指定抢占式优先级,最低7位用于指定响应优先级
- 最高2位用于指定抢占式优先级,最低6位用于指定响应优先级
- 最高3位用于指定抢占式优先级,最低5位用于指定响应优先级
- 最高4位用于指定抢占式优先级,最低4位用于指定响应优先级
- 最高5位用于指定抢占式优先级,最低3位用于指定响应优先级
- 最高6位用于指定抢占式优先级,最低2位用于指定响应优先级
- 最高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中断执行。
STM32F10x之NVIC的更多相关文章
- STM32 NVIC
在stm32中是要配置nvic的.何为nvic,对于我这样的初学者来说,直观感受就是在设置为中断后 还需要配置 中断的优先级nvic就是搞这个的. 那么具体的需要配置些什么那? void NVIC_C ...
- STM32F10x 学习笔记6(USART实现串口通讯 2)
这次讲讲利用串口收发中断来进行串口通讯.STM32 上为每个串口分配了一个中断.也就是说无论是发送完成还是收到数据或是数据溢出都产生同一个中断.程序需在中断处理函数中读取状态寄存器(USART_SR) ...
- stm32F10x复习-1
地点:家 1.库文件说明 _htmresc: LOGO的设计图 Libraries: 源代码及启动文件 -- CoreSupport 核内设备函数层的CM3核通用的源文件.作用是为采用Cortex-M ...
- GPIOLED配置、key、中断NVIC配置
#include "stm32f10x.h" #include "stm32f10x_gpio.h" //内核,(NVIC) #include "mi ...
- STM32中EXTI和NVIC的关系
(1)NVIC(嵌套向量中断):NVIC是Cortex-M3核心的一部分,关于它的资料不在<STM32的技术参考手册>中,应查阅ARM公司的<Cortex-M3技术参考手册>C ...
- [STM32F10x] 利用定时器测量频率
硬件:STM32F103C8T6 平台:ARM-MDk V5.11 原理 利用STM32F10x的定时器的捕获(Capture)单元测量输入信号的频率. 基本原理是通过两次捕获达到的计数器的差值,来计 ...
- STM32 NVIC配置详解
例程: /* Configure one bit for preemption priority */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1) ...
- stm32之NVIC
非本人原创,转载自http://blog.csdn.net/denghuanhuandeng/article/details/8350392 STM32的NVIC理解 例程: /* Configur ...
- STM32 之 NVIC(中断向量、优先级) 简述
一.背景 需要使用STM32的CAN进行通信,经过一系列配置后,已可正常收发,还剩下一个CAN通信的错误处理.可错 误中断使能寄存器已经配置使能了,出错后就是无法进入"CAN1_SCE_IR ...
随机推荐
- 推荐WEB 端批量移动设备管理控制工具STF
推荐WEB 端批量移动设备管理控制工具STF 1 官方网站 https://openstf.io/ 2 github https://github.com/openstf/stf 后面有时间了,抽空也 ...
- FontForge 汉化教程
引用 :http://www.sucaijishi.com/2018/articles_0815/258.html FontForge是一款免费字库编辑工具,官方暂不提供简体中文,本文汉化方法在201 ...
- Nginx开启gzip提高页面加载速度
今天发现页面多次请求数据且加载的数据大,需要等待的时间很长 记得Nginx有gzip,可以对数据进行压缩 gzip是nginx服务器的ngx_http_gzip_module模块提供的在线实时数据压缩 ...
- 深入理解C语言 - 指针详解
一.什么是指针 C语言里,变量存放在内存中,而内存其实就是一组有序字节组成的数组,每个字节有唯一的内存地址.CPU 通过内存寻址对存储在内存中的某个指定数据对象的地址进行定位.这里,数据对象是指存储在 ...
- 解决python错误 UnicodeDecodeError: 'gb2312' codec can't decode byte 0x8b in position 1: illegal multibyte sequence
报错的代码: url= 'http://kaijiang.500.com/shtml/ssq/19001.shtml' page =urllib.request.urlopen(url) conten ...
- 深入V8引擎-AST(6)
花了5篇才把一个字符串词法给解析完,不知道要多久才能刷完整个流程,GC.复杂数据类型的V8实现那些估计又是几十篇,天呐,真是给自己挖了个大坑. 前面几篇实际上只是执行了scanner.Initiali ...
- redis 实战操作RDB和AOF快照持久化
前言:redis是我们常用的缓存方式,今天就来介绍下两种持久化的方式吧,先科普概念,再实战操作 一.RDB Redis将某一时刻的快照(备份的数据库数据)保存成一种称为RDB格式的文件中,这种格式是经 ...
- 使用Visual Studio的单元测试
步骤1:创建被测试项目 创建单元测试项目步骤2:在测试项目中写测试代码步骤3:运行测试 方法1 右键运行测试,方法2 点击测试 运行所有测试备注:单击方法 右测有提示可以看测试方法的输出
- [個人紀錄] regular 搜集
判斷有理數 ^(0|[1-9]([0-9]{1,5})?)((\.(([0-9]{1,5})?[1-9])))?$
- winfrom数据导出
/// <summary> /// 数据导出 /// </summary> /// <param name="dataGridView">< ...