10. NVIC中断控制器
一、什么是中断
中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。
当处理机接受中断时,只需暂停一个或几个周期而不执行处理程序的中断,称为简单中断。中断又可分为 屏蔽中断 和 非屏蔽中断 两类。可由程序控制其屏蔽的中断称为 屏蔽中断 或 可屏蔽中断。屏蔽时,处理机将不接受中断。反之,不能由程序控制其屏蔽,处理机一定要立即处理的中断称为 非屏蔽中断 或 不可屏蔽中断。非屏蔽中断主要用于断电、电源故障等必须立即处理的情况。处理机响应中断时,不需执行查询程序。由被响应中断源向 CPU 发向量地址的中断称为 向量中断,反之为非向量中断。向量中断可以提高中断响应速度。
二、中断的作用和意义
- 实时控制
- 在确定时间内相应事件做出响应,如:温度控制
- 故障处理
- 检测到故障,需要第一时间处理,如:电梯夹人
- 数据传输
- 不确定数据何时会来,如:串口数据接收
中断的意义:高效处理紧急程序,不会一直占用 CPU 资源;
三、什么是NVIC
向量中断控制器,简称 NVIC,是 Cortex‐M3 不可分离的一部分,它与 CM3 内核的逻辑紧密耦合。M3 内核都是支持 256 个中断,其中包含了 16 个系统中断和 240 个外部中断,并且具有 256 级的可编程中断设置。然而芯片厂商一般不会把内核的这些资源全部用完,如STM32F103ZET6 的系统中断有 10 个,外部中断有 60个 。
四、什么是中断向量表
中断向量表是指定义一块固定的内存,以 4 字节对齐,存放各个 中断服务函数程序的首地址。中断向量表定义在启动文件中,当发生中断时,CPU 会自动执行对应的中断服务函数。
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD WWDG_IRQHandler ; Window Watchdog
DCD PVD_IRQHandler ; PVD through EXTI Line detect
DCD TAMPER_IRQHandler ; Tamper
DCD RTC_IRQHandler ; RTC
DCD FLASH_IRQHandler ; Flash
DCD RCC_IRQHandler ; RCC
DCD EXTI0_IRQHandler ; EXTI Line 0
DCD EXTI1_IRQHandler ; EXTI Line 1
DCD EXTI2_IRQHandler ; EXTI Line 2
DCD EXTI3_IRQHandler ; EXTI Line 3
DCD EXTI4_IRQHandler ; EXTI Line 4
DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
DCD ADC1_2_IRQHandler ; ADC1 & ADC2
DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
DCD CAN1_RX1_IRQHandler ; CAN1 RX1
DCD CAN1_SCE_IRQHandler ; CAN1 SCE
DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
DCD TIM1_BRK_IRQHandler ; TIM1 Break
DCD TIM1_UP_IRQHandler ; TIM1 Update
DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
DCD TIM2_IRQHandler ; TIM2
DCD TIM3_IRQHandler ; TIM3
DCD TIM4_IRQHandler ; TIM4
DCD I2C1_EV_IRQHandler ; I2C1 Event
DCD I2C1_ER_IRQHandler ; I2C1 Error
DCD I2C2_EV_IRQHandler ; I2C2 Event
DCD I2C2_ER_IRQHandler ; I2C2 Error
DCD SPI1_IRQHandler ; SPI1
DCD SPI2_IRQHandler ; SPI2
DCD USART1_IRQHandler ; USART1
DCD USART2_IRQHandler ; USART2
DCD USART3_IRQHandler ; USART3
DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
DCD TIM8_BRK_IRQHandler ; TIM8 Break
DCD TIM8_UP_IRQHandler ; TIM8 Update
DCD TIM8_TRG_COM_IRQHandler ; TIM8 Trigger and Commutation
DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare
DCD ADC3_IRQHandler ; ADC3
DCD FSMC_IRQHandler ; FSMC
DCD SDIO_IRQHandler ; SDIO
DCD TIM5_IRQHandler ; TIM5
DCD SPI3_IRQHandler ; SPI3
DCD UART4_IRQHandler ; UART4
DCD UART5_IRQHandler ; UART5
DCD TIM6_IRQHandler ; TIM6
DCD TIM7_IRQHandler ; TIM7
DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
__Vectors_End
| 位置 | 优先级 | 优先级类型 | 名称 | 说明 | 地址 |
|---|---|---|---|---|---|
| 保留 | 0x0000_0000 | ||||
| -3 | 固定 | Reset | 复位 | 0x0000_0004 | |
| -2 | 固定 | NMI | 不可屏蔽中断 RCC 时钟安全系统(CSS)联接到 NMI 向量 |
0x0000_0008 | |
| -1 | 固定 | 硬件失效(HardFault) | 所有类型的失效 | 0x0000_000C | |
| 0 | 可设置 | 存储管理(MemManage) | 存储器管理 | 0x0000_0010 | |
| 1 | 可设置 | 总线错误(BusFault) | 预取指失败,存储器访问失败 | 0x0000_0014 | |
| 2 | 可设置 | 错误应用(UsageFault) | 未定义的指令或非法状 | 0x0000_0018 | |
| 保留 | 0x0000_001C ~ 0x0000_002B | ||||
| 3 | 可设置 | SVCall | 通过 SWI 指令的系统服务调用 | 0x0000_002C | |
| 4 | 可设置 | 调试监控(DebugMonitor) | 调试监控器 | 0x0000_0030 | |
| 保留 | 0x0000_0034 | ||||
| 5 | 可设置 | PendSV | 可挂起的系统服务 | 0x0000_0038 | |
| 6 | 可设置 | SysTick | 系统嘀嗒定时器 | 0x0000_003C | |
| 0 | 7 | 可设置 | WWDG | 窗口定时器中断 | 0x0000_0040 |
| 1 | 8 | 可设置 | PVD | 连到 EXTI 的电源电压检测(PVD)中断 | 0x0000_0044 |
| 2 | 9 | 可设置 | TAMPER | 侵入检测中断 | 0x0000_0048 |
| 3 | 10 | 可设置 | RTC | 实时时钟(RTC)全局中断 | 0x0000_004C |
| 4 | 11 | 可设置 | FLASH | 闪存全局中断 | 0x0000_0050 |
| 5 | 12 | 可设置 | RCC | 复位和时钟控制(RCC)中断 | 0x0000_0054 |
| 6 | 13 | 可设置 | EXTI0 | EXTI 线0 中断 | 0x0000_0058 |
| 7 | 14 | 可设置 | EXTI1 | EXTI 线1 中断 | 0x0000_005C |
| 8 | 15 | 可设置 | EXTI2 | EXTI 线2 中断 | 0x0000_0060 |
| 9 | 16 | 可设置 | EXTI3 | EXTI 线3 中断 | 0x0000_0064 |
| 10 | 17 | 可设置 | EXTI4 | EXTI 线4 中断 | 0x0000_0068 |
| 11 | 18 | 可设置 | DMA1 通道1 | DMA1 通道1 全局中断 | 0x0000_006C |
| 12 | 19 | 可设置 | DMA1 通道2 | DMA1 通道2 全局中断 | 0x0000_0070 |
| 13 | 20 | 可设置 | DMA1 通道3 | DMA1 通道3 全局中断 | 0x0000_0074 |
| 14 | 21 | 可设置 | DMA1 通道4 | DMA1 通道4 全局中断 | 0x0000_0078 |
| 15 | 22 | 可设置 | DMA1 通道5 | DMA1 通道5 全局中断 | 0x0000_007C |
| 16 | 23 | 可设置 | DMA1 通道6 | DMA1 通道6 全局中断 | 0x0000_0080 |
| 17 | 24 | 可设置 | DMA1 通道7 | DMA1 通道7 全局中断 | 0x0000_0084 |
| 18 | 25 | 可设置 | ADC1_2 | ADC1 和 ADC2 的全局中断 | 0x0000_0088 |
| 19 | 26 | 可设置 | USB_HP_CAN_TX | USB 高优先级 或 CAN 发送中断 | 0x0000_008C |
| 20 | 27 | 可设置 | USB_LP_CAN_RX0 | USB 低优先级 或 CAN 接收0 中断 | 0x0000_0090 |
| 21 | 28 | 可设置 | CAN_RX1 | CAN 接收1 中断 | 0x0000_0094 |
| 22 | 29 | 可设置 | CAN_SCE | CAN SCE 中断 | 0x0000_0098 |
| 23 | 30 | 可设置 | EXTI9_5 | EXTI 线[9:5] 中断 | 0x0000_009C |
| 24 | 31 | 可设置 | TIM1_BRK | TIM1 刹车中断 | 0x0000_00A0 |
| 25 | 32 | 可设置 | TIM1_UP | TIM1 更新中断 | 0x0000_00A4 |
| 26 | 33 | 可设置 | TIM1_TRG_COM | TIM1 触发 和 通信 中断 | 0x0000_00A8 |
| 27 | 34 | 可设置 | TIM1_CC | TIM1 捕获比较中断 | 0x0000_00AC |
| 28 | 35 | 可设置 | TIM2 | TIM2 全局中断 | 0x0000_00B0 |
| 29 | 36 | 可设置 | TIM3 | TIM3 全局中断 | 0x0000_00B4 |
| 30 | 37 | 可设置 | TIM4 | TIM4 全局中断 | 0x0000_00B8 |
| 31 | 38 | 可设置 | I2C1_EV | I2C1 事件中断 | 0x0000_00BC |
| 32 | 39 | 可设置 | I2C1_ER | I2C1错误中断 | 0x0000_00C0 |
| 33 | 40 | 可设置 | I2C2_EV | I2C2 事件中断 | 0x0000_00C4 |
| 34 | 41 | 可设置 | I2C2_ER | I2C2 错误中断 | 0x0000_00C8 |
| 35 | 42 | 可设置 | SPI1 | SPI1 全局中断 | 0x0000_00CC |
| 36 | 43 | 可设置 | SPI2 | SPI2 全局中断 | 0x0000_00D0 |
| 37 | 44 | 可设置 | USART1 | USART1 全局中断 | 0x0000_00D4 |
| 38 | 45 | 可设置 | USART2 | USART2 全局中断 | 0x0000_00D8 |
| 39 | 46 | 可设置 | USART3 | USART3 全局中断 | 0x0000_00DC |
| 40 | 47 | 可设置 | EXTI15_10 | EXTI 线[15:10] 中断 | 0x0000_00E0 |
| 41 | 48 | 可设置 | RTCAlarm | 连到 EXTI 的 RTC 闹钟中断 | 0x0000_00E4 |
| 42 | 49 | 可设置 | USB 唤醒 | 连到 EXTI 的 从USB 待机唤醒中断 | 0x0000_00E8 |
| 43 | 50 | 可设置 | TIM8_BRK | TIM8 刹车中断 | 0x0000_00EC |
| 44 | 51 | 可设置 | TIM8_UP | TIM8 更新中断 | 0x0000_00F0 |
| 45 | 52 | 可设置 | TIM8_TRG_COM | TIM8 触发 和 通信 中断 | 0x0000_00F4 |
| 46 | 53 | 可设置 | TIM8_CC | TIM8 捕获比较中断 | 0x0000_00F8 |
| 47 | 54 | 可设置 | ADC3 | ADC3 全局中断 | 0x0000_00FC |
| 48 | 55 | 可设置 | FSMC | FSMC 全局中断 | 0x0000_0100 |
| 49 | 56 | 可设置 | SDIO | SDIO 全局中断 | 0x0000_0104 |
| 50 | 57 | 可设置 | TIM5 | TIM5 全局中断 | 0x0000_0108 |
| 51 | 58 | 可设置 | SPI3 | SPI3 全局中断 | 0x0000_010C |
| 52 | 59 | 可设置 | UART4 | UART4 全局中断 | 0x0000_0110 |
| 53 | 60 | 可设置 | UART5 | UART5 全局中断 | 0x0000_0114 |
| 54 | 61 | 可设置 | TIM6 | TIM6 全局中断 | 0x0000_0118 |
| 55 | 62 | 可设置 | TIM7 | TIM7 全局中断 | 0x0000_011C |
| 56 | 63 | 可设置 | DMA2 通道1 | DMA2 通道1 全局中断 | 0x0000_0120 |
| 57 | 64 | 可设置 | DMA2 通道2 | DMA2 通道2 全局中断 | 0x0000_0124 |
| 58 | 65 | 可设置 | DMA2 通道3 | DMA2 通道3 全局中断 | 0x0000_0128 |
| 59 | 66 | 可设置 | DMA2 通道4_5 | DMA2 通道4 和 DMA2 通道5 全局中断 | 0x0000_012C |
六、中断优先级
STM32 中的中断优先级可以分为:抢占式优先级 和 响应优先级,响应优先级 也称 子优先级,每个中断源都需要被指定这两种优先级。抢占式优先级和响应优先级的区别:
抢占优先级:抢占优先级高的中断可以打断正在执行的抢占优先级低的中断。
响应优先级:抢占优先级相同,响应优先级高的中断不能打断响应优先级低的中断。
当两个或者多个中断的 抢占式优先级 和 响应优先级 相同时,那么就遵循 自然优先级,看中断向量表的中断排序,数值越小,优先级越高。
在 NVIC 中由寄存器 NVIC_IPR0-NVIC_IPR59 共 60 个寄存器控制中断优先级,每个寄存器的 8 位,所以就有了 240 个宽度为 8bit 的中断优先级控制寄存器,原则上每个外部中断可配置的优先级为 0~255,数值越小,优先级越高。但是实际上 M3 芯片为了精简设计,只使用了高四位 [7:4],低四位取零,这样以至于最多只有 16 级中断嵌套,即 2^4=16。
对于 NVCI 的中断优先级分组:STM32F103 将中断分为 5 个组,组 0 ~ 4。该分组的设置是由 SCB->AIRCR 寄存器的 bit 10 ~ 8来定义的。具体的分配关系如下:
| 优先级分组 | AIRCR[10:8] | bit[7:4] 分配情况 | 分配结果 |
|---|---|---|---|
| 0 | 111 | none : [7:4] | 0 位抢占优先级,4 位响应优先级 |
| 1 | 110 | [7] : [6:4] | 1 位抢占优先级,3 位响应优先级 |
| 2 | 101 | [7:6] : [5:4] | 2 位抢占优先级,2 位响应优先级 |
| 3 | 100 | [7:5] : [4] | 3 位抢占优先级,1 位响应优先级 |
| 4 | 011 | [7:4] : none | 4 位抢占优先级,0 位响应优先级 |
一个工程中,一般只设置一次中断优先级分组;
六、NVIC寄存器介绍
typedef struct
{
__IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[24U];
__IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[24U];
__IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[24U];
__IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[24U];
__IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */
uint32_t RESERVED4[56U];
__IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */
uint32_t RESERVED5[644U];
__OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */
} NVIC_Type;
| NVIC 相关寄存器 | 位数 | 寄存器个数 | 备注 |
|---|---|---|---|
| 中断使能寄存器(ISER) | 32 | 8 | 每个位控制一个中断 |
| 中断除能寄存器(ICER) | 32 | 8 | 每个位控制一个中断 |
| 应用程序中断及复位控制寄存器(AIRCR) | 32 | 1 | 位[10:8] 控制优先级分组 |
| 中断优先级寄存器(IPR) | 8 | 240 | 8 个位对应一个中断,而 STM32 只使用高 4 位 |
ISER[8]:ISER 全称是:Interrupt SetEnable Registers,这是一个 中断使能寄存器组。上面说了 CM3 内核支持 256 个中断,这里用 8 个 32 位寄存器来控制,每个位控制一个中断。但是 STM32F103 的可屏蔽中断最多只有 60 个,所以对我们来说,有用的就是两个(ISER[0] 和 ISER[1]),总共可以表示 64 个中断。而 STM32F103 只用了其中的 60 个。ISER[0] 的 bit0 ~ 31 分别对应中断 0 ~ 31;ISER[1] 的 bit0 ~ 27 对应中断 32 ~ 59,这样总共 60 个中断就可以分别对应上了。你要使能某个中断,必须设置相应的 ISER 位为 1,使该中断被使能(这里仅仅是使能,还要配合中断分组、屏蔽、IO口映射等设置才算是一个完整的中断设置)。具体每一位对应哪个中断,请参考 stm32f103xe.h 里面的第 69 行附近。
ICER[8]:全称是:Interrupt ClearEnable Registers,是一个 中断除能寄存器组。该寄存器组与 ISER 的作用恰好相反,是用来清除某个中断的使能的。其对应位的功能,也和 ICER 一样。这里要专门设置一个 ICER 来清除中断位,而不是向 ISER 写 0 来清除,是因为 NVIC 的这些寄存器都是写 1 有效的,写 0 是无效的。
ISPR[8]:全称是:Interrupt SetPending Registers,是一个 中断使能挂起控制寄存器组。每个位对应的中断和 ISER 是一样的。通过置 1,可以将正在进行的中断挂起,而执行同级或更高级别的中断。写 0 是无效的。
ICPR[8]:全称是:Interrupt ClearPending Registers,是一个 中断解挂控制寄存器组。其作用与 ISPR 相反,对应位也和 ISER 是一样的。通过设置 1,可以将挂起的中断解挂。写 0 无效。
IABR[8]:全称是:Interrupt Active Bit Registers,是一个 中断激活标志位寄存器组。对应位所代表的中断和 ISER 一样,如果为 1,则表示该位所对应的中断正在被执行。这是一个只读寄存器,通过它可以知道当前在执行的中断是哪一个。在中断执行完了由硬件自动清零。
IP[240]:全称是:Interrupt Priority Registers,是一个 中断优先级控制的寄存器组。STM32F103 的中断分组与这个寄存器组密切相关。IP寄存器组 由 240 个 8bit 的寄存器组成,每个可屏蔽中断占用 8bit,这样总共可以表示 240 个可屏蔽中断。而 STM32F103 只用到了其中的 60 个。IP[59] ~ IP[0]分别对应中断 59 ~ 0。而每个可屏蔽中断占用的 8bit 并没有全部使用,而是只用了高 4 位。这 4 位,又分为 抢占优先级 和 子优先级。抢占优先级在前,子优先级在后。而这两个优先级各占几个位又要根据 SCB->AIRCR 中的中断分组设置来决定。
七、NVIC的使用
ST 公司把 core_cm3.h 文件的 NVIC 相关函数封装到 stm32f1xx_hal_cortex.c 文件中。
7.1、设置中断分组
【1】、HAL_NVIC_SetPriorityGrouping() 函数
HAL_NVIC_SetPriorityGrouping() 是设置中断优先级分组函数。其声明如下:
/**
* @brief Sets the priority grouping field (preemption priority and subpriority)
* using the required unlock sequence.
* @param PriorityGroup: The priority grouping bits length.
* This parameter can be one of the following values:
* @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
* 4 bits for subpriority
* @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
* 3 bits for subpriority
* @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
* 2 bits for subpriority
* @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
* 1 bits for subpriority
* @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
* 0 bits for subpriority
* @note When the NVIC_PriorityGroup_0 is selected, IRQ preemption is no more possible.
* The pending IRQ priority will be managed only by the subpriority.
* @retval None
*/
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup);
- 函数形参:
PriorityGroup 是中断优先级分组号,可以选择范围:NVIC_PRIORITYGROUP_0 到 NVIC_PRIORITYGROUP_4(共5组)。
/** @defgroup CORTEX_Preemption_Priority_Group CORTEX Preemption Priority Group
* @{
*/
#define NVIC_PRIORITYGROUP_0 0x00000007U /*!< 0 bits for pre-emption priority
4 bits for subpriority */
#define NVIC_PRIORITYGROUP_1 0x00000006U /*!< 1 bits for pre-emption priority
3 bits for subpriority */
#define NVIC_PRIORITYGROUP_2 0x00000005U /*!< 2 bits for pre-emption priority
2 bits for subpriority */
#define NVIC_PRIORITYGROUP_3 0x00000004U /*!< 3 bits for pre-emption priority
1 bits for subpriority */
#define NVIC_PRIORITYGROUP_4 0x00000003U /*!< 4 bits for pre-emption priority
0 bits for subpriority */
- 函数返回值:
无;
7.2、设置中断优先级
【1】、HAL_NVIC_SetPriority() 函数
HAL_NVIC_SetPriority() 是设置中断优先级函数,用于设置中断的 抢占优先级 和 响应优先级(子优先级)。其声明如下:
/**
* @brief Sets the priority of an interrupt.
* @param IRQn: External interrupt number.
* This parameter can be an enumerator of IRQn_Type enumeration
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xx.h))
* @param PreemptPriority: The preemption priority for the IRQn channel.
* This parameter can be a value between 0 and 15
* A lower priority value indicates a higher priority
* @param SubPriority: the subpriority level for the IRQ channel.
* This parameter can be a value between 0 and 15
* A lower priority value indicates a higher priority.
* @retval None
*/
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority);
- 函数参数:
IRQn 是中断号,可以选择范围:IRQn_Type 定义的枚举类型,定义在 stm32f103xe.h。
/**
* @brief STM32F10x Interrupt Number Definition, according to the selected device
* in @ref Library_configuration_section
*/
/*!< Interrupt Number Definition */
typedef enum
{
/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
HardFault_IRQn = -13, /*!< 3 Cortex-M3 Hard Fault Interrupt */
MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */
/****** STM32 specific Interrupt Numbers *********************************************************/
WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */
PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */
TAMPER_IRQn = 2, /*!< Tamper Interrupt */
RTC_IRQn = 3, /*!< RTC global Interrupt */
FLASH_IRQn = 4, /*!< FLASH global Interrupt */
RCC_IRQn = 5, /*!< RCC global Interrupt */
EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */
EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */
EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */
EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */
EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */
DMA1_Channel1_IRQn = 11, /*!< DMA1 Channel 1 global Interrupt */
DMA1_Channel2_IRQn = 12, /*!< DMA1 Channel 2 global Interrupt */
DMA1_Channel3_IRQn = 13, /*!< DMA1 Channel 3 global Interrupt */
DMA1_Channel4_IRQn = 14, /*!< DMA1 Channel 4 global Interrupt */
DMA1_Channel5_IRQn = 15, /*!< DMA1 Channel 5 global Interrupt */
DMA1_Channel6_IRQn = 16, /*!< DMA1 Channel 6 global Interrupt */
DMA1_Channel7_IRQn = 17, /*!< DMA1 Channel 7 global Interrupt */
ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */
USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */
USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */
CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */
CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */
EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break Interrupt and TIM9 global Interrupt */
TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global Interrupt */
TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */
TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
TIM4_IRQn = 30, /*!< TIM4 global Interrupt */
I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */
I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */
SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
SPI2_IRQn = 36, /*!< SPI2 global Interrupt */
USART1_IRQn = 37, /*!< USART1 global Interrupt */
USART2_IRQn = 38, /*!< USART2 global Interrupt */
USART3_IRQn = 39, /*!< USART3 global Interrupt */
EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
RTC_Alarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global Interrupt */
TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global Interrupt */
TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */
TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */
ADC3_IRQn = 47, /*!< ADC3 global Interrupt */
FSMC_IRQn = 48, /*!< FSMC global Interrupt */
SDIO_IRQn = 49, /*!< SDIO global Interrupt */
TIM5_IRQn = 50, /*!< TIM5 global Interrupt */
SPI3_IRQn = 51, /*!< SPI3 global Interrupt */
UART4_IRQn = 52, /*!< UART4 global Interrupt */
UART5_IRQn = 53, /*!< UART5 global Interrupt */
TIM6_IRQn = 54, /*!< TIM6 global Interrupt */
TIM7_IRQn = 55, /*!< TIM7 global Interrupt */
DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */
DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */
DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */
DMA2_Channel4_5_IRQn = 59, /*!< DMA2 Channel 4 and Channel 5 global Interrupt */
} IRQn_Type;
PreemptPriority 是 抢占优先级,可以选择范围:0 到 15。
SubPriority 是 响应优先级,可以选择范围:0 到 15。
- 函数返回值:
无;
7.3、使能中断
【1】、HAL_NVIC_EnableIRQ() 函数
HAL_NVIC_EnableIRQ() 是中断使能函数。其声明如下:
/**
* @brief Enables a device specific interrupt in the NVIC interrupt controller.
* @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
* function should be called before.
* @param IRQn External interrupt number.
* This parameter can be an enumerator of IRQn_Type enumeration
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
* @retval None
*/
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
- 函数参数:
IRQn 是 中断号,可以选择范围:IRQn_Type 定义的枚举类型,定义在 stm32f103xe.h。
/**
* @brief STM32F10x Interrupt Number Definition, according to the selected device
* in @ref Library_configuration_section
*/
/*!< Interrupt Number Definition */
typedef enum
{
/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
HardFault_IRQn = -13, /*!< 3 Cortex-M3 Hard Fault Interrupt */
MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */
/****** STM32 specific Interrupt Numbers *********************************************************/
WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */
PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */
TAMPER_IRQn = 2, /*!< Tamper Interrupt */
RTC_IRQn = 3, /*!< RTC global Interrupt */
FLASH_IRQn = 4, /*!< FLASH global Interrupt */
RCC_IRQn = 5, /*!< RCC global Interrupt */
EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */
EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */
EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */
EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */
EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */
DMA1_Channel1_IRQn = 11, /*!< DMA1 Channel 1 global Interrupt */
DMA1_Channel2_IRQn = 12, /*!< DMA1 Channel 2 global Interrupt */
DMA1_Channel3_IRQn = 13, /*!< DMA1 Channel 3 global Interrupt */
DMA1_Channel4_IRQn = 14, /*!< DMA1 Channel 4 global Interrupt */
DMA1_Channel5_IRQn = 15, /*!< DMA1 Channel 5 global Interrupt */
DMA1_Channel6_IRQn = 16, /*!< DMA1 Channel 6 global Interrupt */
DMA1_Channel7_IRQn = 17, /*!< DMA1 Channel 7 global Interrupt */
ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */
USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */
USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */
CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */
CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */
EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break Interrupt and TIM9 global Interrupt */
TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global Interrupt */
TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */
TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
TIM4_IRQn = 30, /*!< TIM4 global Interrupt */
I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */
I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */
SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
SPI2_IRQn = 36, /*!< SPI2 global Interrupt */
USART1_IRQn = 37, /*!< USART1 global Interrupt */
USART2_IRQn = 38, /*!< USART2 global Interrupt */
USART3_IRQn = 39, /*!< USART3 global Interrupt */
EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
RTC_Alarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global Interrupt */
TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global Interrupt */
TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */
TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */
ADC3_IRQn = 47, /*!< ADC3 global Interrupt */
FSMC_IRQn = 48, /*!< FSMC global Interrupt */
SDIO_IRQn = 49, /*!< SDIO global Interrupt */
TIM5_IRQn = 50, /*!< TIM5 global Interrupt */
SPI3_IRQn = 51, /*!< SPI3 global Interrupt */
UART4_IRQn = 52, /*!< UART4 global Interrupt */
UART5_IRQn = 53, /*!< UART5 global Interrupt */
TIM6_IRQn = 54, /*!< TIM6 global Interrupt */
TIM7_IRQn = 55, /*!< TIM7 global Interrupt */
DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */
DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */
DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */
DMA2_Channel4_5_IRQn = 59, /*!< DMA2 Channel 4 and Channel 5 global Interrupt */
} IRQn_Type;
- 函数返回值:
无;