STM32-EXTI中断/事件管理器
0、前言
异常类型
来自stm32f10x.h
中IRQn_Type
结构体
/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable 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 */
#ifdef STM32F10X_HD
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_IRQn = 24, /*!< TIM1 Break Interrupt */
TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */
TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation 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 */
RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
TIM8_BRK_IRQn = 43, /*!< TIM8 Break Interrupt */
TIM8_UP_IRQn = 44, /*!< TIM8 Update Interrupt */
TIM8_TRG_COM_IRQn = 45, /*!< TIM8 Trigger and Commutation 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 */
#endif /* STM32F10X_HD */
NVIC
NVIC即嵌套向量中断控制器,STM32的NVIC是Cortex-M3的NVIC的一个子集
相关库函数
static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn); //使能中断
static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn); //失能中断
static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn); //设置中断悬起位
static __INLINE uint32_t NVIC_ClearPendingIRQ(IRQn_Type IRQn); //清除中断悬起位
static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn); //获得悬起中断编号
static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority); //设置中断优先级
static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn); //获得中断优先级
static __INLINE void NVIC_SystemReset(void); //系统复位
中断优先级
中断分组,0~4
(第3组)抢占优先级0~7,响应优先级1或0
抢占优先级级别高于响应优先级,数值越小代表优先级越高
高优先级的抢占优先级可打断正在运行的低抢占优先级中断
高优先级的响应优先级不可打断低响应优先级
NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority |
---|---|---|
NVIC_PriorityGroup_0 | 0 | 0-15 |
NVIC_PriorityGroup_1 | 0-1 | 0-7 |
NVIC_PriorityGroup_2 | 0-3 | 0-3 |
NVIC_PriorityGroup_3 | 0-7 | 0-1 |
NVIC_PriorityGroup_4 | 0-15 | 0 |
NVIC配置优先级分组
- 中断优先级分组
//整个系统执行过程中,只设置一次中断分组。
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
/*
NVIC_PriorityGroup_0~NVIC_PriorityGroup_4
*/
- 初始化结构体
typedef struct
{
uint8_t NVIC_IRQChannel; //定义中断源,选自IRQn_Type结构体中元素
uint8_t NVIC_IRQChannelPreemptionPriority; //抢占优先级
uint8_t NVIC_IRQChannelSubPriority; //子优先级
FunctionalState NVIC_IRQChannelCmd; //中断是否使能
} NVIC_InitTypeDef;
//中断初始化
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
- 编写对应的中断服务函数,统一写在
stm32f10x_it.c
1、EXTI-外部中断/事件控制器
简介
外部中断/事件控制器由20个产生事件/中断请求的边沿检测器组成。
每个输入线可以独立地配置输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。
每个输入线都可以独立地被屏蔽。挂起寄存器保持着状态线的中断请求
挂载于APB2总线
主要特性:
- 每个中断/事件都有独立的触发和屏蔽
- 每个中断线都有专用的状态位
- 支持多达20个软件的中断/事件请求
- 检测脉冲宽度低于APB2时钟宽度的外部信号。参见数据手册中电气特性部分的相关参数。
由输入线输入检测信号经一系列处理后,可至NVIC中断控制器产生软件层面的中断,或者经脉冲发生器产生硬件层面的事件,供给TIM,ADC等。
中断线
共有20条中断/事件线,EXTI0-15可用于GPIO,其他用于特定的外设事件
外部中断编程
常用库函数
//中断服务函数列表
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
EXTI9_5_IRQHandler
EXTI15_10_IRQHandler
// 设置IO口与中断线的映射关系
// exp: GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
//初始化中断线:触发方式等
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
//判断中断线中断状态,是否发生
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
//清除中断线上的中断标志位,必须手动清零
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
EXTI初始化结构体
typedef struct
{
uint32_t EXTI_Line; //指定要配置的中断线
EXTIMode_TypeDef EXTI_Mode; //模式:事件 OR中断
EXTITrigger_TypeDef EXTI_Trigger;//触发方式:上升沿/下降沿/双沿触发
FunctionalState EXTI_LineCmd; //使能 OR失能
}EXTI_InitTypeDef;
配置步骤
-
外设时钟使能,复用时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);
-
配置NVIC中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3); //设置优先级分组 // NVIC结构体初始化 /* 配置中断源 */ NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; /* 配置抢占优先级 */ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; /* 配置子优先级 */ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; /* 使能中断通道 */ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
-
配置IO口
GPIO_Init(); //设置IO口与中断线的映射关系。 void GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource13);
-
初始化EXTI结构体
EXTI_InitTypeDef* EXTI_InitStructure; EXTI_InitStructure.EXTI_Line=EXTI_Line13; //可选EXTI0-19 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断或事件(EXTI_Mode_Event) EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //EXTI_Trigger_Rising / EXTI_Trigger_Rising_Falling EXTI_InitStructure.EXTI_LineCmd = ENABLE; //ENABLE或DISABLE EXTI_Init(&EXTI_InitStructure);
-
编写中断服务函数(
stm32f10x_it.c
)void EXTI15_10_IRQHandler(void) { //确保是否产生了EXTI Line中断 if(EXTI_GetITStatus(EXTI_Line13) != RESET) { //清除中断标志位 EXTI_ClearITPendingBit(EXTI_Line13); } }