STM32之外部中断

 

图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[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灯的状态
        }
    }
}
View Code

 

posted @ 2019-10-08 08:44  千浦千钰  阅读(1187)  评论(0编辑  收藏  举报