Chapter 16 STM32 中断应用概览
STM32 中断非常强大,每个外设都可以产生中断
文中所述 “异常就是中断,中断就是异常”
异常类型
- 系统异常有8个,加上 Rest 和 HardFrault 也算上就是 10 个
- 外部中断有 60 个
- 除个别异常的优先级被固定外,其它异常的优先级都是可以编程的
系统异常和外部中断在标准库文件 stm32f10x.h 头文件中可查询。
IRQn_Tpye 结构体里包含了 F103 系列全部的异常声明
NVIC 简介
NVIC 控制整个芯片中断相关功能。它是内核里面的一个外设。
STM32 中的 NVIC 是 Cortex-M3 的 NVIC 的一个子集。
NVIC 寄存器简介
NVIC 结构体定义,在固件库头文件:core_m3.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
typedef struct { __IO uint32_t ISER[8]; uint32_t RESERVED0[24]; __IO uint32_t ICER[8]; uint32_t RSERVED1[24]; __IO uint32_t ISPR[8]; uint32_t RESERVED2[24]; __IO uint32_t ICPR[8]; uint32_t RESERVED3[24]; __IO uint32_t IABR[8]; uint32_t RESERVED4[56]; __IO uint8_t IP[240]; uint32_t RESERVED5[644]; __O uint32_t STIR; } NVIC_Type;
|
配置中断的时候我们一般只用:
- ISER :使能中断
- ICER :清除中断
- IP :设置中断优先级
NVIC 中断配置固库
固件库文件 core_m3.h 的最最后,定了 NVIC 的一些函数。用得比较少,甚至不用,配置中断的时候会用更简洁的方法。
中断优先级
优先级定义
中断优先级寄存器 NVIC_IPRx
- 配置外部中断优先级,8 位,只使用高 4 位
- 这 4 位又被分成:抢占(主)优先级、子优先级
- 多中断响应时按:“抢占优先级 > 子优先级 > 硬件中断编号” 顺序执行
优先级分组
- 由内核外设 SCB->AIRCR(应用程序中断和复位控制寄存器) 的 PRIGROUP[10:8] 位决定。
- 设置优先级分组:NVIC_PriorityGroupConifg()
- 有关 NVIC 中断相关的库函数:
misc.c、misc.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) { assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup)); SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; }
|
优先级分组真值表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ============================================================================================================================ NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description ============================================================================================================================ NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority | | | 4 bits for subpriority ---------------------------------------------------------------------------------------------------------------------------- NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority | | | 3 bits for subpriority ---------------------------------------------------------------------------------------------------------------------------- NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority | | | 2 bits for subpriority ---------------------------------------------------------------------------------------------------------------------------- NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority | | | 1 bits for subpriority ---------------------------------------------------------------------------------------------------------------------------- NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority | | | 0 bits for subpriority ============================================================================================================================
|
中断编程
配置每个中断的时候,一般有 3 个编程要点:
1、使能外设某个中断
2、初始化 NVIC_InitTypeDef 结构体
配置中断优先级分组
设置抢占优先级、子优先级
使能中断请求
| typedef struct { uint8_t NVIC_IRQChannel; uint8_t NVIC_IRQChannelPreemptionPriority; uint8_t NVIC_IRQChannelSubPriority; FunctionalState NVIC_IRQChannelCmd; } NVIC_InitTypeDef;
|
3、编写中断服务函数
- 在启动文件中
stm32f10x_startup_md.s 中已预告为每个中断写了一个中断服务函数,内容为空,用于初始化中断向量表
- 实际使用的中断服务函数是我们自己重新编写,写在
stm32f10x_it.c 文件中
- 中断服务函数的函数名必须与启动文件里预先设置的一样,否则程序跳进启动文件里的空函数无限循环,实现不了中断