Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >STM32中断看这一篇就够了

STM32中断看这一篇就够了

作者头像
秋名山码神
发布于 2023-11-17 02:11:59
发布于 2023-11-17 02:11:59
2.8K00
代码可运行
举报
文章被收录于专栏:码神随笔码神随笔
运行总次数:0
代码可运行

1. 前言

STM32中断:

中断是一种机制,允许外部事件或者特定条件的发生打断正常的程序执行流程,从而执行特定的中断服务程序。这有助于实现实时响应和处理外部事件的能力。 STM32微控制器中的中断包括两种类型:内部中断和外部中断。

  • 内部中断:由微控制器内部的特定事件触发,例如定时器溢出、串行通信完成等。
  • 外部中断:由外部设备或者传感器触发,例如按键按下、传感器检测到特定条件等。 在STM32中,中断控制器(NVIC)负责管理和协调所有中断请求。通过配置中断优先级、使能或禁用特定中断,开发者可以实现对中断的灵活控制。

几乎每个引脚都可以单独设置中断,具体的可以去查看,《中文参考手册》。

参考资料:《STM32F10X-中文参考手册》中断和事件章节 《野火STM32手册》

2. NVIC

NVIC是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。

2.1 NVIC寄存器简介

NVIC寄存器包括以下几种功能:

  1. 中断优先级:NVIC允许针对每个可能的中断源设置优先级,通过设置优先级来确定中断的响应顺序。通常,较低的数值表示更高的优先级。
  2. 中断使能:可以通过NVIC寄存器来使能或禁用特定的中断源,以控制中断请求的触发。
  3. 中断向量表偏移寄存器:用于指定中断服务程序(ISR)的地址,当特定中断触发时,处理器会跳转到相应的中断服务程序开始执行。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef struct {
    __IO uint32_t ISER[8];       // 中断使能寄存器
    uint32_t RESERVED0[24];
    __IO uint32_t ICER[8];       // 中断清除寄存器
    uint32_t RSERVED1[24];
    __IO uint32_t ISPR[8];       // 中断使能悬起寄存器
    uint32_t RESERVED2[24];
    __IO uint32_t ICPR[8];       // 中断清除悬起寄存器
    uint32_t RESERVED3[24];
    __IO uint32_t IABR[8];       // 中断有效位寄存器
    uint32_t RESERVED4[56];
    __IO uint8_t  IP[240];       // 中断优先级寄存器(8Bit wide)
    uint32_t RESERVED5[644];
    __O  uint32_t STIR;          // 软件触发中断寄存器
}  NVIC_Type;

一般只用ISER、ICER和IP这三个寄存器,ISER用来使能中断,ICER用来失能中断,IP用来设置中断优先级

2.2 中断优先级的定义

数值越小,优先级越高, 在F103系列中,只用到了0-4,但是原则上有0-255,

用于表达优先级的这4bit,又被分组成抢占优先级和子优先级。

  1. 有多个中断同时响应,抢占优先级高的就会抢占抢占优先级低的优先得到执行
  2. 抢占优先级相同,就比较子优先级
  3. 抢占优先级和子优先级都相同的话,就比较他们的硬件中断编号,编号越小,优先级越高

2.3 优先级分组

2.3 中断编程

三个步骤:

  1. 使能外部中断
  2. 初始化NVIC_InitTypeDef结构体
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef struct {
    uint8_t NVIC_IRQChannel;                    // 中断源
    uint8_t NVIC_IRQChannelPreemptionPriority;  // 抢占优先级
    uint8_t NVIC_IRQChannelSubPriority;         // 子优先级
    FunctionalState NVIC_IRQChannelCmd;         // 中断使能或者失能
} NVIC_InitTypeDef;
  1. 编写中断服务函数,一般写在stm32f10x_it.c这个库中

3. 外部中断/事件控制器(EXTI)

外部中断/事件控制器由20个产生事件/中断请求的边沿检测器组成,每个输入线可以独立地配置输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。每个输入线都可以独立地被屏蔽。挂起寄存器保持着状态线的中断请求

3.1 EXTI功能框图

斜杠20,表示在控制器内部类似的信号线路有20个, EXTI总共有20个中断/事件线

红色代表产生中断,绿色代表产生事件

产生中断线路目的是把输入信号输入到NVIC,进一步会运行中断服务函数,实现功能,这样是软件级的。而产生事件线路目的就是传输一个脉冲信号给其他外设使用, 并且是电路级别的信号传输,属于硬件级的。

3.2 中断事件线

EXTI有20个中断/事件线,每个GPIO都可以被设置为输入线,占用EXTI0至EXTI15, 还有另外七根用于特定的外设事件,见表 EXTI中断_事件线 。

4根特定外设中断/事件线由外设触发,具体用法参考《STM32F10X-中文参考手册》中对外设的具体说明。

EXTI0至EXTI15用于GPIO,通过编程控制可以实现任意一个GPIO作为EXTI的输入源。由表 EXTI中断_事件线 可知, EXTI0可以通过AFIO的外部中断配置寄存器1(AFIO_EXTICR1)的EXTI0[3:0]位选择配置为PA0、 PB0、PC0、PD0、PE0、PF0、PG0、PH0或者PI0

3.3 EXTI初始化结构体

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef struct {
    uint32_t EXTI_Line;                 // 中断/事件线
    EXTIMode_TypeDef EXTI_Mode;         // EXTI模式
    EXTITrigger_TypeDef EXTI_Trigger;   // 触发类型
    FunctionalState EXTI_LineCmd;       // EXTI使能
} EXTI_InitTypeDef;

  1. EXTI_Line:EXTI中断/事件线选择,可选EXTI0至EXTI19,可参考表 EXTI中断_事件线 选择。
  2. EXTI_Mode:EXTI模式选择,可选为产生中断(EXTI_Mode_Interrupt)或者产生事件(EXTI_Mode_Event)。
  3. EXTI_Trigger:EXTI边沿触发事件,可选上升沿触发(EXTI_Trigger_Rising)、 下降沿触发( EXTI_Trigger_Falling)或者上升沿和下降沿都触发( EXTI_Trigger_Rising_Falling)。
  4. EXTI_LineCmd:控制是否使能EXTI线,可选使能EXTI线(ENABLE)或禁用(DISABLE)。

3.4 按键中断

  1. 初始化用来产生中断的GPIO;
  2. 初始化EXTI;
  3. 配置NVIC;
  4. 编写中断服务函数;

宏定义:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//引脚定义
#define KEY1_INT_GPIO_PORT         GPIOA
#define KEY1_INT_GPIO_CLK          (RCC_APB2Periph_GPIOA\
                                    |RCC_APB2Periph_AFIO)
#define KEY1_INT_GPIO_PIN          GPIO_Pin_0
#define KEY1_INT_EXTI_PORTSOURCE   GPIO_PortSourceGPIOA
#define KEY1_INT_EXTI_PINSOURCE    GPIO_PinSource0
#define KEY1_INT_EXTI_LINE         EXTI_Line0
#define KEY1_INT_EXTI_IRQ          EXTI0_IRQn

#define KEY1_IRQHandler            EXTI0_IRQHandler


#define KEY2_INT_GPIO_PORT         GPIOC
#define KEY2_INT_GPIO_CLK          (RCC_APB2Periph_GPIOC\
                                    |RCC_APB2Periph_AFIO)
#define KEY2_INT_GPIO_PIN          GPIO_Pin_13
#define KEY2_INT_EXTI_PORTSOURCE   GPIO_PortSourceGPIOC
#define KEY2_INT_EXTI_PINSOURCE    GPIO_PinSource13
#define KEY2_INT_EXTI_LINE         EXTI_Line13
#define KEY2_INT_EXTI_IRQ          EXTI15_10_IRQn

NVIC配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;

    /* 配置NVIC为优先级组1 */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

    /* 配置中断源:按键1 */
    NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;
    /* 配置抢占优先级:1 */
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    /* 配置子优先级:1 */
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    /* 使能中断通道 */
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* 配置中断源:按键2,其他使用上面相关配置 */
    NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ;
    NVIC_Init(&NVIC_InitStructure);
}

EXIT中断配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void EXTI_Key_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;

    /*开启按键GPIO口的时钟*/
    RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);

    /* 配置 NVIC 中断*/
    NVIC_Configuration();

    /*--------------------------KEY1配置---------------------*/
    /* 选择按键用到的GPIO */
    GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;
    /* 配置为浮空输入 */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);

    /* 选择EXTI的信号源 */
    GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, \
                        KEY1_INT_EXTI_PINSOURCE);
    EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;

    /* EXTI为中断模式 */
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    /* 上升沿中断 */
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    /* 使能中断 */
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    /*--------------------------KEY2配置------------------*/
    /* 选择按键用到的GPIO */
    GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;
    /* 配置为浮空输入 */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure);

    /* 选择EXTI的信号源 */
    GPIO_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE, \
                        KEY2_INT_EXTI_PINSOURCE);
    EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE;

    /* EXTI为中断模式 */
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    /* 下降沿中断 */
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    /* 使能中断 */
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
}

中断服务函数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void KEY1_IRQHandler(void)
{
    //确保是否产生了EXTI Line中断
    if (EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) {
        // LED1 取反
        LED1_TOGGLE;
        //清除中断标志位
        EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);
    }
}

void KEY2_IRQHandler(void)
{
    //确保是否产生了EXTI Line中断
    if (EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET) {
        // LED2 取反
        LED2_TOGGLE;
        //清除中断标志位
        EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE);
    }
}

最后

如果本文对你有所帮助,还请三连支持一下博主!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-11-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【STM32】EXTI---外部中断/事件控制器
开发板:stm32f407VET6 开发环境:keil5 MDK 一、EXTI 简介 外部中断/事件控制器(EXTI)管理了控制器的 23个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以
AXYZdong
2020/10/29
1.4K0
【STM32】EXTI---外部中断/事件控制器
STM32定时器与中断整理
F429 在内核水平上搭载了一个异常响应系统, 支持为数众多的系统异常和外部中断。
小锋学长生活大爆炸
2020/08/13
1.2K0
STM32定时器与中断整理
中断-NVIC与EXTI外设详解(超全面)
NVIC :嵌套向量中断控制器,属于内核外设,管理着包括内核和片上所有外设的中断相关的功能。
全栈程序员站长
2022/08/24
2.1K0
中断-NVIC与EXTI外设详解(超全面)
一小时彻底掌握stm32中断。
在STM32中执行中断主要分三部分: ==1.配置NVIC_Config()函数 2.配置EXTI_Config()函数 3.编写中断服务函数== (注:本文章所用代码为中断按键代码,实现了按键进入中断从而控制LED亮灭)了解10904更多92304加
7537367
2020/07/31
2.1K0
STM32学习笔记之—红外通信
首先大家不要觉得红外通信很难,知道原理的话其实也就那么回事儿,而本文讲解的重点不是原理性的内容(原理性的这类比较底层的知识往往比较复杂,交个那些大佬慢慢研究吧),本文主要是教大家如何使用红外通信,希望大家看了本教程之后能够进行简单的红外通信,做做简单的DIY。_
全栈程序员站长
2022/11/17
1.3K0
STM32学习笔记之—红外通信
STM32笔记之 NVIC(嵌套向量中断控制器)[通俗易懂]
写在前面: 本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
全栈程序员站长
2022/09/02
2.4K0
(24)STM32——待机唤醒(低功耗)笔记
        这三种模式的功耗是逐渐降低的,特别是待机模式,功耗特别低,最低只需要 2.2uA 左右的电流。停机模式是次低功耗的,其典型的电流消耗在 350uA 左右。最后就是睡眠模式了。根据最低电源消耗,最快启动时间和可用的唤醒源等条件,选择一种最佳的低功耗模式。
小点点
2022/12/12
1.6K0
(24)STM32——待机唤醒(低功耗)笔记
STM32中的NVIC详解[通俗易懂]
转载自 https://blog.csdn.net/wuyuzun/article/details/72783152
全栈程序员站长
2022/08/24
3.1K0
STM32中的NVIC详解[通俗易懂]
STM32CubeMX实战教程(三)——外部中断(中断及HAL_Delay函数避坑)
学单片机的,相信对中断的概念都已经了如指掌了,中断具体是什么我在这里也就不再详细说明,不懂的上网找找也一大堆。那么在介绍实验之前我先跟大家简单讲讲STM32当中的NVIC(嵌套向量中断控制器)
全栈程序员站长
2022/09/05
6.2K2
STM32CubeMX实战教程(三)——外部中断(中断及HAL_Delay函数避坑)
STM32中断详述——外部EXTI
NVIC在STM32中,它是用来统一分配中断优先级和管理中断的,是一个内核外设,NVIC的结构图如下图3所示
秋名山码神
2023/04/28
1K0
STM32中断详述——外部EXTI
STM32中断优先级NVIC
使用中断就是饭做好了,服务员会为你端上来,然后你开始吃饭。端上来之前你爱干啥就干啥。
全栈程序员站长
2022/08/24
1.3K0
STM32中断优先级NVIC
(十四)STM32——外部中断(EXTI)
目录 学习目标 内容 介绍 配置 代码 运行结果 总结  ---- 学习目标         本节内容我们将介绍一下外部中断,STM32F4 的每个 IO 都可以作为外部 中断的中断输入口,这点也是 STM32F4 的强大之处。本节我们将使用 STM32F4 的 IO 口作为外部中断输入,实现独立按键的外部中断功能。和独立按键类似,只不过是用中断完成的。 内容 介绍         STM32F407 的中断控制器支持 22 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏
小点点
2022/12/12
1.2K0
(十四)STM32——外部中断(EXTI)
STM32的NVIC和中断的总结「建议收藏」
前言: 1.要想学习STM32中断,要先掌握STM32对优先级的定义; 2.有51单片机开发经验会比较容易理解中断优先级; 3.本篇博文基于STM32F103ZET6芯片和3.5.0标准库编写; 4.本篇博文从寄存器入手,最终实现编程的步骤;如有不足之处,还请前辈多多指教;
全栈程序员站长
2022/09/01
5780
STM32F407-USART2+DMA空闲中断收发
用户11186929
2024/07/01
3660
【嵌入式】你真的知道STM32中的EXTI外部中断吗?你看过EXTI功能框图吗?没关系,我来给你一一介绍,干货满满!
STM32的EXTI是管理外部中断的重要模块。通过EXTI,当外部信号发生变化时,可以触发中断,使CPU暂停当前正在运行的程序,转而处理中断事件,处理完成后又返回原来被暂停的位置继续执行,极大地增强了单片机对外部事件响应的能力。。本文将详细介绍STM32的EXTI外部中断的配置和使用方法,并提供详细的代码示例和图片说明。
用户10923087
2024/11/19
6630
【嵌入式】你真的知道STM32中的EXTI外部中断吗?你看过EXTI功能框图吗?没关系,我来给你一一介绍,干货满满!
STM32F4 SPI DMA
张贴的代码显示如何配置我的GPIO,定时器,SPI, DMA和NVIC模块,以及一些系统如何工作的解释。 注意,我使用的是STM32F4标准外设库。
小锋学长生活大爆炸
2020/09/24
2.2K0
STM32F4 SPI DMA
(22)STM32——RTC时钟笔记(基于正点原子探索者)
目录 学习目标 运行结果 内容 介绍 配置 寄存器 配置过程 日历 闹钟 自动唤醒 代码 总结  ---- 学习目标         今天我们要介绍的有关PTC时钟的相关知识,其中包括了RTC日历、RTC时钟和RTC周期性自动唤醒。其实我们在51单片机的时候利用过DS1302完成过时钟的实验,但因为51单片机本身的精度原因,导致有一点点误差,当我接触到32的时钟时,觉得特别精准,虽然繁琐了一点点(其实51也好麻烦)。好了,接下来就让我们开始介绍一下32的RTC时钟吧! 运行结果 LED灯也在闪,但是
小点点
2022/12/12
1K0
(22)STM32——RTC时钟笔记(基于正点原子探索者)
GPIO—按键中断
前面“第10章 基础重点—中断系统”介绍了STM32的中断和中断优先级,知道了所有外设中断都由 NVIC管理,比如USART、ADC、I2C、SPI等。GPIO产生的中断也不例外,但在给NVIC管理之前,还有一个EXTI(External interrupt/event controller,外部中断/事件控制器)先处理一下,如图 13.1.1 所示
韦东山
2022/05/05
3.1K0
GPIO—按键中断
NVIC的使用[通俗易懂]
中断编程的三个部分—— 1.配置NVIC_Config()函数 NVIC 是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。因此控制中断的进行与NVIC_Config函数的配置密切相关。 2.配置EXTI_Config()函数 EXIT(External interrupt/event controller):外部中断/事件控制器,管理了控制器的 20个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。 EXTI 可以实现对每个中断/事件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性。 (开启相应GPIO的时钟,初始化要与EXIT相连的GPIO(配置EXIT并连接GPIO引脚),初始化GPIO外设,配置中断/事件线。)
全栈程序员站长
2022/09/02
1.1K0
【STM32】串口通信---用代码与芯片对话
文章目录 前言 一、串口通信基本知识 二、编程思路 usart.h usart.c main.c 宏定义 三、总结 前言 开发板:stm32f407VET6 开发环境:keil5 MDK 一、串口通信基本知识 【STM32】5分钟了解STM32的串口通信 二、编程思路 usart.h // ============================================= # @Time : 2020-09-03 # @Author : AXYZdong # @CSDN : http
AXYZdong
2020/11/05
8860
相关推荐
【STM32】EXTI---外部中断/事件控制器
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验