一、中断介绍
stm32是高级单片机,所以大部分外设都有中断,
主要学习的是外部中断
1.1、中断概念
CPU执行程序时,由于发生某种随机事件(外部或内部),引起CPU暂时中断正在运行的程序,转去执行一段特殊的服务程序(中断服务子程序或中断处理程序),以处理该事件,该事件处理完后又返回被中断的程序继续执行,这一过程称为中断。引起中断的称为中断源,有些中断还能够被其他高优先级的中断所中断,那么这种情况被称为中断嵌套。

M3的内核理论上可以有256个中断,16个内核中断和240个外部中断。STM32F10x芯片只用了84个中断其中16个位内核中断通道68(stm32F107)个位可屏蔽中断(stm32F103只用60个可屏蔽中断)。这些中断通道按照不同的优先级顺序固定分配该相应的外部设备。
1.2、中断事件
1.2.1、stm32f107中断事件 互联网型

1.2.2、stm32f103中断事件

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 是中断优先级寄存器。

1.3、中断优先级

STM32F103 芯片支持 60 个可屏蔽中断通道,每个中断通道都具备自己的中断优先级控制字节(8 位,理论上每个外部中断优先级可以设置为0-255,数值越小,优先级越高。但是 STM32F103 中只使用 4 位,高 4 位有效),用于表达优先级的高 4 位又被分组成抢占式优先级和响应优先级,通常也把响应优先级称为“亚优先级”或“副优先级”,每个中断源都需要被指定这两种优先级。
高抢占式优先级的中断事件会打断当前的主程序或者中断程序运行,俗称中断嵌套。在抢占式优先级相同的情况下,高响应优先级的中断优先被响应
当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。
如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;
如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理那一个,越靠前的先执行。
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)

一、中断介绍
stm32是高级单片机,所以大部分外设都有中断,
主要学习的是外部中断
1.1、中断概念
CPU执行程序时,由于发生某种随机事件(外部或内部),引起CPU暂时中断正在运行的程序,转去执行一段特殊的服务程序(中断服务子程序或中断处理程序),以处理该事件,该事件处理完后又返回被中断的程序继续执行,这一过程称为中断。引起中断的称为中断源,有些中断还能够被其他高优先级的中断所中断,那么这种情况被称为中断嵌套。

M3的内核理论上可以有256个中断,16个内核中断和240个外部中断。STM32F10x芯片只用了84个中断其中16个位内核中断通道68(stm32F107)个位可屏蔽中断(stm32F103只用60个可屏蔽中断)。这些中断通道按照不同的优先级顺序固定分配该相应的外部设备。
1.2、中断事件
1.2.1、stm32f107中断事件 互联网型

1.2.2、stm32f103中断事件

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 是中断优先级寄存器。

1.3、中断优先级

STM32F103 芯片支持 60 个可屏蔽中断通道,每个中断通道都具备自己的中断优先级控制字节(8 位,理论上每个外部中断优先级可以设置为0-255,数值越小,优先级越高。但是 STM32F103 中只使用 4 位,高 4 位有效),用于表达优先级的高 4 位又被分组成抢占式优先级和响应优先级,通常也把响应优先级称为“亚优先级”或“副优先级”,每个中断源都需要被指定这两种优先级。
高抢占式优先级的中断事件会打断当前的主程序或者中断程序运行,俗称中断嵌套。在抢占式优先级相同的情况下,高响应优先级的中断优先被响应
当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。
如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;
如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理那一个,越靠前的先执行。
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)

举报