STM32中断详述——外部EXTI

news2024/12/21 21:49:22

前置知识

  • 中断:在主程序运行过程中,出现了特定的中断源,使得CPU暂停当前正在运行中的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续执行,可以参考图1所示。

图1
图1 中断程序图

  • 中断优先级:当有多个中断源同时请求中断的时候,CPU会根据中断源的轻重缓急进行裁决,优先响应更加紧急的中断源

  • 中断嵌套:其中一个中断正在运行中,又出现了一个新的更高级的中断,CPU再次暂停当前中断程序,转而运行新的程序,处理完成后依次返回。如图2所示:
    在这里插入图片描述
    图2 嵌套中断程序图

STM32 中断

STM32F1系列

  • 68个可屏蔽中断通道,包含EXTI,TIM,ADC,USART,SPI,I2C,RTC等多个外设
  • 使用NVIC统一管理中断,每个中断通道都有16个可编程的优先等级,可对优先级进行分组,进一步设置抢占优先级和响应优先级

NVIC基本结构

NVIC在STM32中,它是用来统一分配中断优先级和管理中断的,是一个内核外设,NVIC的结构图如下图3所示
在这里插入图片描述
图3 NVIC结构图
由于CPU是主要用来运算的,故把中断分配的任务外包给了NVIC,他有很多个输入口,可以接很多的中断口。

NVIC中断分组

在STM32中,NVIC中断分组可以分为两个级别:全局中断分组和子优先级分组。

  1. 全局中断分组:用于配置所有中断请求的优先级分组方式,可以通过SCB(System Control Block)模块中的AIRCR(Application Interrupt and Reset Control Register)寄存器进行配置。全局中断分组主要影响到普通中断的优先级顺序。

  2. 子优先级分组:用于配置同一优先级中多个中断之间的响应顺序,通过NVIC模块的IPR(Interrupt Priority Register)寄存器进行配置。

在全局中断分组中,将中断的优先级分为4组,每组优先级数目不同。可根据实际需要选择合适的分组方式。具体的分组方式如下:

  1. 0位抢占优先级和4位响应优先级(0:4):将16个主优先级分成16/1=16个组,每组只包含一个优先级。

  2. 1位抢占优先级和3位响应优先级(1:3):将16个主优先级分成16/4=4个组,每组包含4个优先级。

  3. 2位抢占优先级和2位响应优先级(2:2):将16个主优先级分成16/16=1个组,所有中断的优先级相同。

  4. 3位抢占优先级和1位响应优先级(3:1):将16个主优先级分成16/64=1/4个组,每组包含64个优先级。

在选择中断分组时,需要权衡系统的可靠性和中断响应速度。如果需要更快的中断响应速度,则应当选取更高的优先级;如果需要更稳定的系统,则应降低优先级。

EXTI外部中断

在STM32单片机中,可以使用外部中断输入线(EXTI)来实现外部中断的响应。EXTI线为双边沿触发,可以同时支持上升沿和下降沿触发中断,还支持软件触发和信号线电平状态查询等多种功能。

在使用STM32中的EXTI外部中断时,需要注意以下几点:

  1. 配置GPIO引脚:首先需要将要使用的GPIO引脚配置为输入模式,同时使能外部中断线。

  2. 配置EXTI线:选择要使用的中断线并配置其触发方式,例如上升沿、下降沿、低电平、高电平等。

  3. 编写中断服务函数:当外部中断触发时,会跳转到对应的中断服务函数进行处理。需要编写相应的中断服务函数来响应中断事件。

  4. 关闭中断:在中断服务函数中对紧急情况进行处理后,需要及时将中断屏蔽以避免中断重复触发。

以下是一个简单的STM32EXTI外部中断的示例:

#include "stm32f10x.h"

void EXTI0_IRQHandler(void)
{
    if (EXTI_GetITStatus(EXTI_Line0) != RESET)
    {
        /* 处理中断事件 */

        /* 关闭中断 */
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}

int main()
{
    /* 使能GPIO引脚和EXTI线 */
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    
    /* 配置GPIO引脚 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    /* 配置EXTI线 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; /* 上升沿触发 */
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
    
    /* 配置中断优先级 */
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    while(1)
    {
        /* 正常运行代码 */
    }
}

定义了一个名为EXTI0_IRQHandler的中断服务函数,通过读取EXTI_GetITStatus函数来检测是否有中断请求产生,执行完中断服务函数后,需要使用EXTI_ClearITPendingBit清除中断标志位并关闭中断。

上面的例子可能还是有点晦涩,我们先来看一下EXTI的基本结构,如图4所示:

在这里插入图片描述
图4 EXTI基本结构图

在上图中AFIO、EXTI、NVIC都有其特定的作用:

  • AFIO(Alternate Function I/O):是一种外设复用功能,可以将单个GPIO端口的复用功能分配给多个外设,例如复用其他串行通信接口或IO端口。在外部中断中,为了允许对每个I/O引脚选择不同的中断线,需要使用AFIO来配置GPIO端口的复用功能,从而定义中断线的连接。

  • EXTI(External Interrupt/Event Controller):是管理外设中断/事件的控制器,通常用于激活处理器中的中断。EXTI外部中断线和GPIO Pin相关联,当线上电平发生变化时,EXTI会触发一次中断请求,并产生中断标志位。通过操作EXTI, 可以设置中断线的触发方式和优先级等参数。

  • NVIC(Nested Vectored Interrupt Controller):是STM32芯片中处理各种中断请求的一个内部模块,支持嵌套中断机制,用于优化系统的多任务管理。NVIC中,优先级分组分为:抢占优先级分组和响应优先级分组。抢占优先级越高,CPU在处理该中断时,会放弃低优先级中断的响应并快速地进入该中断处理函数中。

在STM32外部中断的使用中,这三个组件经常一同出现:

  1. AFIO和GPIO可以一起配置中断线路和端口,以便将输入引脚映射到正确的外部中断线路。
  2. EXTI和系统中断溢出控制器协同工作,确定是否还有活动中断,以及确保在执行给定中断的处理程序之前没有丢失或覆盖其他中断。
  3. NVIC控制中断处理程序的优先级,以确保在中断“堆栈”中按正确顺序处理多个中断。

下面我们通过一个红外传感器计次的代码来实际感受一下,外部中断:

红外传感器计次

#include "stm32f10x.h"                  // Device header

uint16_t CountSensor_Count;

void CountSensor_Init(void)
{
	//使用的GPIOB端口和复用中断功能,为外部中断线提供供电
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	
	//定义的GPIO_InitTypeDef结构体为GPIO配置结构体,用来给GPIOB14配置输入模式和上拉输入(Internal Pull Up)。GPIOB14的GPIO_Pin定义为GPIO_Pin_14,其它参数与对应引脚电路方案有关,根据需要进行修改,例如GPIO_Speed为GPIO_Speed_50MHz,这是为了配置管脚输出的最大时钟速度,也就是所有的管脚寄存器(ODR和BSR等,不包括MODER)都运行在50MHz的时钟下
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	//告诉NVIC如何映射中断线。使用GPIOB14时,可以将其用于EXTI15线路上,以便将此引脚映射到正确的线路
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
	
	//EXTI_InitTypeDef结构体类型和EXTI_Init()函数来初始化外部中断功能。针对 GPIOB14,需要使用EXTI_Line14枚举类型来选择要使用的中断线路。ENABLE命令行参数用于使能配置好的中断线路。EXTI_Mode设置为EXTI_Mode_Interrupt来使用EXTI的中断模式,而EXTI_Trigger则表示使用下降沿触发中断模式。这些配置后,再调用EXTI_Init()函数注册到 NVIC 的 EXTI 列表中,以确保能够正确响应中断事件
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line = EXTI_Line14;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_Init(&EXTI_InitStructure);
	
	//在第二组中断中优先级分组,一共可以实现16个不同的优先级级别,包括4个抢占优先级和4个响应优先级。该函数可以用于设置 NVIC 的中断优先级分组,在 NVIC 中按照优先级的设置顺序执行相应中断服务程序。NVIC_PriorityGroup_2 表示在一个共享优先级中,两位用于变换优先级设置
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	//首先定义了一个 NVIC_InitTypeDef 结构体类型,用于存储 NVIC 的各项参数信息。然后通过 .NVIC_IRQChannel 参数设置了 EXTI15_10 对应的中断通道,这表示配置的是 EXTI 产生的中断事件,其中 EXTI15_10 表示相关管脚的最大ID号,表示将配置EXTI的从15到10的中断响应优先级。接着,NVIC_InitStructure.NVIC_IRQChannelCmd设置为ENABLE以告诉 NVIC 此中断通道该项参数已经完成配置,可以开始中断处理。而 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 和NVIC_InitStructure.NVIC_IRQChannelSubPriority 这两项参数则是设置相应的抢占优先级和响应优先级。抢占优先级从 0 到 15,数值最小的优先级最高,而响应优先级的取值范围与抢占优先级的取值范围相同,因为这里两个通道的具体优先级是一样的,所以都设置为 1,。最后,调用函数 NVIC_Init(),向 NVIC 注册中断服务函数,这样 NVIC 就知道该如何优先处理 EXTI 捕获到的中断事件了。执行这些代码后,配置的 EXTI 引脚成功启动,产生中断信号后外部中断的优先级也正常被处理。
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
}

uint16_t CountSensor_Get(void)
{
	return CountSensor_Count;
}

void EXTI15_10_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line14) == SET)
	{
		/*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
		if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)
		{
			CountSensor_Count ++;
		}
		EXTI_ClearITPendingBit(EXTI_Line14);
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/455762.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

法雷奥,百年巨头的新周期

传统汽车零部件Tier1正在加速适应全球智能化、电动化的汽车产业新变革趋势。同时,继续扩大在中国市场的投资,并强化本土化研发能力和资源投入,已经是大势所趋。 “2022年,法雷奥启动了’Move Up’计划,确定了四个符合市…

PC1 - 搭建项目

先看路由,可以查看功能模块划分。熟悉什么看什么 router文件夹下routerConfig.tsx 配置路由,创建模块文件(写好内容模块),lazy可懒加载导入。App.tsx配置一级路由,配置二级路由出口 { path:/, element: …

PTA L2-046 天梯赛的赛场安排 (25 分)

天梯赛使用 OMS 监考系统,需要将参赛队员安排到系统中的虚拟赛场里,并为每个赛场分配一位监考老师。每位监考老师需要联系自己赛场内队员对应的教练们,以便发放比赛账号。为了尽可能减少教练和监考的沟通负担,我们要求赛场的安排满…

「教程」天气预警 API 详解:申请密钥到接入代码一气呵成!

引言 天气预警 API 作为一种新型的数据接口,为开发者和应用提供了方便的获取天气预警数据的方式。通过该 API ,可以获取指定城市当前生效中的各类天气预警信息,例如暴雨、雷电、台风等。预警数据来自国家预警中心,保证了数据的高…

Linux部署人大金仓(Kingbase8)

陈老老老板🦸 👨‍💻本文专栏:国产数据库-人大金仓(kingbase8)(主要讲一些人大金仓数据库相关的内容) 👨‍💻本文简述:本文讲一下LInux上部署人大…

《计算机网络——自顶向下方法》精炼——2.3-2.4

<font color-#FFD700>“Knowledge is power” - Sir Francis Bacon 文件传输协议&#xff1a;FTP FTP协议可以在本地文件系统和远程文件系统之间传输文件。 概述 FTP在用户和服务器之间架起两条TCP连接&#xff0c;控制连接和数据连接。 控制连接&#xff1a;控制连…

[BJDCTF2020CTF]之CTFHub-Misc篇刷题记录(完结)

CTFHub-Misc篇刷题记录①wp SUCTF-2019-MISC签到题RCTF-2019-Misc-draw2020-BJDCTF-Misc-藏藏藏2020-BJDCTF-Misc-签个到2020-BJDCTF-Misc-认真你就输了2020-BJDCTF-Misc-你猜我是个啥2020-BJDCTF-Misc-一叶障目2020-BJDCTF-Misc-鸡你太美2020-BJDCTF-Misc-just a rar[BJDCTF20…

Linux下搭建Go开发环境

Linux下搭建Go开发环境可以按照以下步骤进行&#xff1a; 1、下载最新的Go语言二进制包&#xff0c;可以从官网 https://golang.org/dl/ 下载。 2、将下载好的包解压缩到你想要安装的目录下&#xff0c;如 /usr/local/go。 3、添加环境变量&#xff0c;在终端中输入以下命令…

Matplotlib 绘图标记

Matplotlib 绘图标记 绘图过程如果我们想要给坐标自定义一些不一样的标记&#xff0c;就可以使用 plot() 方法的 marker 参数来定义。 以下实例定义了实心圆标记&#xff1a; 实例 import matplotlib.pyplot as plt import numpy as npypoints np.array([1,3,4,5,8,9,6,1,3…

【信息安全】一文读懂 “3保1评” 等保、分保、关保、密评

【前言】 信息安全知识大而杂&#xff0c;网上资料参差不齐&#xff0c;相关概念模糊不清&#xff0c;所以想归纳一些知识点&#xff0c;与各位共勉。 本篇博文介绍国内安全领域常见的“3保1评”&#xff0c;即等保&#xff08;网络安全等级保护&#xff09;、分保&#xff08;…

[ Java SE] 对象的比较

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…

Postgres逻辑复制详解

逻辑复制 逻辑复制&#xff08;Logical Replication&#xff09;&#xff0c;是一种根据数据对象的 复制标识&#xff08;Replica Identity&#xff09;&#xff08;通常是主键&#xff09;复制数据对象及其变化的方法。 逻辑复制 这个术语与 物理复制相对应&#xff0c;物理…

不得不说的结构型模式-适配器模式

适配器模式&#xff08;Adapter Pattern&#xff09;是结构型模式之一&#xff0c;它将一个类的接口转换成客户希望的另一个接口&#xff0c;从而使原本由于接口不兼容而不能一起工作的类能够协同工作。适配器模式包括对象适配器和类适配器两种实现方式。 在对象适配器中&#…

Ae 入门系列之十:效果和动画预设

Ae 中提供了丰富的效果 Effects和动画预设 Animation Presets&#xff0c;可以轻松、快速地创建出各种酷炫的动画。 ◆ ◆ ◆ 效果 添加效果 方法一&#xff1a;先选中一个或多个图层&#xff0c;然后在Ae菜单&#xff1a;效果 Effect中找到并添加需要的效果。 方法二&#x…

什么是gpt一4-如何用上gpt-4

怎么使用gpt-4 目前GPT-4还未正式发布或公开&#xff0c;因此也没有详细的对接说明。但是我们可以根据GPT-4的前身GPT-3的应用经验&#xff0c;以及GPT-4的预期功能推测一些可能的使用步骤&#xff1a; 选择适合的GPT-4实现技术&#xff1a;GPT-4可能有不同的实现技术&#xff…

Allegro PCB后处理

Allegro PCB后处理&#xff0c;主要是完成线路设计以后&#xff0c;输出生产文件之前的处理。这是看教程做的记录&#xff0c;方便以后自己参考。 教程&#xff1a; [小哥Cadence Allegro 132讲字幕版PCB视频教程]_哔哩哔哩_bilibili 感觉关键是多看右边Options菜单&#xff0…

nodejs+python+php+springboot+vue 校园快递代取配送系统

管理员的主要功能有&#xff1a; 1.管理员输入账户登陆后台 2.个人中心&#xff1a;管理员修改密码和账户信息 3.用户管理&#xff1a;对注册的用户信息进行删除&#xff0c;查询&#xff0c;添加&#xff0c;修改 4.配送员管理&#xff1a;对配送员信息进行添加&#xff0c;修…

力扣刷题——移除元素

1、移除元素 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中…

【模拟IC】版图的基础操作和基础知识总结(1)

今天总结一下在画版图使用的基本操作和遇到的问题及解决方法。# 一、基本操作 &#xff08;1&#xff09;首先是使用layout XL的优势是可以对应原理图的器件&#xff0c;这样方便我们画版图。 &#xff08;2&#xff09;快捷键的操作&#xff1a; F 进行整体版图的居中 K 就是…

忙碌中也要记得休息,这两款好玩的游戏推荐给你

第一款&#xff1a;古墓丽影9年度版 《古墓丽影9》&#xff08;原名Tomb Raider&#xff09;是由水晶动力开发&#xff0c;史克威尔艾尼克斯发行的动作冒险游戏。 它于 2013 年发布。续集是古墓丽影崛起和古墓丽影暗影。 本作的重点是新版劳拉&#xff08;Lara Croft&#xf…