浅谈STM32外部中断

时间:2024-03-24 15:47:21

一、外部请求:

uSTM32的中断控制器支持19个外部中断/事件请求:
 

线0~15:对应外部IO口的输入中断。

线16:连接到PVD输出。

线17:连接到RTC闹钟事件。

线18:连接到USB唤醒事件。

二、中断方式

每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位

三、中断线

看图:

          GPIOx.0映射到EXTI0

          GPIOx.1映射到EXTI1

           …

          GPIOx.15映射到EXTI15

浅谈STM32外部中断

选择不同闪存容量的32,中断线有点不一样

中断线使用需要注意的问题:

IO口每个都可以作为中断使用,但是却不能同时使用,稍不注意,都会造成程序错误,但是却不报错,运行的结果与自己想的相差甚远,却找不出原因:

外部中断配置寄存器AFIO_EXITCRx(x=1,2,3,4),每个寄存器控制IO端口(A~G)的4个IO口

例如:AFIO_EXITCR1的[3:0]控制(PA0~PG0);[3:0]=0x0000,选PA0; =0x0001,选PB0;以此类推

        AFIO_EXITCR1的[7:4]控制(PA1~PG1);[3:0]=0x0000,选PA1; =0x0001,选PB1;以此类推

        AFIO_EXITCR2的[3:0]控制(PA4~PG4);[3:0]=0x0000,选PA4; =0x0001,选PB4;以此类推

即:AFIO_EXITCR1控制(PA~PG)端口的0~3   I/O 口,AFIO_EXITCR2控制(PA~PG)端口的4~7   I/O 口,

        AFIO_EXITCR1控制(PA~PG)端口的8~11   I/O 口,AFIO_EXITCR2控制(PA~PG)端口的12~15   I/O 口

因此,每次只能出现一个相同数字的IO口(PA0~PG0,一个工程最多只能出现其中一个,其它的也一样)则每次最多有16个外部中断

即:假如AFIO_EXITCR1的[3:0] 为 0000时,选择的是PA0作为中断

浅谈STM32外部中断

但是STM32只有7个中断服务函数分别为

EXIT0,  供PA0,PB0,,,,PG0使用

EXIT1,   供PA1,PB1,,,,PG1使用

EXIT2,   供PA2,PB2,,,,PG2使用

EXIT3,   供PA3,PB3,,,,PG3使用

EXIT4,   供PA4,PB4,,,,PG4使用

 EXIT9_5,  供PA5~PA9,PB5~PB9,,,,PG5~PG9使用

EXIT15_10,    供PA10~PA15,PB10~PB15,,,,PG10~PG15使用

因为,一个中断服务函数,一次只能给一个IO口使用,所以同时只能有7个外部中断

四、代码初始化

我现在使用的是原子的寄存器的代码,粘贴上来吧

步骤:

1、初始化IO口为输入    RCC->APB2ENR|

2、开启与该 IO 口相对的线上中断/事件,设置触发条件。                                                                                                                      Ex_NVIC_Config(GPIO_A,0,RTIR);    PA0 ,上升沿触发 

3、配置中断分组(NVIC),并使能中断。                                                                                                                                              MY_NVIC_Init(2,3,EXTI0_IRQn,2);    /抢占2,子优先级3,中断线0,组2  

4、编写中断服务函数。
     void EXTI0_IRQHandler(void)
 

中断初始化:

void EXTIX_Init(void)
{

    RCC->APB2ENR|=1<<2;     //使能PORTA时钟
    RCC->APB2ENR|=1<<6;     //使能PORTE时钟
    GPIOA->CRL&=0XFFFFFFF0;    //PA0设置成输入,默认下拉      
    GPIOA->CRL|=0X00000008; 
      
    GPIOE->CRL&=0XFFF00FFF;    //PE3/4设置成输入      
    GPIOE->CRL|=0X00088000;                    
    GPIOE->ODR|=3<<3;           //PE3/4 上拉
    
    Ex_NVIC_Config(GPIO_A,0,RTIR);     //上升沿触发 
    Ex_NVIC_Config(GPIO_E,3,FTIR);     //下降沿触发
     Ex_NVIC_Config(GPIO_E,4,FTIR);     //下降沿触发
    MY_NVIC_Init(2,3,EXTI0_IRQn,2);    //抢占2,子优先级3,组2  
    MY_NVIC_Init(2,1,EXTI3_IRQn,2);    //抢占2,子优先级1,组2       
    MY_NVIC_Init(2,0,EXTI4_IRQn,2);    //抢占2,子优先级0,组2       
}
 

中断服务函数:

void EXTI0_IRQHandler(void)
{
    delay_ms(10);    //消抖
    if(WK_UP==1)    //WK_UP按键
    {                 
        //中断想要实现什么功能,可以写在这里    
    }         
    EXTI->PR=1<<0;  //清除LINE0上的中断标志位  

//外部中断3服务程序
void EXTI3_IRQHandler(void)
{
    delay_ms(10);    //消抖
    if(KEY1==0)         //按键KEY1
    {                 
       //中断想要实现什么功能,可以写在这里
    }         
    EXTI->PR=1<<3;  //清除LINE3上的中断标志位  
}
//外部中断4服务程序
void EXTI4_IRQHandler(void)
{
    delay_ms(10);    //消抖
    if(KEY0==0)         //按键KEY0
    {
             //中断想要实现什么功能,可以写在这里
    }         
    EXTI->PR=1<<4;  //清除LINE4上的中断标志位  
}

简述:

每个IO口都可以作为外部中断,

但是只有4个配置寄存器,因此同时只能配置16个IO口作为外部中断;

但是只有7个外部中断服务函数,并且不能共用,因此同时最多只能有7个外部中断。