STM32的每个IO口都可以作为外部中断输入。
GPIOx.0映射到EXTI0,GPIOx.1映射到EXTI1,……同一个时间只能有一个IO口映射到中断线。
对于每一个中断线,可以设置相应的触发方式(上升沿触发、下降沿触发、边沿触发)和使能。
IO外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数
总共分为三步:
第一步映射到中断线,第二部选择中断触发方式,第三步设置中断服务函数
外部中断的配置步骤:
#include <stm32f2xx.h> #include "SYSINIT.h" #include "led.h" /** 外部中断实验 **/ int main(){
/**系统初始化**/ SYS_INIT(); GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /*********************************内部向量中断初始化**************************************/ /* Set the Vector Table base address at 0x0 */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000); /* Configure the Priority Group to 2 bits */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; //使能按键所在的外部中断通道 EXTI1 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /********************************************************************************/ /*********************************外部中断初始化**************************************/ //开启IO口复用时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG , ENABLE); /* Connect Button EXTI Line to Button GPIO Pin */ //设置IO口与中断线的映射关系 和GPIOE.1绑定 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource1); /* Configure Button EXTI line */ EXTI_InitStructure.EXTI_Line = EXTI_Line1; //指定要配置的中断线 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //模式:事件OR中断 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //触发方式:下降沿触发 因为按钮接地 EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能 //初始化中断线、触发方式等 EXTI_Init(&EXTI_InitStructure); //清除中断线上的中断标志位 EXTI_ClearITPendingBit(EXTI_Line1); /********************************************************************************/ /**LED初始化**/ LED_Init(); GPIO_ResetBits(GPIOE,GPIO_Pin_14); //开 //初始化按键SW17 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_Init(GPIOE, &GPIO_InitStructure); //PE1输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOE,&GPIO_InitStructure); GPIO_ResetBits(GPIOE,GPIO_Pin_2); while(1){
} } /***********************************粗延时函数*************************************/ vu16 Delay_ms(vu16 Count) {
u16 i=0; while(Count--) {
for(i=12000;i>0;i--); } return Count; } /***********************************外部中断函数*************************************/ void EXTI1_IRQHandler (void) {
Delay_ms(200); //消去抖动 //判断中断是否发生 //EXTI_GetITStatus(EXTI_Line1) //如果PE1=0 if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_1)==0) {
//翻转 GPIO_ToggleBits(GPIOE,GPIO_Pin_14); } //结束的时候必须手动清零 EXTI_ClearITPendingBit(EXTI_Line1); }