【5】STM32·HAL库·中断

目录

一、什么是中断

1.1、中断的定义

1.2、中断的作用和意义

1.3、STM32 GPIO外部中断简图

二、NVIC

2.1、NVIC基本概念 

2.2、NVIC相关寄存器介绍

2.3、NVIC工作原理

2.4、STM32中断优先级基本概念

2.5、STM32中断优先级分组

2.6、STM32 NVIC的使用

2.6.1、设置中断分组

2.6.2、设置中断优先级

2.6.3、使能中断

三、EXTI

3.1、EXTI基本概念

3.2、EXTI主要特性

3.3、EXTI工作原理(F1/F4/F7)

四、EXTI和IO映射关系

4.1、SYSCFG简介(F4/F7/H7) 

4.2、EXTI与IO对应关系

五、如何使用中断

5.1、配置流程图

5.2、STM32 EXTI 的配置步骤(外部中断)

5.3、STM32 EXTI 的 HAL 库设置步骤(外部中断)

5.4、HAL库中断回调处理机制原理图

六、编程实战

通过外部中断控制一个灯亮灭


一、什么是中断

1.1、中断的定义

打断 CPU 执行正常的程序,转而处理紧急程序,然后返回原暂停的程序继续运行,就叫中断

1.2、中断的作用和意义

实时控制:在确定时间内对相应事件作出响应,如温度监控

故障处理:检测到故障,需要第一时间处理,如电梯门夹人了

数据传输:不确定数据何时会来,如串口数据接收

中断的意义:高效处理紧急程序,不会一直占用 CPU 资源

1.3、STM32 GPIO外部中断简图

二、NVIC

2.1、NVIC基本概念 

NVIC(Nested vectored interrupt controller),嵌套向量中断控制器,属于内核(M3/4/7)

NVIC 支持:256 个中断(16 内核 + 240 外部),支持:256 个优先级,允许裁剪!

中断向量表的概念

定义一块固定的内存,以 4 字节对齐,存放各个中断服务函数程序的首地址

中断向量表定义在启动文件,当发生中断,CPU 会自动执行对应的中断服务函数

在启动文件中定义的 10 个内核中断,从上往下自然优先级依次降低

                DCD     Reset_Handler              ; Reset Handler
                DCD     NMI_Handler                ; NMI Handler
                DCD     HardFault_Handler          ; Hard Fault Handler
                DCD     MemManage_Handler          ; MPU Fault Handler
                DCD     BusFault_Handler           ; Bus Fault Handler
                DCD     UsageFault_Handler         ; Usage Fault Handler
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     SVC_Handler                ; SVCall Handler
                DCD     DebugMon_Handler           ; Debug Monitor Handler
                DCD     0                          ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler
                DCD     SysTick_Handler            ; SysTick Handler

在启动文件中定义的 82 个外部中断,从上往下自然优先级依次降低

                DCD     WWDG_IRQHandler                   ; Window WatchDog                                        
                DCD     PVD_IRQHandler                    ; PVD through EXTI Line detection                        
                DCD     TAMP_STAMP_IRQHandler             ; Tamper and TimeStamps through the EXTI line            
                DCD     RTC_WKUP_IRQHandler               ; RTC Wakeup through the EXTI line                       
                DCD     FLASH_IRQHandler                  ; FLASH                                           
                DCD     RCC_IRQHandler                    ; RCC                                             
                DCD     EXTI0_IRQHandler                  ; EXTI Line0                                             
                DCD     EXTI1_IRQHandler                  ; EXTI Line1                                             
                DCD     EXTI2_IRQHandler                  ; EXTI Line2                                             
                DCD     EXTI3_IRQHandler                  ; EXTI Line3                                             
                DCD     EXTI4_IRQHandler                  ; EXTI Line4                                             
                DCD     DMA1_Stream0_IRQHandler           ; DMA1 Stream 0                                   
                DCD     DMA1_Stream1_IRQHandler           ; DMA1 Stream 1                                   
                DCD     DMA1_Stream2_IRQHandler           ; DMA1 Stream 2                                   
                DCD     DMA1_Stream3_IRQHandler           ; DMA1 Stream 3                                   
                DCD     DMA1_Stream4_IRQHandler           ; DMA1 Stream 4                                   
                DCD     DMA1_Stream5_IRQHandler           ; DMA1 Stream 5                                   
                DCD     DMA1_Stream6_IRQHandler           ; DMA1 Stream 6                                   
                DCD     ADC_IRQHandler                    ; ADC1, ADC2 and ADC3s                            
                DCD     CAN1_TX_IRQHandler                ; CAN1 TX                                                
                DCD     CAN1_RX0_IRQHandler               ; CAN1 RX0                                               
                DCD     CAN1_RX1_IRQHandler               ; CAN1 RX1                                               
                DCD     CAN1_SCE_IRQHandler               ; CAN1 SCE                                               
                DCD     EXTI9_5_IRQHandler                ; External Line[9:5]s                                    
                DCD     TIM1_BRK_TIM9_IRQHandler          ; TIM1 Break and TIM9                   
                DCD     TIM1_UP_TIM10_IRQHandler          ; TIM1 Update and TIM10                 
                DCD     TIM1_TRG_COM_TIM11_IRQHandler     ; TIM1 Trigger and Commutation and TIM11
                DCD     TIM1_CC_IRQHandler                ; TIM1 Capture Compare                                   
                DCD     TIM2_IRQHandler                   ; TIM2                                            
                DCD     TIM3_IRQHandler                   ; TIM3                                            
                DCD     TIM4_IRQHandler                   ; TIM4                                            
                DCD     I2C1_EV_IRQHandler                ; I2C1 Event                                             
                DCD     I2C1_ER_IRQHandler                ; I2C1 Error                                             
                DCD     I2C2_EV_IRQHandler                ; I2C2 Event                                             
                DCD     I2C2_ER_IRQHandler                ; I2C2 Error                                               
                DCD     SPI1_IRQHandler                   ; SPI1                                            
                DCD     SPI2_IRQHandler                   ; SPI2                                            
                DCD     USART1_IRQHandler                 ; USART1                                          
                DCD     USART2_IRQHandler                 ; USART2                                          
                DCD     USART3_IRQHandler                 ; USART3                                          
                DCD     EXTI15_10_IRQHandler              ; External Line[15:10]s                                  
                DCD     RTC_Alarm_IRQHandler              ; RTC Alarm (A and B) through EXTI Line                  
                DCD     OTG_FS_WKUP_IRQHandler            ; USB OTG FS Wakeup through EXTI line                        
                DCD     TIM8_BRK_TIM12_IRQHandler         ; TIM8 Break and TIM12                  
                DCD     TIM8_UP_TIM13_IRQHandler          ; TIM8 Update and TIM13                 
                DCD     TIM8_TRG_COM_TIM14_IRQHandler     ; TIM8 Trigger and Commutation and TIM14
                DCD     TIM8_CC_IRQHandler                ; TIM8 Capture Compare                                   
                DCD     DMA1_Stream7_IRQHandler           ; DMA1 Stream7                                           
                DCD     FMC_IRQHandler                    ; FMC                                             
                DCD     SDIO_IRQHandler                   ; SDIO                                            
                DCD     TIM5_IRQHandler                   ; TIM5                                            
                DCD     SPI3_IRQHandler                   ; SPI3                                            
                DCD     UART4_IRQHandler                  ; UART4                                           
                DCD     UART5_IRQHandler                  ; UART5                                           
                DCD     TIM6_DAC_IRQHandler               ; TIM6 and DAC1&2 underrun errors                   
                DCD     TIM7_IRQHandler                   ; TIM7                   
                DCD     DMA2_Stream0_IRQHandler           ; DMA2 Stream 0                                   
                DCD     DMA2_Stream1_IRQHandler           ; DMA2 Stream 1                                   
                DCD     DMA2_Stream2_IRQHandler           ; DMA2 Stream 2                                   
                DCD     DMA2_Stream3_IRQHandler           ; DMA2 Stream 3                                   
                DCD     DMA2_Stream4_IRQHandler           ; DMA2 Stream 4                                   
                DCD     ETH_IRQHandler                    ; Ethernet                                        
                DCD     ETH_WKUP_IRQHandler               ; Ethernet Wakeup through EXTI line                      
                DCD     CAN2_TX_IRQHandler                ; CAN2 TX                                                
                DCD     CAN2_RX0_IRQHandler               ; CAN2 RX0                                               
                DCD     CAN2_RX1_IRQHandler               ; CAN2 RX1                                               
                DCD     CAN2_SCE_IRQHandler               ; CAN2 SCE                                               
                DCD     OTG_FS_IRQHandler                 ; USB OTG FS                                      
                DCD     DMA2_Stream5_IRQHandler           ; DMA2 Stream 5                                   
                DCD     DMA2_Stream6_IRQHandler           ; DMA2 Stream 6                                   
                DCD     DMA2_Stream7_IRQHandler           ; DMA2 Stream 7                                   
                DCD     USART6_IRQHandler                 ; USART6                                           
                DCD     I2C3_EV_IRQHandler                ; I2C3 event                                             
                DCD     I2C3_ER_IRQHandler                ; I2C3 error                                             
                DCD     OTG_HS_EP1_OUT_IRQHandler         ; USB OTG HS End Point 1 Out                      
                DCD     OTG_HS_EP1_IN_IRQHandler          ; USB OTG HS End Point 1 In                       
                DCD     OTG_HS_WKUP_IRQHandler            ; USB OTG HS Wakeup through EXTI                         
                DCD     OTG_HS_IRQHandler                 ; USB OTG HS                                      
                DCD     DCMI_IRQHandler                   ; DCMI  
                DCD     0                                 ; Reserved				                              
                DCD     HASH_RNG_IRQHandler               ; Hash and Rng
                DCD     FPU_IRQHandler                    ; FPU

2.2、NVIC相关寄存器介绍

NVIC 还有:中断挂起,解挂,激活标志等非常用功能,不做介绍!

2.3、NVIC工作原理

2.4、STM32中断优先级基本概念

1,抢占优先级(pre):高抢占优先级可以打断正在执行的低抢占优先级中断

2,响应优先级(sub):当抢占优先级相同时,响应优先级高的先执行,但是不能互相打断

3,抢占和响应都相同的情况下,自然优先级越高的,先执行

4,自然优先级:中断向量表的优先级

5,数值越小,表示优先级越高

2.5、STM32中断优先级分组

特别提示:一个工程中,一般只设置一次中断优先级分组

举个例子,中断优先级分组设置为 2

EXTI1 和 RTC 可以打断:EXTI0 和 Systick 的中断,获得优先执行!

2.6、STM32 NVIC的使用

2.6.1、设置中断分组

HAL库驱动函数:HAL_NVIC_SetPriorityGrouping()

/**
  * @brief  Sets the priority grouping field (preemption priority and subpriority)
  *         using the required unlock sequence.
  * @param  PriorityGroup The priority grouping bits length. 
  *         This parameter can be one of the following values:
  *         @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
  *                                    4 bits for subpriority
  *         @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
  *                                    3 bits for subpriority
  *         @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
  *                                    2 bits for subpriority
  *         @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
  *                                    1 bits for subpriority
  *         @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
  *                                    0 bits for subpriority
  * @note   When the NVIC_PriorityGroup_0 is selected, IRQ preemption is no more possible. 
  *         The pending IRQ priority will be managed only by the subpriority. 
  * @retval None
  */
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup);

对应的可选参数有

/** @defgroup CORTEX_Preemption_Priority_Group CORTEX Preemption Priority Group
  * @{
  */
#define NVIC_PRIORITYGROUP_0         0x00000007U /*!< 0 bits for pre-emption priority
                                                      4 bits for subpriority */
#define NVIC_PRIORITYGROUP_1         0x00000006U /*!< 1 bits for pre-emption priority
                                                      3 bits for subpriority */
#define NVIC_PRIORITYGROUP_2         0x00000005U /*!< 2 bits for pre-emption priority
                                                      2 bits for subpriority */
#define NVIC_PRIORITYGROUP_3         0x00000004U /*!< 3 bits for pre-emption priority
                                                      1 bits for subpriority */
#define NVIC_PRIORITYGROUP_4         0x00000003U /*!< 4 bits for pre-emption priority
                                                      0 bits for subpriority */

特别提醒:例程中,中断分组已经在 HAL_Init() 函数中设置了分组 2

2.6.2、设置中断优先级

HAL库驱动函数:HAL_NVIC_SetPriority()

/**
  * @brief  Sets the priority of an interrupt.
  * @param  IRQn External interrupt number.
  *         This parameter can be an enumerator of IRQn_Type enumeration
  *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
  * @param  PreemptPriority The preemption priority for the IRQn channel.
  *         This parameter can be a value between 0 and 15
  *         A lower priority value indicates a higher priority 
  * @param  SubPriority the subpriority level for the IRQ channel.
  *         This parameter can be a value between 0 and 15
  *         A lower priority value indicates a higher priority.          
  * @retval None
  */
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority);

第一个参数 IRQn_Type IRQn

/**
 * @brief STM32F4XX Interrupt Number Definition, according to the selected device 
 *        in @ref Library_configuration_section 
 */
typedef enum
{
/******  Cortex-M4 Processor Exceptions Numbers ****************************************************************/
  NonMaskableInt_IRQn         = -14,    /*!< 2 Non Maskable Interrupt                                          */
  MemoryManagement_IRQn       = -12,    /*!< 4 Cortex-M4 Memory Management Interrupt                           */
  BusFault_IRQn               = -11,    /*!< 5 Cortex-M4 Bus Fault Interrupt                                   */
  UsageFault_IRQn             = -10,    /*!< 6 Cortex-M4 Usage Fault Interrupt                                 */
  SVCall_IRQn                 = -5,     /*!< 11 Cortex-M4 SV Call Interrupt                                    */
  DebugMonitor_IRQn           = -4,     /*!< 12 Cortex-M4 Debug Monitor Interrupt                              */
  PendSV_IRQn                 = -2,     /*!< 14 Cortex-M4 Pend SV Interrupt                                    */
  SysTick_IRQn                = -1,     /*!< 15 Cortex-M4 System Tick Interrupt                                */
/******  STM32 specific Interrupt Numbers **********************************************************************/
  WWDG_IRQn                   = 0,      /*!< Window WatchDog Interrupt                                         */
  PVD_IRQn                    = 1,      /*!< PVD through EXTI Line detection Interrupt                         */
  TAMP_STAMP_IRQn             = 2,      /*!< Tamper and TimeStamp interrupts through the EXTI line             */
  RTC_WKUP_IRQn               = 3,      /*!< RTC Wakeup interrupt through the EXTI line                        */
  FLASH_IRQn                  = 4,      /*!< FLASH global Interrupt                                            */
  RCC_IRQn                    = 5,      /*!< RCC global Interrupt                                              */
  EXTI0_IRQn                  = 6,      /*!< EXTI Line0 Interrupt                                              */
  EXTI1_IRQn                  = 7,      /*!< EXTI Line1 Interrupt                                              */
  EXTI2_IRQn                  = 8,      /*!< EXTI Line2 Interrupt                                              */
  EXTI3_IRQn                  = 9,      /*!< EXTI Line3 Interrupt                                              */
  EXTI4_IRQn                  = 10,     /*!< EXTI Line4 Interrupt                                              */
  DMA1_Stream0_IRQn           = 11,     /*!< DMA1 Stream 0 global Interrupt                                    */
  DMA1_Stream1_IRQn           = 12,     /*!< DMA1 Stream 1 global Interrupt                                    */
  DMA1_Stream2_IRQn           = 13,     /*!< DMA1 Stream 2 global Interrupt                                    */
  DMA1_Stream3_IRQn           = 14,     /*!< DMA1 Stream 3 global Interrupt                                    */
  DMA1_Stream4_IRQn           = 15,     /*!< DMA1 Stream 4 global Interrupt                                    */
  DMA1_Stream5_IRQn           = 16,     /*!< DMA1 Stream 5 global Interrupt                                    */
  DMA1_Stream6_IRQn           = 17,     /*!< DMA1 Stream 6 global Interrupt                                    */
  ADC_IRQn                    = 18,     /*!< ADC1, ADC2 and ADC3 global Interrupts                             */
  CAN1_TX_IRQn                = 19,     /*!< CAN1 TX Interrupt                                                 */
  CAN1_RX0_IRQn               = 20,     /*!< CAN1 RX0 Interrupt                                                */
  CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                                */
  CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                                */
  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                                     */
  TIM1_BRK_TIM9_IRQn          = 24,     /*!< TIM1 Break interrupt and TIM9 global interrupt                    */
  TIM1_UP_TIM10_IRQn          = 25,     /*!< TIM1 Update Interrupt and TIM10 global interrupt                  */
  TIM1_TRG_COM_TIM11_IRQn     = 26,     /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */
  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                                    */
  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                             */
  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                             */
  TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                             */
  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                              */
  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                              */
  I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                              */
  I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                              */
  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                             */
  SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                             */
  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                                           */
  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                                           */
  USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                                           */
  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                                   */
  RTC_Alarm_IRQn              = 41,     /*!< RTC Alarm (A and B) through EXTI Line Interrupt                   */
  OTG_FS_WKUP_IRQn            = 42,     /*!< USB OTG FS Wakeup through EXTI line interrupt                     */
  TIM8_BRK_TIM12_IRQn         = 43,     /*!< TIM8 Break Interrupt and TIM12 global interrupt                   */
  TIM8_UP_TIM13_IRQn          = 44,     /*!< TIM8 Update Interrupt and TIM13 global interrupt                  */
  TIM8_TRG_COM_TIM14_IRQn     = 45,     /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */
  TIM8_CC_IRQn                = 46,     /*!< TIM8 Capture Compare global interrupt                             */
  DMA1_Stream7_IRQn           = 47,     /*!< DMA1 Stream7 Interrupt                                            */
  FSMC_IRQn                   = 48,     /*!< FSMC global Interrupt                                             */
  SDIO_IRQn                   = 49,     /*!< SDIO global Interrupt                                             */
  TIM5_IRQn                   = 50,     /*!< TIM5 global Interrupt                                             */
  SPI3_IRQn                   = 51,     /*!< SPI3 global Interrupt                                             */
  UART4_IRQn                  = 52,     /*!< UART4 global Interrupt                                            */
  UART5_IRQn                  = 53,     /*!< UART5 global Interrupt                                            */
  TIM6_DAC_IRQn               = 54,     /*!< TIM6 global and DAC1&2 underrun error  interrupts                 */
  TIM7_IRQn                   = 55,     /*!< TIM7 global interrupt                                             */
  DMA2_Stream0_IRQn           = 56,     /*!< DMA2 Stream 0 global Interrupt                                    */
  DMA2_Stream1_IRQn           = 57,     /*!< DMA2 Stream 1 global Interrupt                                    */
  DMA2_Stream2_IRQn           = 58,     /*!< DMA2 Stream 2 global Interrupt                                    */
  DMA2_Stream3_IRQn           = 59,     /*!< DMA2 Stream 3 global Interrupt                                    */
  DMA2_Stream4_IRQn           = 60,     /*!< DMA2 Stream 4 global Interrupt                                    */
  ETH_IRQn                    = 61,     /*!< Ethernet global Interrupt                                         */
  ETH_WKUP_IRQn               = 62,     /*!< Ethernet Wakeup through EXTI line Interrupt                       */
  CAN2_TX_IRQn                = 63,     /*!< CAN2 TX Interrupt                                                 */
  CAN2_RX0_IRQn               = 64,     /*!< CAN2 RX0 Interrupt                                                */
  CAN2_RX1_IRQn               = 65,     /*!< CAN2 RX1 Interrupt                                                */
  CAN2_SCE_IRQn               = 66,     /*!< CAN2 SCE Interrupt                                                */
  OTG_FS_IRQn                 = 67,     /*!< USB OTG FS global Interrupt                                       */
  DMA2_Stream5_IRQn           = 68,     /*!< DMA2 Stream 5 global interrupt                                    */
  DMA2_Stream6_IRQn           = 69,     /*!< DMA2 Stream 6 global interrupt                                    */
  DMA2_Stream7_IRQn           = 70,     /*!< DMA2 Stream 7 global interrupt                                    */
  USART6_IRQn                 = 71,     /*!< USART6 global interrupt                                           */
  I2C3_EV_IRQn                = 72,     /*!< I2C3 event interrupt                                              */
  I2C3_ER_IRQn                = 73,     /*!< I2C3 error interrupt                                              */
  OTG_HS_EP1_OUT_IRQn         = 74,     /*!< USB OTG HS End Point 1 Out global interrupt                       */
  OTG_HS_EP1_IN_IRQn          = 75,     /*!< USB OTG HS End Point 1 In global interrupt                        */
  OTG_HS_WKUP_IRQn            = 76,     /*!< USB OTG HS Wakeup through EXTI interrupt                          */
  OTG_HS_IRQn                 = 77,     /*!< USB OTG HS global interrupt                                       */
  DCMI_IRQn                   = 78,     /*!< DCMI global interrupt                                             */
  RNG_IRQn                    = 80,     /*!< RNG global Interrupt                                              */
  FPU_IRQn                    = 81      /*!< FPU global interrupt                                               */
} IRQn_Type;

这是一个枚举类型,内容包括 10 个内核中断和 82 个外部中断

后面两个参数 uint32_t PreemptPriority 和 uint32_t SubPriority 分别是抢占优先级和响应优先级

2.6.3、使能中断

HAL库驱动函数:HAL_NVIC_EnableIRQ()

/**
  * @brief  Enables a device specific interrupt in the NVIC interrupt controller.
  * @note   To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
  *         function should be called before. 
  * @param  IRQn External interrupt number.
  *         This parameter can be an enumerator of IRQn_Type enumeration
  *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
  * @retval None
  */
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn);

参数和上面的第一个参数完全一样,包括 10 个内核中断和 82 个外部中断

三、EXTI

3.1、EXTI基本概念

EXTI(External(Extended) interrupt/event Controller),外部(扩展)中断事件控制器

包含 23 个产生事件/中断请求的边沿检测器,即总共:23 条 EXTI 线(F4)

中断和事件的理解

中断:要进入 NVIC,有相应的中断服务函数,需要 CPU 处理

事件:不进入 NVIC,仅用于内部硬件自动控制的,如:TIM、DMA、ADC 

3.2、EXTI主要特性

F1/F4/F7 系列

每条 EXTI 线都可以单独配置:选择类型(中断或者事件)、触发方式(上升沿,下降沿或者双边沿触发)、支持软件触发、开启/屏蔽、有挂起状态位

H7 系列

由其它外设对 EXTI 产生的事件分为可配置事件和直接事件

可配置事件:简单概括,基本和 F1/F4/F7 系列类似

直接事件:固定上升沿触发、不支持软件触发、无挂起状态位(由其它外设提供)

3.3、EXTI工作原理(F1/F4/F7)

① 边沿检测

② 软件触发

③ 中断屏蔽/清除

④ 事件屏蔽

常用的寄存器有:EXTI_FTSREXTI_RTSREXTI_IMREXTI_PR

四、EXTI和IO映射关系

4.1、SYSCFG简介(F4/F7/H7) 

SYSCFG(System configuration controller),即系统配置控制器,用于外部中断映射配置等

外部中断配置寄存器 SYSCFG_EXTICR 1~4,配置 EXTI 中断线 0~15 对应具体哪个 IO 口

特别注意:配置 SYSCFG 寄存器之前要使能 SYSCFG 时钟,方法如下

__HAL_RCC_SYSCFG_CLK_ENABLE();

4.2、EXTI与IO对应关系

AFIO_EXTICR1 的 EXTI0[3:0] 位控制(F1)

SYSCFG_EXTICR1 的 EXTI0[3:0] 位控制(F4/F7/H7)

Px0映射到EXTI0

Px1映射到EXTI1

...

Px14映射到EXTI14

Px15映射到EXTI15

五、如何使用中断

5.1、配置流程图

5.2、STM32 EXTI 的配置步骤(外部中断)

1、使能 GPIO 时钟

2、设置 GPIO 输入模式,上/下拉/浮空输入

3、使能 SYSCFG 时钟,设置 SYSCFG 时钟开启寄存器

4、设置 EXTI 和 IO 对应关系,选择 PA~PK 其中某组 IO 对应 EXTI 输入线,SYSCFG_EXTICR

5、设置 EXTI 对应通道的屏蔽和上升沿/下降沿触发,IMR、RTSR/FTSR

6、设置 NVIC,分三步:设置优先级分组、设置优先级、使能中断

7、设计中断服务函数,编写对应中断的中断服务函数,清除中断标志位

注意:步骤 2 - 5,使用 HAL_GPIO_Init() 一步到位

5.3、STM32 EXTI 的 HAL 库设置步骤(外部中断)

1、使能 GPIO 时钟:使用 __HAL_RCC_GPIOx_CLK_ENABLE()

2、GPIO/SYSCFG/EXTI:使用 HAL_GPIO_Init()

3、设置中断分组:使用 HAL_NVIC_SetPriorityGrouping(),此函数仅需设置一次

4、设置中断优先级:使用 HAL_NVIC_SetPriority()

5、使能中断:使用 HAL_NVIC_EnableIRQ()

6、设计中断服务函数:编写 EXTIx_IRQHandler() 中断服务函数,清除中断标志位

STM32仅有:EXTI0~4、EXTI9_5、EXTI15_10,7个外部中断服务函数

5.4、HAL库中断回调处理机制原理图

六、编程实战

通过外部中断控制一个灯亮灭

main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
#include "./BSP/EXTI/exti.h"

int main(void)
{
    HAL_Init();                         // 初始化HAL库
    sys_stm32_clock_init(336, 8, 2, 7); // 设置时钟,168Mhz
    delay_init(168);                    // 延时初始化
    led_init();                         // 初始化LED
    key_init();                         // 初始化按键
    extix_init();                       // 初始化外部中断输入
    LED0(0);                            // 先点亮红灯

    while (1)
    {
        delay_ms(1000);
    }
}

由于 KEY0 和 KEY1 共用了同一个外部中断服务函数 EXTI9_5_IRQHandler(),进入该中断服务函数后还需要通过 EXTI_PR 寄存器来判断具体是哪个中断线触发的

exti.c

#include "./BSP/EXTI/exti.h"

/* 外部中断初始化程序 */
void extix_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;

    key_init();
    gpio_init_struct.Pin = KEY0_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_IT_FALLING; /* 下降沿触发 */
    gpio_init_struct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(KEY0_GPIO_PORT, &gpio_init_struct); /* KEY0配置为下降沿触发中断 */

    gpio_init_struct.Pin = KEY1_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_IT_FALLING; /* 下降沿触发 */
    gpio_init_struct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(KEY1_GPIO_PORT, &gpio_init_struct); /* KEY1配置为下降沿触发中断 */

    gpio_init_struct.Pin = WKUP_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_IT_RISING; /* 上升沿触发 */
    gpio_init_struct.Pull = GPIO_PULLDOWN;
    HAL_GPIO_Init(WKUP_GPIO_PORT, &gpio_init_struct); /* WKUP配置为上升沿触发中断 */

    HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 2); /* 抢占0,子优先级2 */
    HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);         /* 使能中断线4 */

    HAL_NVIC_SetPriority(EXTI0_IRQn, 1, 2); /* 抢占3,子优先级2 */
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);         /* 使能中断线0 */
}

/* KEY0 KEY1 外部中断服务程序 */
void EXTI9_5_IRQHandler(void)
{
    if (__HAL_GPIO_EXTI_GET_IT(KEY0_GPIO_PIN) != RESET) /* 判断发现是KEY0中断线触发 */
    {
        HAL_GPIO_EXTI_IRQHandler(KEY0_GPIO_PIN); /* 调用中断处理公用函数 清除KEY0所在中断线 的中断标志位 */
        __HAL_GPIO_EXTI_CLEAR_IT(KEY0_GPIO_PIN); /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
    }
    if (__HAL_GPIO_EXTI_GET_IT(KEY1_GPIO_PIN) != RESET) /* 判断发现是KEY1中断线触发 */
    {
        HAL_GPIO_EXTI_IRQHandler(KEY1_GPIO_PIN); /* 调用中断处理公用函数 清除KEY0所在中断线 的中断标志位 */
        __HAL_GPIO_EXTI_CLEAR_IT(KEY1_GPIO_PIN); /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
    }
}

/* WK_UP 外部中断服务程序 */
void EXTI0_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(WKUP_GPIO_PIN); /* 调用中断处理公用函数 清除KEY_UP所在中断线 的中断标志位,中断下半部在HAL_GPIO_EXTI_Callback执行 */
    __HAL_GPIO_EXTI_CLEAR_IT(WKUP_GPIO_PIN); /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
}

/* 中断服务程序中需要做的事情,在HAL库中所有的外部中断服务函数都会调用此函数 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    delay_ms(20); /* 消抖 */
    switch (GPIO_Pin)
    {
    case KEY0_GPIO_PIN:
        if (KEY0 == 0)
        {
            LED0_TOGGLE(); /* LED0 状态取反 */
        }
        break;

    case KEY1_GPIO_PIN:
        if (KEY1 == 0)
        {
            LED1_TOGGLE(); /* LED1 状态取反 */
        }
        break;

    case WKUP_GPIO_PIN:
        if (WK_UP == 1)
        {
            LED0_TOGGLE(); /* LED0 状态取反 */
            LED1_TOGGLE(); /* LED1 状态取反 */
        }
        break;

    default:
        break;
    }
}

exti.c 中使用的宏定义在上一章【4】STM32·HAL库·GPIO 的 key.h 对应,这里直接引入就好了

exti.h

#ifndef __EXTI_H
#define __EXTI_H

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/KEY/key.h"
#include "./BSP/LED/led.h"

void extix_init(void); /* 外部中断初始化 */

#endif
  • 31
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HZU_Puzzle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值