图1.0编程
图1.1ide
中断控制器支持23条中断线,其中16条是IO管脚中断线,分别是EXTI0~EXTI15:spa
图 1.23d
另外七根中断线以下图:code
中断线和管脚的对应关系:EXTI0~EXTI15 和GPIOx0~15一一对应,x:A~G。blog
每条中断线控制着7个管脚的中断跳变沿的输入,经过寄存器SYSCFG_EXTICRx(x:1~4)来进行多选1。it
举例:中断线0,即EXTI0控制着7个管脚的中断源输入,分别是PA0,PB0,PC0,PD0,PE0,PF0,PG0。class
外部中断寄存器配置SYSCFG共有四个寄存器,他们的做用是相似的,管理着某中断下某引脚的选择,下列只介绍第一个寄存器,其余相似:配置
EXTI0[3:0] 用于选择中断线0的中断源管脚 0000: PA0 引脚 0001: PB0 引脚 0010: PC0 引脚 0011: PD0 引脚 0100: PE0 引脚 0101: PF0 引脚 0110: PG0 引脚 0111: PH0 引脚 1000: PI0 引脚 举例:中断线0的中断源管脚选择为PA0管脚,对应的代码以下: SYSCRF->EXTICR1 &=~(0xF<<0); EXTI1[3:0] 用于选择中断线1的中断源管脚 0000: PA1 引脚 0001: PB1 引脚 0010: PC1 引脚 0011: PD1 引脚 0100: PE1 引脚 0101: PF1 引脚 0110: PG1 引脚 0111: PH1 引脚 1000: PI1 引脚 举例:中断线1的中断源管脚选择为PF1管脚,对应的代码以下: SYSCRF->EXTICR1 |=(5<<4); EXTI2[3:0] 用于选择中断线2的中断源管脚 0000: PA2 引脚 0001: PB2 引脚 0010: PC2 引脚 0011: PD2 引脚 0100: PE2 引脚 0101: PF2 引脚 0110: PG2 引脚 0111: PH2 引脚 1000: PI2 引脚 CR1 EXTI3[3:0] 用于选择中断线3的中断源管脚 0000: PA3 引脚 0001: PB3 引脚 0010: PC3 引脚 0011: PD3 引脚 0100: PE3 引脚 0101: PF3 引脚 0110: PG3 引脚 0111: PH3 引脚 1000: PI3 引脚 CR1
四位为一小组,四位控制一条中断线,用于选择中断线的中断源管脚。中断线0~中断线15 分别于EXTI0[3:0]~EXTI15[3:0]一一对应。请求
编程时,SYSCFG_EXTICR1对应SYSCFG->EXTICR[0]
SYSCFG_EXTICR2对应SYSCFG->EXTICR[1]
SYSCFG_EXTICR3对应SYSCFG->EXTICR[2]
SYSCFG_EXTICR4对应SYSCFG->EXTICR[3]
下面工程文件是用外部中断检测四个按键:
#include "stm32f4xx.h" #include "delay.h" void Key_Init(void) { RCC->AHB1ENR |= 1<<0;//使能GPIOA的时钟 GPIOA->MODER &=~(3<<0);//PA0配置为输入模式 GPIOA->PUPDR &=~(3<<0);//PA0配置为浮空模式 //GPIOA->PUPDR |=2<<0;//下拉 也能够配置 RCC->AHB1ENR |= 1<<4;//使能GPIOE时钟 GPIOE->MODER &=~(3<<4);//PE2配置为输入模式 GPIOE->PUPDR &=~(3<<4);//PE2配置为浮空模式 //GPIOA->PUPDR |=1<<4;//初始为上拉 GPIOE->MODER &=~(3<<6);//PE3配置为输入模式 GPIOE->PUPDR &=~(3<<6);//PE3配置为浮空模式 //GPIOA->PUPDR |=1<<6; GPIOE->MODER &=~(3<<8);//PE4配置为输入模式 GPIOE->PUPDR &=~(3<<8);//PE4配置为浮空模式 //GPIOA->PUPDR |=1<<8; } void EXIT_Init(void) { RCC->APB2ENR |= 1<<14;//使能系统配置控制器时钟 /*******初始化KEY1<-->PA0的中断线0**********/ SYSCFG->EXTICR[0] &=~(0XF<<0);//配置SYSCFG 外部中断配置寄存器,选择中断源管脚 EXTI->RTSR |= 1<<0;//选择中断线0触发边沿为上升沿 EXTI->IMR |= 1<<0;//开放中断线0的中断请求 NVIC_EnableIRQ(EXTI0_IRQn);//使能中断通道,NVIC_EnableIRQ(IRQn) /*******初始化KEY2<-->PE2的中断线2**********/ SYSCFG->EXTICR[0] |= (4<<8);//配置SYSCFG 外部中断配置寄存器,选择中断源管脚 //中断线2,一条中断线位为4,第二位就是8了 EXTI->FTSR |= 1<<2;//选择中断2触发边沿为降低沿 EXTI->IMR |= 1<<2;//开放中断线2的中断请求 NVIC_EnableIRQ(EXTI2_IRQn);//使能中断通道,NVIC_EnableIRQ(IRQn) /*******初始化KEY3<-->PE3的中断线3**********/ SYSCFG->EXTICR[0] |= (4<<12);//配置SYSCFG 外部中断配置寄存器,选择中断源管脚 EXTI->FTSR |= 1<<3;//选择中断线3触发边沿为降低沿 EXTI->IMR |= 1<<3;//开放中断线3的中断请求 NVIC_EnableIRQ(EXTI3_IRQn);//使能中断通道,NVIC_EnableIRQ(IRQn) /*******初始化KEY4<-->PE4的中断线4**********/ SYSCFG->EXTICR[1] |= (4<<0);//配置SYSCFG 外部中断配置寄存器,选择中断源管脚 EXTI->FTSR |= 1<<4;//选择中断线0触发边沿为降低沿 EXTI->IMR |= 1<<4;//开放中断线4的中断请求 NVIC_EnableIRQ(EXTI4_IRQn);//使能中断通道,NVIC_EnableIRQ(IRQn) } void EXTI0_IRQHandler(void) { //k1 PA0 led1 pf6 if(EXTI->PR &(1<<0)) //判断中断线0是否触发了中断 { EXTI->PR |= 1<<0;//置一清零 Delay_ms(10);//延时10ms消抖 if(GPIOA->IDR &(1<<0))//判断KEY1是不稳定的按下了 { GPIOF->ODR ^= 1<<6;//取反LED1灯的状态 } } } void EXTI2_IRQHandler(void) { //k2 PE2 led3 pf9 if(EXTI->PR &(1<<2)) //判断中断线2是否触发了中断 { EXTI->PR |= 1<<2;//置一清零 Delay_ms(10);//延时10ms消抖 if(!(GPIOE->IDR &(1<<2)))//判断KEY2是不稳定的按下了 { GPIOF->ODR ^= 1<<9;//取反LED2灯的状态; } } } void EXTI3_IRQHandler(void) { //k3 PE3 led3 pf10 if(EXTI->PR &(1<<3)) //判断中断线3是否触发了中断 { EXTI->PR |= 1<<3;//置一清零 Delay_ms(10);//延时10ms消抖 if(!(GPIOE->IDR &(1<<3)))//判断KEY3是不稳定的按下了 { GPIOF->ODR ^= 1<<10;//取反LED3灯的状态 } } } void EXTI4_IRQHandler(void) { //k4 PE4 led4 pc0 if(EXTI->PR &(1<<4)) //判断中断线4是否触发了中断 { EXTI->PR |= 1<<4;//置一清零 Delay_ms(10);//延时10ms消抖 if(!(GPIOE->IDR &(1<<4)))//判断KEY4是不稳定的按下了 { GPIOC->ODR ^= 1<<0;//取反LED4灯的状态 } } }