一、STM32外部中断介绍
STM32的每一个IO口都可以作为外部中断的中断输入口。STM32F103的中断控制器支持19个外部中断/事情请求。每个中断都设有状态位,每个中断/事件都有独立的触发和屏蔽设置。
STM32F103的19个外部中断为:
线0~15 | 对应外部IO口的输入中断 |
线16 | 连接到PVD输出 |
线17 | 连接到RTC闹钟事件 |
线18 | 连接到USB唤醒事件 |
其中,STM32供IO口使用的中断线只有16个。STM32如何把16个中断线和IO口一一对应起来呢?STM32是这样设计的,GPIO的管脚GPIOx.0~GPIOx.15(x = A,B,C,D,E,F,G)分别对应中断线0~15,如此一来,每个中断线对应了最多7个IO口。举个例子说明,GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0对应中断线0。每个中断线上每次只能连接在1个IO口上,这样就需要通过配置来决定对应中断线配置到哪个GPIO上了。如下是GPIO和中断线的映射关系图:
二、实验要求
按下按键KEY1,采用外部中断方式控制LED1状态的翻转。
三、程序
1. IO口外部中断初始化步骤
(1)初始化IO口为输入;
(2)开启AFIO时钟;
(3)设置IO口与中断线的映射关系;
(4)初始化线上中断,设置触发条件等;
(5)配置中断分组(NVIC),并使能中断;
(6)编写中断服务函数。
void exit_init(void)
{
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
key_init(); //按键初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //复用AFIO时钟使能
/****************GPIOE.3与中断线3进行映射***************/
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3); //KEY1-PE3,设置PE3和中断线3的映射
/*********************初始化中断线上中断**********************/
EXTI_InitStruct.EXTI_Line = EXTI_Line3; //中断线3
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_Init(&EXTI_InitStruct);
/*********************配置中断分组***********************/
NVIC_InitStruct.NVIC_IRQChannel = EXTI3_IRQn; //使能按键KEY1外部中断通道3
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级2
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2; //子优先级2
NVIC_Init(&NVIC_InitStruct);
}
void EXTI3_IRQHandler(void) //外部中断3服务函数
{
delay_ms(10); //消抖
if(KEY1 == 0)
{
LED1 = !LED1;
}
EXTI_ClearITPendingBit(EXTI_Line3); //清除LINE3上的中断标志位
}
int main(void)
{
exit_init();
LED_init();
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2
while(1);
}