文章目录
- 13.1 异常类型
- 13.2 NVIC
- 13.2.1 NVIC一些概念
- 13.2.2 NVIC的SDK支持
- 13.3 优先级的定义
- 13.3.1 AIRCR
- 13.3.2 优先级分组
- 13.4 中断编程
- 13.4.1 中断服务函数
RT1052 中断非常强大,每个外设都可以产生中断
13.1 异常类型
异常响应系统,分为系统异常和外部中断。
- 其中系统异常有 10 个,外部中断有 160 个。
- 有关具体的系统异常和外部中断可在 SDK 库文件 MINXRT1052.h 这个头文件查询到
- 在 IRQn_Type 这个枚举类型里面包含了 RT1052 全部的异常声明。
13.2 NVIC
RT1052的 NVIC 是 Cortex-M7 的 NVIC 的一个子集。
13.2.1 NVIC一些概念
中断请求
- 大多数外设都能够发送中断请求,一个引脚由低电平变为高电平、串口接收到数据、定时器计时完成等都可以向 CPU 发送中断请求。
中断号
- 每个中断请求拥有一个固定的标号
- CPU 通过中断号来区分不同的中断
- 不同的中断请求可以拥有相同的中断号。
- RT1052 拥有 151 个中断号,但是可以接收 240 个中断请求
中断优先级
- 优先级数值越小,优先级越高。
中断优先级分组
- 优先级分位两部分,分别为抢占优先级和子优先级
- 如果一个中断正在执行,另外一个抢占优先级更高的中断发生了则打断底优先级的中断。
- 如果两个中断请求的抢占优先级相同,子优先级不同则高优先级不能打断低优先级,但是如果两个中断请求同时发生并且抢占优先级相同,则根据子优先级决定谁先执行。
- 抢占优先级和子优先级都相同的话,就比较他们的硬件中断编号,编号越小,优先级越高。
中断服务函数
- 中断号对应的函数叫做中断向量表
- 当中断的到相应时 CPU 就会执行中断服务函数里面的内容。
13.2.2 NVIC的SDK支持
有关 NVIC 的内容定义在 SDK 的 core_cm7.h 中
SDK 为 NVIC 提供了这些库函数,涵盖了 NVIC 几乎所有功能使用
1 #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
2 #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping
3 #define NVIC_EnableIRQ __NVIC_EnableIRQ
4 #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ
5 #define NVIC_DisableIRQ __NVIC_DisableIRQ
6 #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ
7 #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ
8 #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ
9 #define NVIC_GetActive __NVIC_GetActive
10 #define NVIC_SetPriority __NVIC_SetPriority
11 #define NVIC_GetPriority __NVIC_GetPriority
12 #define NVIC_SystemReset __NVIC_SystemReset
如:NVIC_SystemReset()
中断号(MIMXRT1052.h)
1 typedef enum IRQn {
2
3 CTI0_ERROR_IRQn = 17,
4 LPUART6_IRQn = 25,
5 LPUART7_IRQn = 26,
6 LPUART8_IRQn = 27,
7 LPI2C1_IRQn = 28,
8 LPI2C2_IRQn = 29,
9 LPI2C3_IRQn = 30,
10 .. .. ..
11 .. .. ..
12 .. .. ..
13
14 PWM4_3_IRQn = 150,
15 PWM4_FAULT_IRQn = 151,
16 Reserved168_IRQn = 152,
17 Reserved169_IRQn = 153,
18 Reserved170_IRQn = 154,
19 Reserved171_IRQn = 155,
20 Reserved172_IRQn = 156,
21 Reserved173_IRQn = 157,
22 SJC_ARM_DEBUG_IRQn = 158,
23 NMI_WAKEUP_IRQn = 159
24 } IRQn_Type
13.3 优先级的定义
NVIC 有一个专门的寄存器:应用程序中断和复位控制寄存器 AIRCR,详细请参考《armv7m_arm》参考手册第 B3.2.6 章节.
13.3.1 AIRCR
AIRCR[PRIGROUP] 用来配置外部中断的优先级分组,宽度为 3bit。
M 系列内核的中断优先级一样由 8 个 bit 位来表示,对于 RT1052 芯片,只使用其中 [7:4] 位。
- 这四位再划分为抢占优先级和子优先级
13.3.2 优先级分组
优先级的分组由内核外设 SCB 的应用程序中断及复位控制寄存器 AIRCR 的 PRIGROUP[10:8] 位决定。
根据 PRIGROUP 优先级分组的值对应于优先级 [7:0] 位的划分方式
1052 芯片只用到 [7:4] 位,所以在 8 种分组下要另外去掉无效的 bit 位后来看主优先级和子优先级分别占多少位。
- 当优先级分组取 0b000、0b001、0b010、0b011 时都只有主优先级。
设置优先级分组可调用库函数 NVIC_SetPriorityGrouping 实现
13.4 中断编程
使用 NVIC_SetPriorityGrouping(uint32_t PriorityGroup) 函数配置中断优先级分组。
使用 uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) 函数配置具体外设中断通道的抢占优先级和子优先级。
使用 NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) 函数设置中断编号的优先级
使用 NVIC_EnableIRQ(IRQn_Type IRQn) 函数使能中断请求
13.4.1 中断服务函数
在启动文件 startup_MIMXRT1052.s 中我们预先为每个中断都写了一个中断服务函数,只是这些中断函数都是为空,为的只是初始化中断向量表。
- 关于中断服务函数的函数名必须跟启动文件里面预先设置的一样
- 系统就在中断向量表中找不到中断服务函数的入口,直接跳转到启动文件里面预先写好的空函数,并且在里面无限循环,实现不了中断。