常用库函数
    ①void SYSCFGEXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex);
    //设置IO口与中断线的映射关系
    exp: SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);//区别M3
    ②void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
    //_初始化中断线:触发方式等
    ③ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
    //判断中断线中断状态,是否发生
    ④void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
    //清除中断线上的中断标志位
    ⑤RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟
    //这个函数非常重要,在使用外部中断的时候一定要先使能SYSCFG时钟

    EXTI_Init 需要用到的结构体
    typedef struct
    {
    uint32_t EXTI_Line; //指定要配置的中断线
    EXTIMode_TypeDef EXTI_Mode; //模式:事件 OR中断
    EXTITrigger_TypeDef EXTI_Trigger;//触发方式:上升沿/下降沿/双沿触发
    FunctionalState EXTI_LineCmd; //使能 OR失能
    }EXTI_InitTypeDef;

    uint32_t EXTI_Line 可选参数 在 stm32xxf4_exti.h 105行~127行
    EXTIMode_TypeDef EXTI_Mode 可选项 在 54行~58行
    EXTITrigger_TypeDef EXTI_Trigger 66-71
    FunctionalState EXTI_LineCmd ENABLE & DISABLE

    一般步骤
    ①使能SYSCFG时钟:

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    ② 初始化IO口为输入。

    GPIO_Init();

    ③设置IO口与中断线的映射关系。
    void SYSCFG_EXTILineConfig();
    ④初始化线上中断,设置触发条件等。

    EXTI_Init();
    ⑤配置中断分组(NVIC),并使能中断。

    NVIC_Init();

    编写中断服务函数。

    EXTIx_IRQHandler();
    ⑦清除中断标志位
    EXTI_ClearITPendingBit();

    exti.h

    1. #include "stm32f4xx.h" // 将ST公司标准固件库头文件包含进来
    2. #include "led.h"
    3. #include "beep.h"
    4. #include "delay.h"
    5. #include "key.h"
    6. void EXTIX_Init(void); //外部中断初始化

    exti.c

    1. #include "exti.h" // 将接口驱动程序头文件包含进来
    2. //接口驱动函数定义
    3. void EXTI0_IRQHandler(void)
    4. {
    5. delay_ms(10); //消抖
    6. if(WK_UP==1)
    7. {
    8. BEEP=!BEEP; //蜂鸣器翻转
    9. }
    10. EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位
    11. }
    12. void EXTI2_IRQHandler(void)
    13. {
    14. delay_ms(10); //消抖
    15. if(KEY2==0)
    16. {
    17. LED0=!LED0;
    18. }
    19. EXTI_ClearITPendingBit(EXTI_Line2);//清除LINE2上的中断标志位
    20. }
    21. //外部中断3服务程序
    22. void EXTI3_IRQHandler(void)
    23. {
    24. delay_ms(10); //消抖
    25. if(KEY1==0)
    26. {
    27. LED1=!LED1;
    28. }
    29. EXTI_ClearITPendingBit(EXTI_Line3); //清除LINE3上的中断标志位
    30. }
    31. void EXTI4_IRQHandler(void)
    32. {
    33. delay_ms(10); //消抖
    34. if(KEY0==0)
    35. {
    36. LED0=!LED0;
    37. LED1=!LED1;
    38. }
    39. EXTI_ClearITPendingBit(EXTI_Line4);//清除LINE4上的中断标志位
    40. }
    41. void EXTIX_Init(void)
    42. {
    43. NVIC_InitTypeDef NVIC_InitStructure;
    44. EXTI_InitTypeDef EXTI_InitStructure;
    45. KEY_Init(); //按键对应的IO口初始化
    46. RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟
    47. SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);//PE2 连接到中断线2
    48. SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);//PE3 连接到中断线3
    49. SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);//PE4 连接到中断线4
    50. SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);//PA0 连接到中断线0
    51. /* 配置EXTI_Line0 */
    52. EXTI_InitStructure.EXTI_Line = EXTI_Line0;//LINE0
    53. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件
    54. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发
    55. EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能LINE0
    56. EXTI_Init(&EXTI_InitStructure);//配置
    57. /* 配置EXTI_Line2,3,4 */
    58. EXTI_InitStructure.EXTI_Line = EXTI_Line2 | EXTI_Line3 | EXTI_Line4;
    59. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件
    60. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
    61. EXTI_InitStructure.EXTI_LineCmd = ENABLE;//中断线使能
    62. EXTI_Init(&EXTI_InitStructure);//配置
    63. NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//外部中断0
    64. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//抢占优先级0
    65. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级2
    66. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
    67. NVIC_Init(&NVIC_InitStructure);//配置
    68. NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//外部中断2
    69. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;//抢占优先级3
    70. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级2
    71. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
    72. NVIC_Init(&NVIC_InitStructure);//配置
    73. NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;//外部中断3
    74. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//抢占优先级2
    75. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级2
    76. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
    77. NVIC_Init(&NVIC_InitStructure);//配置
    78. NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;//外部中断4
    79. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;//抢占优先级1
    80. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级2
    81. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
    82. NVIC_Init(&NVIC_InitStructure);//配置
    83. }

    main.c

    1. #include "exti.h"
    2. int main(void)
    3. {
    4. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
    5. delay_init(168); //初始化延时函数
    6. LED_Init(); //初始化LED端口
    7. BEEP_Init(); //初始化蜂鸣器端口
    8. EXTIX_Init(); //初始化外部中断输入
    9. LED0=0; //先点亮红灯
    10. while(1)
    11. {
    12. }
    13. }

    结果 同 按键检测的那个