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