STM32G474单片机开发入门(四)中断详解及GPIO外部中断输入

文章目录

一.概要

中断是指单片机正在处理某个事件A,发生了另一件事件B,请求单片机迅速去处理(中断发生),单片机暂时停止当前的工作(中断响应),转去处理事件B(中断服务),待单片机处理事件B完成后,再回到原来的事件A(断点)继续执行,这一过程称之为中断。

STM32单片机的中断系统支持多种中断类型,包括内部中断和外部中断。内部中断通常由处理器内部的事件引发,如定时器溢出、除零错误等,而外部中断则由外部硬件或设备触发的事件引发,如按键按下、传感器触发等。

二.可嵌套的向量中断控制器 (NVIC)

在芯片的内核里专门有一个管理中断机制的模块------NVIC(嵌套向量中断控制器)控制器。这控制器是CortexM4内核专门负责处理中断相关问题的机构,专门做中断管理相关的事务。

NVIC的核心功能是中断优先级分组、中断优先级的配置、读中断请求标志、清除中断请求标志、使能中断、清除中断等,它控制着STM32G474中断向量表中断号为0-101的102个中断,外部中断信号从核外发出,信号最终要传递到NVIC(嵌套向量中断控制器)。NVIC跟内核紧密耦合,它控制着整个芯片中断的相关功能。

三.中断向量表

在中断向量表里给我们列出了各种外部中断,黑色的图是内核的中断,这12个系统中断不能被打断也不可以设置优先级,他们的优先级是固定的,且发生事件时必须要响应,后面的图是外设相关的外部中断,STM32G4参考手册文档里有列出所有相关的中断。

程序中的中断向量表在启动文件startup_stm32g474xx.s中,代码如下:

c 复制代码
; Vector Table Mapped to Address 0 at Reset
                AREA    RESET, DATA, READONLY
                EXPORT  __Vectors
                EXPORT  __Vectors_End
                EXPORT  __Vectors_Size
__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_PVM_IRQHandler                ; PVD/PVM1/PVM2/PVM3/PVM4 through EXTI Line detection
                DCD     RTC_TAMP_LSECSS_IRQHandler        ; RTC, TAMP and RCC LSE_CSS 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
              

四.中断优先级详解

中断优先级分为抢占优先级和子优先级两部分,用于确定中断的响应顺序和执行顺序。抢占优先级用于确定中断的响应优先级,而子优先级用于确定中断的实际执行优先级。当多个中断同时触发时,系统会优先处理抢占优先级较高的中断,而在相同抢占优先级的情况下,会根据子优先级来确定中断的执行顺序

占先式优先级:当其中一个中断正在执行时,其他的中断是否可以打断正在执行的中断。

子优先级:决定当多个占先式优先级都相同且多个中断同时到来的时候,先执行哪一个中断。

优先级大小:占先式优先级>子优先级

优先级越高其对应的值越低。数字越小,优先级越高。

五.STM32外部中断控制器(EXTI)

1.EXTI简介

STM32单片机的外部中断/事件控制器(External Interrupt/Event Controller,简称EXTI),使得微控制器能够高效地响应外部事件并执行相应的任务,EXTI允许STM32微控制器对外部事件进行监测和响应,这些事件可以是来自GPIO引脚的电平变化信号。当外部事件发生时,EXTI能够立即唤醒微控制器,并执行预定义的中断服务程序(ISR)或者事件处理函数,我们接下去对EXTI外部中断进行详细介绍。

2.EXTI在中断向量表的位置

GPIO口外部中断在中断向量表中分配了16个中断向量



GPIO对应的外部中断,例如PA0,PB0,PC0对应的中断服务程序都是EXTI0_IRQHandler,一般只选其中一个引脚就可以。

程序代码中的中断服务程序一般如下:

c 复制代码
/**
  * 外部中断0的中断服务程序
  */
void EXTI0_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI0_IRQn 0 */
  /* USER CODE END EXTI0_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  /* USER CODE BEGIN EXTI0_IRQn 1 */
  /* USER CODE END EXTI0_IRQn 1 */
}

3.EXTI外部中断产生的信号流向

如下图编号1~4是外部中断的信号流向

1.编号1是GPIO的任意一个引脚,就是高低电平信号输入脚。

2.编号2是一个边沿检测电路,通过上升/下降沿触发选择器寄存器,对GPIO输入信号开启边沿信号检测,检测到了就在后面的编号3或门处给个1,而两个寄存器可以配置上升沿/下降沿,或者上升沿和下降沿都触发。

3.编号3是一个或门电路,软件中断事件寄存器由软件置位 1,这一操作会把请求挂起寄存器的相应位置1。

4.编号4是一个与门电路,中断屏蔽寄存器设置为1表示开放中断,编号 4 电路输出的信号会被保存到挂起寄存器(EXTI_PR)内,如果确定编号 4 电路输出为 1 就会把EXTI_PR(挂起寄存器) 对应位置 1,在该位中写入'1'可以清除它,也可以通过改变边沿检测的极性清除。

5.编号4出来的信号发送到内核NVIC中请求产生中断,并跳转到中断服务函数。

4.EXTI中断产生后的中断服务程序

中断向量表中的中断服务程序就是下图所示,中断产生后就会跳入对应的中断服务程序,我们应用程序就可以对中断服务程序根据需要进行修改,外部中断0的中断服务程序就是EXTI0_IRQHandler。

我们应用程序一般在stm32g4xx_it.c中对中断服务程序进行应用修改就可以。

比如PA0引脚外部中断服务程序如下:

c 复制代码
//外部中断0服务程序
void EXTI0_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI0_IRQn 0 */

  /* USER CODE END EXTI0_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  /* USER CODE BEGIN EXTI0_IRQn 1 */
  HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8);//PC8翻转输出
  /* USER CODE END EXTI0_IRQn 1 */
}

但如果是PA5引脚的外部中断服务程序,向量表中是没有EXTI5_IRQHandler这个函数,由于PA5~PA9是共用中断服务程序,所以PA5的外部中断服务程序就是

void EXTI9_5_IRQHandler(void),中断向量表中有这个函数。

在中断服务程序中,尽量放一些处理时间短的代码,尽量不要调用时间等待函数(例如HAL_Delay),因为这会阻塞整个系统,包括其他中断。如果在中断服务程序中使用HAL_Delay,可能会导致不可预测的后果,如死机、复位等。

六.CubeMX配置一个GPIO输入中断的例程

硬件准备:

STLINK接STM32G474RET6开发板,STLINK接电脑USB口。

如下图所示,打开STM32CubeMX软件,新建工程。

如下图所示,Part Number处输入STM32G474RE,再双击就创建新的工程。

如下图所示,配置下载口引脚,PA13为SWD的SWDIO脚,PA14为SWD的SWCLK脚。

如下图所示,可以查看STM32G474RET6开发板原理图,PC8连接LED灯,所以配置PC8为GPIO输出,推挽输出。

如下图所示,配置系统主频170Mhz,使用内部16MHZ晶振。

查看STM32G474RET6开发板原理图,PA0引脚跟按键相连,配置PA0引脚为外部中断0引脚,配置PA0引脚下拉,因为是上升沿产生中断,配置成下拉使能,PA0引脚初始电平就稳定,上升沿中断信号就稳。

配置外部中断使能。

配置工程文件名,保存路径,KEIL5工程输出方式,生成工程。

用Keil5打开工程。

添加代码,就能实现按下按键一次,进入中断一次,LED灯亮或者灭。

主要代码

c 复制代码
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();//SysTick配置成1ms中断

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();//内部16MHZ晶振,170MHZ系统主频

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();//PC8配置成输出,PA0配置成输入,中断上升沿触发会进入void EXTI0_IRQHandler(void)函数
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  HAL_Delay(100);//等待100ms
	
  }
  /* USER CODE END 3 */
}

//每产生一次中断,系统就会调用这函数一次
void EXTI0_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI0_IRQn 0 */

  /* USER CODE END EXTI0_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  /* USER CODE BEGIN EXTI0_IRQn 1 */
  HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8);//PC8翻转输出
  /* USER CODE END EXTI0_IRQn 1 */
}

七.小结

中断是STM32单片机开发中经常会用到的功能,对中断有了一定了解,在开发中应用中断,能使单片机的运行效率提升很多。

相关推荐
逼子格3 小时前
【Proteus仿真】虚拟终端出现乱码问题解决
单片机·嵌入式硬件·proteus·嵌入式·硬件工程·电路仿真·虚拟终端
MAR-Sky5 小时前
单片机学习中的一些简单总结
单片机·嵌入式硬件·学习
点灯小铭5 小时前
基于stm32的物联网OneNet火灾报警系统
stm32·单片机·嵌入式硬件·物联网·毕业设计·课程设计
许商13 小时前
【stm32】【edgetx】解析链接脚本文件(ld)
stm32·单片机·嵌入式硬件
云山工作室15 小时前
基于单片机的三相逆变电源设计
单片机·嵌入式硬件·毕业设计·毕设
国科安芯17 小时前
ASP3605电源芯片关键指标测试说明
功能测试·单片机·嵌入式硬件·pcb工艺
SundayBear17 小时前
LVGL 开发指南:从入门到精通的嵌入式 GUI 实战心法
单片机·嵌入式·lvgl
弘毅 失败的 mian20 小时前
利用 VsCode + EIDE 进行嵌入式开发(保姆级教程)
经验分享·笔记·vscode·stm32·单片机·嵌入式硬件·eide
小龙报21 小时前
《KelpBar海带Linux智慧屏项目》
linux·c语言·vscode·单片机·物联网·ubuntu·学习方法