夜深人静学32系列10——GPIO中断/NVIC/EXTI/SYSCFG详解,外部中断控制LED

上期我们学习了GPIO驱动数码管/蜂鸣器/LED和按键等外设,本期我们一起来学习STM32中断的相关内容

什么是中断?

当CPU正在处理某个事件的时候,外界发生了紧急事件请求,CPU需要暂停当前的工作,转而去处理这个紧急事件,处理完之后,再次回到之前被中断的地方,继续执行原来的工作,这样的过程就叫做中断。

具体内容可以去看 “蓝桥杯单片机学习5——外部中断” ,我有详细的介绍过!

中断的意义

在这里插入图片描述

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

GPIO外部中断的中断简图

在51单片机的学习中,我们了解过外部中断的相关概念,在STM32中,我们也有外部中断的概念
在这里插入图片描述
不同于51单片机,要实现一个完整的外部中断,需要经历图上的四个步骤,下面我将详细的介绍每一个环节,首先我们从NVIC开始。

NVIC

什么是NVIC?

NVIC:Nested vectored interrupt controller,中文名称:嵌套向量中断控制器,属于内核(M3/4/7),最多可支持对256种(16个内核中断和240个外部中断)中断的控制,可设置256个中断优先级,允许厂商根据产品需要对其进行裁剪

在我们的NANO板子中,使用了62个中断10个内核中断+52个外部中断),最多支持16个优先级(使用4位中断优先级),

中断向量表

中断向量表就是在内存中定义了一段空间,以四字节对齐的方式,按照中断编号顺序存放每一个中断服务函数的首地址

中断向量表定义在启动文件,当发生中断,CPU会判断中断源,通过中断向量表进入到对应的中断服务函数中。

以下是NANO板的中断向量表全部内容,在STM32F411参考手册的201~203页

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码

__Vectors       DCD     __initial_sp               ; Top of Stack
                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

                ; External Interrupts
                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     0                                 ; Reserved                                                
                DCD     0                                 ; Reserved                                               
                DCD     0                                 ; Reserved                                             
                DCD     0                                 ; Reserved                                               
                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     0                                 ; Reserved                                          
                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     0                                 ; Reserved                  
                DCD     0                                 ; Reserved                 
                DCD     0                                 ; Reserved
                DCD     0                                 ; Reserved                                   
                DCD     DMA1_Stream7_IRQHandler           ; DMA1 Stream7                                           
                DCD     0                                 ; Reserved                                             
                DCD     SDIO_IRQHandler                   ; SDIO                                            
                DCD     TIM5_IRQHandler                   ; TIM5                                            
                DCD     SPI3_IRQHandler                   ; SPI3                                            
                DCD     0                                 ; Reserved                                           
                DCD     0                                 ; Reserved                                           
                DCD     0                                 ; Reserved                   
                DCD     0                                 ; Reserved                   
                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     0                                 ; Reserved  
                DCD     0                                 ; Reserved  
                DCD     0                                 ; Reserved                                              
                DCD     0                                 ; Reserved                                               
                DCD     0                                 ; Reserved                                               
                DCD     0                                 ; Reserved                                               
                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     0                                 ; Reserved                     
                DCD     0                                 ; Reserved                       
                DCD     0                                 ; Reserved                         
                DCD     0                                 ; Reserved                                    
                DCD     0                                 ; Reserved  
                DCD     0                                 ; Reserved				                              
                DCD     0                                 ; Reserved
                DCD     FPU_IRQHandler                    ; FPU
                DCD     0                                 ; Reserved
		        DCD     0                                 ; Reserved
		        DCD     SPI4_IRQHandler                   ; SPI4
				DCD     SPI5_IRQHandler                   ; SPI5
                                         
__Vectors_End

NVIC寄存器

NVIC的相关寄存器主要包括以下几个:

寄存器有效位数数量功能
中断使能寄存器(ISER)328每一个位控制一个中断使能
中断除能寄存器(ICER)328每一个位控制一个中断除能
中断挂起寄存器(ISPR)328每一个位控制一个中断挂起
中断解挂寄存器(ICPR)328每一个位控制一个中断解挂
中断活动位寄存器(IABP)328只读寄存器,每一个位对应一个中断的状态
中断优先级寄存器(IPR)[7:4]240每一个寄存器对应一个中断的优先级
软件触发中断寄存器(STIR)81写入0~239,可直接触发对应中断
应用程序中断及复位控制寄存器(AIRCR)[10:8]1设置中断优先级分组

中断使能寄存器:Interrupt set-enable registers (NVIC_ISERx)

在这里插入图片描述
一共有8个这样的中断使能寄存器(8*32 = 256),可控制256个中断的使能,在对应位写入1可以使能对应的中断

中断除能寄存器:Interrupt clear-enable registers (NVIC_ICERx)

在这里插入图片描述
同样有8个这样的寄存器,功能与上面相反。

中断挂起寄存器:Interrupt set-pending registers (NVIC_ISPRx)

当产生了一个中断请求,但是CPU无法响应时(比如CPU在执行优先级更高的中断),中断挂起寄存器的对应位会被置1,知道中断执行相应的中断服务函数后清零(也可以手动清零,通过中断解挂寄存器)。
在这里插入图片描述
有八个这样的寄存器,分别控制每一个中断的挂起。写入1时,挂起对应中断

中断解挂寄存器:Interrupt clear-pending registers (NVIC_ICPRx)

有挂起寄存器,那么对应的就会有解挂寄存器。

在这里插入图片描述
有八个这样的寄存器,分别控制每一个中断的解挂。写入1时,解挂对应中断

中断活动位寄存器:Interrupt active bit registers (NVIC_IABRx)

在这里插入图片描述
有8个这样的寄存器,为只读寄存器,如果某中断正在被执行或者被挂起则对应位为1,否则为0。通过这个寄存器我们可以便捷的观察每个中断的状态。

中断优先级寄存器:Interrupt priority registers (NVIC_IPRx)

在这里插入图片描述
在STM32中一共有240个这样的寄存器。分别用来设置240个外部中断的优先级,每个寄存器的低八位用来设置优先级,其他位保留。前面提到过,我们的NANO板最多支持16个优先级设置,是因为NANO板中只用到了低八位中的[7:4]。其它的[3:0]保留,不做使用。

软件触发中断寄存器:Software trigger interrupt register (NVIC_STIR)

在这里插入图片描述
这个寄存器很神奇,可以控制外部中断由软件触发,在寄存器的低八位写入0~239可以控制中断号为0 ~ 239的外部中断触发,进入中断服务函数

应用程序中断及复位控制寄存器:Application interrupt and reset control register (AIRCR)

在这里插入图片描述
这个寄存器不在NVIC的相关寄存器之中,但是关系到NVIC的中断优先级分组,所以我们需要了解。其位[10:8]控制NVIC的中断优先级分组。

需要注意的是,要对该寄存器实现写入,那必须在写入的同时对高16位写入0x5FA,否则写入会失败

其他的位这里不做过多介绍。

NVIC工作原理

在这里插入图片描述
以上是NVIC的具体中作原理,其中:

  • 我们可以人为的控制外部中断的使能或失能,通过对不同中断的优先级及分组进行设置,控制CPU在面对多个中断时的相应顺序。
  • 内核中断也叫NMI(不可屏蔽中断,优先级大于外部中断),可直接被CPU响应。

STM32中断优先级概念:

1,抢占优先级(pre):高抢占优先级可以打断正在执行的低抢占优先级中断
2,响应优先级(sub):当抢占优先级相同时,响应优先级高的先执行,但是不能互相打断
3,抢占和响应都相同的情况下,自然优先级越高的,先执行
4,自然优先级:中断向量表的优先级
5,数值越小,表示优先级越高

中断优先级分组

在NANO板中一个由五种优先级分组,具体如下:
在这里插入图片描述
特别提示:一个工程中,一般只设置一次中断优先级分组。如果进行了多次优先级分组,则以最后一次设置的为准

NVIC的使用

在这里插入图片描述
以上就是NVIC的全部内容,下面我们来学习EXTI的相关内容

EXTI

EXTI基本概念

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

外部中断/事件控制器包含多达 23 个用于产生事件/中断请求的边沿检测器。每根输入线都可 单独进行配置,以选择类型(中断或事件)和相应的触发事件(上升沿触发、下降沿触发或边沿触发)。每根输入线还可单独屏蔽。挂起寄存器用于保持中断请求的状态线。

中0 ~ 15的EXTI线分别对应GPIO0 ~ 15外部中断,其他的EXTI线与事件对应关系如下:

在这里插入图片描述

主要特性

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

H7系列
由其它外设对 EXTI 产生的事件分为可配置事件和直接事件。
可配置事件:简单概括,基本和F1/F4/F7系列类似
直接事件:固定上升沿触发、不支持软件触发、无挂起状态位(由其它外设提供)

中断和事件的理解:
中断:要进入NVIC,有相应的中断服务函数,需要CPU处理
事件:不进入NVIC,仅用于内部硬件自动控制的,如:TIM、DMA、ADC

EXTI工作原理

要了解EXTI的工作原理,我们首先要了解以下EXTI的相关寄存器。

中断屏蔽寄存器:Interrupt mask register (EXTI_IMR)

在这里插入图片描述
对应位为0时屏蔽对应EXTI线上的中断请求。为1时开放对应EXTI线上的中断请求。

注意:

  • EXTI 线 19 连接到以太网唤醒事件
  • EXTI 线 20 连接到 USB OTG HS(在 FS 中配置)唤醒事件
    由于我们的NANO不是互联型的开发板,所以不存在这两个EXTI线。默认保留[20:19]

事件屏蔽寄存器:Event mask register (EXTI_EMR)

在这里插入图片描述
对应位为0时屏蔽对应EXTI线上的事件请求。为1时开放对应EXTI线上的事件请求。

上升沿触发选择寄存器:Rising trigger selection register (EXTI_RTSR)

在这里插入图片描述
对应位为0表示该中断/事件上升沿不触发,为1则表示该中断/事件上升沿触发

下降沿触发选择寄存器:Falling trigger selection register (EXTI_FTSR)

在这里插入图片描述
对应位为0表示该中断/事件下降沿不触发,为1则表示该中断/事件下降沿触发

软件中断事件寄存器:Software interrupt event register (EXTI_SWIER)

在这里插入图片描述
对应位写入1可以将请求挂起寄存器EXTI_PD对应位置1,产生中断请求。
通过清除 EXTI_PR 的对应位(写入“1”),可以清除该位为“0”。

请求挂起寄存器:Pending register (EXTI_PR)

在这里插入图片描述
对应位为1表示产生了中断请求
当在外部中断线上发生了选择的边沿事件,该位被置“1”。在此位中写入“1”可以清除它,也可以通过改变边沿检测的极性清除

以上就是EXTI的所有相关寄存器,下面我们来了解一下EXTI的具体工作原理:

在这里插入图片描述

当外部输入线有信号进来或者软件中断事件寄存器对应为被置1时,边沿检测电路会对其进行检测,如果为对应的信号沿则相关信号触发沿选择寄存器对应位被置1,后通过中断/事件屏蔽寄存器选择,时产生中断还是产生信号,还是都不产生。

EXTI与IO映射关系

SYSCFG简介(F4/F7/H7)

System configuration controller,即系统配置控制器,用于外部中断映射配置等
通过寄存器SYSCFG_EXTICR1 ~ 4,配置EXTI中断线0~15对应具体哪个IO口。

具体配置方法如下:
在这里插入图片描述

举个栗子:
SYSCFG_EXTICR1[11:8] = 0010 代表将PC2端口设置为外部中断模式

EXTI和IO映射关系

在这里插入图片描述
另外七根 EXTI 线连接方式如下:
● EXTI 线 16 连接到 PVD 输出
● EXTI 线 17 连接到 RTC 闹钟事件
● EXTI 线 18 连接到 USB OTG FS 唤醒事件
● 不连
● 不连
● EXTI 线 21 连接到 RTC 入侵和时间戳事件
● EXTI 线 22 连接到 RTC 唤醒事件

中断使用方法

在这里插入图片描述
以上时EXTI的使用方法图解,下面为具体的流程:
在这里插入图片描述
在使用HAL库开发的过程中则只需要进行以下步骤
在这里插入图片描述
STM32中EXTI5 ~ 9 共用一个中断服务函数,EXTI10 ~ 15 共用一个中断服务函数。

中断驱动方式

在这里插入图片描述

HAL库中断回调处理机制

在这里插入图片描述
在使用HAL库开发时,当断触发进入中断服务函数后,首先会调用HAL中断处理公用函数,负责清除对应的中断标志位,后调用中断回调函数,实现对不同中断源的处理

实战1——外部中断控制LED亮灭

前面我们讲了一系列中断的相关内容,下面,我们来尝试以下通过外部中断,来控制LED亮灭。

任务要求

  • 通过按键控制LED的亮灭,当按键按下时,LED的状态翻转
  • 通过按键控制蜂鸣器的开关,
  • 当蜂鸣器打开时,LED7亮起,否则熄灭

具体按键与功能关系如下:

按键功能
WKUP蜂鸣器开启,LED0状态翻转
KEY0蜂鸣器关闭,LED1状态翻转
KEY1LED2状态翻转
KEY2LED3状态翻转
蜂鸣器开启LED7打开,否则关闭

CubeMX配置

总体概览

在这里插入图片描述

端口配置

1 . WKUP配置
在这里插入图片描述
2.KEYX配置
在这里插入图片描述
3. LED/蜂鸣器配置

请参照: “ 夜深人静学32系列9——GPIO驱动数码管/蜂鸣器/按键/LED ”,这里不做介绍

4.NVIC配置在这里插入图片描述

代码实现

1.中断服务函数

void EXTI0_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI0_IRQn 0 */

  /* USER CODE END EXTI0_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(WKUP_Pin);
  /* USER CODE BEGIN EXTI0_IRQn 1 */

  /* USER CODE END EXTI0_IRQn 1 */
}

/**
  * @brief This function handles EXTI line2 interrupt.
  */
void EXTI2_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI2_IRQn 0 */

  /* USER CODE END EXTI2_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(KEY2_Pin);
  /* USER CODE BEGIN EXTI2_IRQn 1 */

  /* USER CODE END EXTI2_IRQn 1 */
}

/**
  * @brief This function handles EXTI line[9:5] interrupts.
  */
void EXTI9_5_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI9_5_IRQn 0 */

  /* USER CODE END EXTI9_5_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(KEY0_Pin);
  HAL_GPIO_EXTI_IRQHandler(KEY1_Pin);
  /* USER CODE BEGIN EXTI9_5_IRQn 1 */

  /* USER CODE END EXTI9_5_IRQn 1 */
}

2.HAL库中断公用处理函数

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)     //确认以及触发中断
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);             //清除中断标志位
    HAL_GPIO_EXTI_Callback(GPIO_Pin);               //调用中断回调函数
  }
}

3.中断回调函数



//数据处理回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if(GPIO_Pin == WKUP_Pin )       //判断中断源为WKUP中断
    {
        HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);    //改变LED0的状态
        HAL_GPIO_WritePin(BEEP_GPIO_Port,BEEP_Pin,GPIO_PIN_RESET);  //打开蜂鸣器
    }   
    if(GPIO_Pin == KEY0_Pin)        //判断中断源为KWY0中断
    {
        HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);    //改变LED1状态
        HAL_GPIO_WritePin(BEEP_GPIO_Port,BEEP_Pin,GPIO_PIN_SET);    //关闭蜂鸣器
    }
    if(GPIO_Pin == KEY1_Pin )       //判断中断源为KWY1中断
    {
        HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);    //改变LED2状态
    }
    if(GPIO_Pin == KEY2_Pin)         //判断中断源为KWY2中断
    {
        HAL_GPIO_TogglePin(LED3_GPIO_Port,LED3_Pin);   //改变LED3状态
    }
    if(HAL_GPIO_ReadPin(BEEP_GPIO_Port,BEEP_Pin) == 1)  //蜂鸣器开启,打开LED7
    {
        HAL_GPIO_WritePin(LED7_GPIO_Port,LED7_Pin,GPIO_PIN_SET);
    }
    if(HAL_GPIO_ReadPin(BEEP_GPIO_Port,BEEP_Pin) == 0)  //蜂鸣器关闭,关闭LED7
    {   
        HAL_GPIO_WritePin(LED7_GPIO_Port,LED7_Pin,GPIO_PIN_RESET);
    }
}

以上就是本次实战用到的所有代码…………

总结

中断的理论知识相当多,需要全部理解存在一定难度,但是使用CubeMX生成代码,会显得尤为简单,不过我们还是需要理解GPIO中断的相关内容,使用起来才会更加简单。

本篇内容较多,制作不易,点个赞吧…………

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不想写代码的我

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

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

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

打赏作者

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

抵扣说明:

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

余额充值