STM32F103mini教程学习总结与心得(三)---->中断http://blog.csdn.net/qq_19598969/article/details/76167436
1. NVIC中断优先级分组
(1)CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。
(2)STM32并没有使用CM3内核的全部东西,而是只用了它的一部分。
(3)STM32有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程的中断优先级。
(4)STM32F103系列上面,又只有60个可屏蔽中断(在107系列才有68个)
2.中断管理方法:对STM32中断进行分组,组0~4。对每个中断设置一个抢占优先级和一个响应优先级值。
3.抢占优先级 & 响应优先级区别(数字越小,优先级越高):
(1)高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
(2)抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
(3)抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
(4)如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;
4.特别说明:一般情况,系统代码执行过程中,只设置一次中断优先级分组,设置好分组之后一般不会再改变分组。
5.中断优先级分组函数【在misc.c+core_m3.h文件中有说明】: void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
6.中断设置相关寄存器 :
__IO uint8_t IP[240]; //中断优先级控制的寄存器组---->Interrupt Priority Registers
=================================>>>STM32F10x系列一共60个可屏蔽中断,使用IP[59]~IP[0]
__IO uint32_t ISER[8]; //中断使能寄存器组----->32位寄存器,ISER[0]的bit0~bit31分别对应中断0~31。ISER[1]的bit0~27对应中断32~59
__IO uint32_t ICER[8]; //中断失能寄存器组----->用来失能中断
__IO uint32_t ISPR[8]; //中断挂起寄存器组----->用来挂起中断
__IO uint32_t ICPR[8]; //中断解挂寄存器组----->用来解挂中断
__IO uint32_t IABR[8]; //中断激活标志位寄存器组----->如果对应位为1,说明该中断正在执行。
static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn);
static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn);
static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
7.中断参数初始化函数
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
typedef struct
{
uint8_t NVIC_IRQChannel; //设置中断通道
uint8_t NVIC_IRQChannelPreemptionPriority;//设置响应优先级
uint8_t NVIC_IRQChannelSubPriority; //设置抢占优先级
FunctionalState NVIC_IRQChannelCmd; //使能/使能
} NVIC_InitTypeDef;
例:
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子优先级位2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据上面指定的参数初始化NVIC寄存器
8.中断优先级设置步骤
①系统运行后先设置中断优先级分组。调用函数:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
整个系统执行过程中,只设置一次中断分组。
②针对每个中断,设置对应的抢占优先级和响应优先级:
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
③ 如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。
9.中断实验步骤
(1)STM32的每个IO都可以作为外部中断输入。
(2)STM32的中断控制器支持19个外部中断/事件请求:
线0~15:对应外部IO口的输入中断。
线16:连接到PVD输出。
线17:连接到RTC闹钟事件。
线18:连接到USB唤醒事件。
(3)每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位。
(4)STM32供IO使用的中断线只有16个,但是STM32F10x系列的IO口多达上百个,STM32F103ZET6(112),STM32F103RCT6(51)
(5)外部中断通用IO映射:GPIOx.0映射到EXTI0
[在AFIO_EXTICR1寄存器配置]GPIOx.1映射到EXTI1
…
GPIOx.15映射到EXTI15
注意:同一时间,同一中断线上,只能有一个IO映射到该中断线上。例如,GPIOA.0接到了EXTI0上的时候, GPIOB.0就不能接入EXTI0。
(6)对于每个中断线,可以设置相应的触发方式(上升沿触发,下降沿触发,边沿触发)以及使能。
(7)对于STM32F1,有16个中断线,但只有7个中断服务函数------->>IO口外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数======>①外部中断线0-4分配5个中断向量,均有各自的服务函数②外部中断线5~9分配一个中断向量,共用一个服务函数③外部中断线10~15分配一个中断向量,共用一个中断服务函数。
说明:开启了线5和线6的中断,那么只要中断触发,那么5-9中断服务函数就会被调用。
(8)中断服务函数列表:EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
EXTI9_5_IRQHandler
EXTI15_10_IRQHandler
(9)外部中断常用库函数:
①void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
//设置IO口与中断线的映射关系
exp: GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
②void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
//初始化中断线:触发方式等
③ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
//判断中断线中断状态,是否发生
④void EXTI_ClearITPendingBit(uint32_t EXTI_Line);------->>手动清零
//清除中断线上的中断标志位
⑤EXTI_Init函数:void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
typedef struct
{
uint32_t EXTI_Line; //指定要配置的中断线
EXTIMode_TypeDef EXTI_Mode; //模式:事件 OR中断
EXTITrigger_TypeDef EXTI_Trigger;//触发方式:上升沿/下降沿/双沿触发
FunctionalState EXTI_LineCmd; //使能 OR失能
}EXTI_InitTypeDef;
例:
EXTI_InitStructure.EXTI_Line=EXTI_Line2;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
(10)外部中断的一般配置步骤:
①初始化IO口为输入。
GPIO_Init();
② 开启IO口复用时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);----->重要
设置IO口与中断线的映射关系。
void GPIO_EXTILineConfig();
初始化线上中断,设置触发条件等。
EXTI_Init();
配置中断分组(NVIC),并使能中断。
NVIC_Init();
⑥ 编写中断服务函数。
EXTIx_IRQHandler();
清除中断标志位
EXTI_ClearITPendingBit();
EXIT.c文件内容