目录
一、中断介绍
1.1、中断概念
1.2、中断事件
1.2.1、stm32f107中断事件 互联网型
1.2.2、stm32f103中断事件
1.3、中断优先级
二、中断配置
stm32是高级单片机,所以大部分外设都有中断,
主要学习的是外部中断
CPU执行程序时,由于发生某种随机事件(外部或内部),引起CPU暂时中断正在运行的程序,转去执行一段特殊的服务程序(中断服务子程序或中断处理程序),以处理该事件,该事件处理完后又返回被中断的程序继续执行,这一过程称为中断。引起中断的称为中断源,有些中断还能够被其他高优先级的中断所中断,那么这种情况被称为中断嵌套。
M3的内核理论上可以有256个中断,16个内核中断和240个外部中断。STM32F10x芯片只用了84个中断其中16个位内核中断通道68(stm32F107)个位可屏蔽中断(stm32F103只用60个可屏蔽中断)。这些中断通道按照不同的优先级顺序固定分配该相应的外部设备。
core_cm3.h 文件内定义了一个 NVIC 结构体,里面定义了相关寄存器
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 这三个寄存器,ISER 是中断使能寄存器,ICER 是中断清除寄存器,IP 是中断优先级寄存器。
STM32F103 中指定中断优先级的寄存器位有 4 位:
第 0 组:所有 4 位用于指定响应优先级
第 1 组:最高 1 位用于指定抢占式优先级,最低 3 位用于指定响应优先级
第 2 组:最高 2 位用于指定抢占式优先级,最低 2 位用于指定响应优先级
第 3 组:最高 3 位用于指定抢占式优先级,最低 1 位用于指定响应优先级
第 4 组:所有 4 位用于指定抢占式优先级
设置优先级分组可调用库函数 HAL_NVIC_SetPriorityGrouping()实现,有关NVIC 中断相关的库函数都在库文件 misc.c 和 misc.h 中,所以当使用到中断时,一定要记得把 misc.c 和 misc.h 添加到工程组中
NVIC_PriorityGroupConfig 函数带一个形参用于中断优先级分组,该值范围可以是 NVIC_PriorityGroup_0-NVIC_PriorityGroup_4,对应优先级与占用的位数信息如下:
函数内最终将分组值给 SCB->AIRCR,说明控制中断优先级寄存器是内核外设SCB 的 AIRCR 寄存器的 PRIGROUP[10:8]位。
(1)使能外设中断,这个具体是由外设相关中断使能位来控制,比如定时器有溢出中断,这个可由定时器的控制寄存器中相应中断使能位来控制。
(2)设置中断优先级分组,初始化 NVIC_InitTypeDef 结构体,设置抢占优先级和响应优先级,使能中断请求
NVIC_InitTypeDef结构体
typedef struct
{
uint8_t NVIC_IRQChannel; //中断源
uint8_t NVIC_IRQChannelPreemptionPriority; //抢占优先级
uint8_t NVIC_IRQChannelSubPriority; //响应优先级
FunctionalState NVIC_IRQChannelCmd; //中断使能或失能
} NVIC_InitTypeDef;
NVIC_IRQChannel:中断源的设置,不同的外设中断,中断源不一样,自然名字也不一样,所以名字不能写错,否则不会进入中断。
typedef enum IRQn
{
//Cortex-M3 处理器异常编号
NonMaskableInt_IRQn = -14,
MemoryManagement_IRQn = -12,
BusFault_IRQn = -11,
UsageFault_IRQn = -10,
SVCall_IRQn = -5,
DebugMonitor_IRQn = -4,
PendSV_IRQn = -2,
SysTick_IRQn = -1,
//STM32 外部中断编号
WWDG_IRQn = 0,
PVD_IRQn = 1,
TAMP_STAMP_IRQn = 2,
// .....省略部分
DMA2_Channel2_IRQn = 57,
DMA2_Channel3_IRQn = 58,
DMA2_Channel4_5_IRQn = 59
}IRQn_Type;
NVIC_IRQChannelPreemptionPriority:抢占优先级,具体的值要根据优先级分组来确定,可以参考前面中断优先级分组内容。
NVIC_IRQChannelSubPriority:响应优先级,具体的值要根据优先级分组来确定,可以参考前面中断优先级分组内容。
NVIC_IRQChannelCmd:中断使能/失能设置,使能配置为 ENABLE,失能配置为 DISABLE。
配置好中断后如果有触发,即会进入中断服务函数,那么中断服务函数也有固定的函数名,可以在 startup_stm32f10x_hd.s 启动文件查看,启动文件提供
的只是一个中断服务函数名,具体实现什么功能还需要我们自己编写,可以将中断服务函数放在 stm32f10x_it.c 文件内,也可以放在自己的应用程序中。通常
我们把中断函数放在应用程序中。不要任意修改中断服务函数名,因为启动文件内中断服务函数名已经固定,如果要修改,你还必须在启动。
文件内把原中断函数修改。
启动函数里面提供的中断服务函数名 不能修改中断服务函数名
使能中 断1 (ENABLE), 失能中断 0(DISABLE)