news 2026/4/18 3:41:13

STM323:ERXI和NVIC

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM323:ERXI和NVIC

1.外部中断EXTI

EXTI:External interrupt/event controller外部中断/事件控制器

1.外部中断基础知识

1.STM32外部中断框架

中断的概念:在主程序运行过程中,出现了特定的中断触发条件,使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行。

  1. 有20条外部中断线
  2. 有十六条是GPIO的中断线(0~15),同一个引脚号对应同一个line
  3. 第十九条line只在有ETH互联设备上才存在
  4. GPIO的中断线要启用必须先要配置AFIO的寄存器EXTICRx

2.STM32外部中断机制框架

  1. 边沿检测:上升沿,下降沿或者双边沿
  2. 软件配置中断或者事件寄存器
  3. 屏蔽中断寄存器或事件寄存器
  4. 请求挂起寄存器
  5. 中断则发送给NVIC中断控制器
  6. 事件则产生一个脉冲响应

2.复用功能

1.什么是复用功能?

处理器的引脚本身默认就是一个普通的GPIO,但是它还可以被复用成其他功能,我们称之为一个引脚的复用功能

3.重映射

1.什么是重映射?

重映射属于复用功能的另外一个功能,可以把具有特殊功能的引脚,分配到其他引脚上去

如果某个功能被重映射了,那么这个功能将不再遵循其默认的默认分配。

2.中断嵌套控制器NVIC

NVIC:Nested Vectored Interrupt Controller 嵌套向量中断控制器

1.中断向量表

Cortex-M3内核支持256个中断,其中包含了16个内核中断(异常)和240个外部中断,并且具有256级的可编程中断设置。但是,STM32并没有使用CM3内核的全部东西,而是只用了它的一部分。STM32有84个中断,包括16个内核中断(异常)和68个可屏蔽中断, 具有16级可编程的中断优先级。而STM32F103系列上面,16个内核中断(异常)不变, 而可屏蔽中断只有60个(在107系列才有68个)

优先级号越小,优先级越高。

2.中断优先级分组

这60个中断,怎么管理呢?这就涉及到STM32的中断分组。STM32可以将中断分成5个 组,分别为组0-4;同时,对每个中断设置一个抢占优先级和响应优先级。分组配置是由 SCB->AIRCR寄存器的bit10-8来定义的。SCB->AIRCR是在哪里的呢?由于这是CM3内核定义的

具体的分配关系如下所示:

CM3中定义了8个Bit用于设置中断源的优先级,而STM32只选用其中的4个Bit抢占优先级的级别高于响应优先级,而数值越小所代表的的优先级越高,介绍一下抢占优先级、响应优先级的区别:

  • 高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的
  • 抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断
  • 抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行
  • 如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;(中断号)

除此之外有两点需要注意:

  • 打断的情况只会与抢占优先级有关, 和响应优先级无关!(中断嵌套)
  • 一般情况下,系统代码执行过程中,只设置一次中断优先级分组,比如分组2,设置好分组之后一般不会再改变分组。随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果。

3.中断优先级控制函数结构体

中断优先级控制函数

  • NVIC_SetPriorityGrouping()。

中断优先级控制结构体参数 NVIC_InitTypeDef

  • NVIC_IRQChannel:定义初始化的是哪一个中断,这个可以在stm32f10x.h文件 中查到每个中断对应的名字,如USART1_IRQn;
  • NVIC_IRQChannelPreemptionPriority:定义此中断的抢占优先级别; NVIC_IRQChannelSubPriority:定义此中断的响应优先级别;
  • NVIC_IRQChannelCmd:该中断是否使能。

NVIC_Init()函数初始化NVIC寄存器

IRQn : Interrupt Request Number 中断请求编号或中断号

4.中断优先级设置步骤

1、系统运行后先设置中断优先级分组。调用函数。

2、针对每个中断,设置对应的抢占优先级和响应优先级。

3、如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。

5.项目:外部中断按键控制LED灯

按键控制LED的开发流程:

第一步:使能功能复用时钟

第二布,配置复用寄存器

第三步,配置中断屏蔽寄存器

固件库按键控制LED灯

外部中断EXTI结构体:

typedef struct {

uint32_t EXTI_Line;

EXTIMode_TypeDef EXTI_Mode;

EXTITrigger_TypeDef EXTI_Trigger;

FunctionalState EXTI_LineCmd;

}EXTI_InitTypeDef;

外部中断EXTI相关库函数:

void EXTI_DeInit(void);

voidEXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);

void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);

FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);

void EXTI_ClearFlag(uint32_t EXTI_Line);

ITStatusEXTI_GetITStatus(uint32_t EXTI_Line);

voidEXTI_ClearITPendingBit(uint32_t EXTI_Line);

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);

检查指定的 EXTI 中断线路是否发生了中断请求,即查询该线路的中断标志位(Interrupt Flag)是否被置位。

工作原理

当配置好的外部中断触发条件(如上升沿)发生时,硬件会自动将对应的中断挂起位 置1。这个函数就是去读取这个状态位的值。

// 方式1:最常用的判断方式(推荐)
if (EXTI_GetITStatus(EXTI_Line0) != RESET)
{
// 中断发生了,执行处理代码
EXTI_ClearITPendingBit(EXTI_Line0);
}

软件流程设计

  • 初始化GPIO、AFIO(EXTI)外设时钟
  • 初始化GPIO按键,初始化LED引脚
  • 连接GPIO引脚到EXTI
  • 初始化EXTI外部中断条件
  • NVIC
  • 初始化NVIC嵌套中断控制器

编写外部中断函数

  • 判断中断发生控制LED灯
#include "stm32f10x.h" #include "Exti.h" void Exti_Init(void) { GPIO_InitTypeDef Gpio_Initstructure; EXTI_InitTypeDef Exti_Initstructure; NVIC_InitTypeDef NVIC_Initstructure; // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE); Gpio_Initstructure.GPIO_Pin = GPIO_Pin_0; Gpio_Initstructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA,&Gpio_Initstructure); 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_Falling; Exti_Initstructure.EXTI_LineCmd = ENABLE; EXTI_Init(&Exti_Initstructure); // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_Initstructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_Initstructure.NVIC_IRQChannelSubPriority = 0; NVIC_Initstructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_Initstructure); }

过程详解:

1.结构体声明和时钟使能

GPIO_InitTypeDef Gpio_Initstructure;
EXTI_InitTypeDef Exti_Initstructure;
NVIC_InitTypeDef NVIC_Initstructure;

// 开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

注:如果不开启AFIO时钟,

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);将不会把PA0引脚连接到EXTI_Line0。实际上是在操作 AFIO 模块的寄存器。

引脚与EXTI的映射关系保持默认或随机,在STM32中,EXTI线默认没有连接到任何GPIO引脚,或者保持上一次的状态。

2.配置GPIO引脚

3.连接GPIO引脚到EXTI线路

PIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);

建立映射关系
将物理引脚PA0连接到EXTI_Line0中断线

注:多个引脚可共享同一条EXTI线(如PA0和PB0都连到EXTI_Line0)

4.配置EXTI模块(中断条件设置)

Exti_Initstructure.EXTI_Line = EXTI_Line0; // 选择EXTI线路0
Exti_Initstructure.EXTI_Mode = EXTI_Mode_Interrupt; // 中断模式
Exti_Initstructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
Exti_Initstructure.EXTI_LineCmd = ENABLE; // 使能该线路
EXTI_Init(&Exti_Initstructure); // 应用配置

EXTI_Trigger_Rising:上升沿触发(低→高)

EXTI_Trigger_Falling:下降沿触发(高→低)

EXTI_Trigger_Rising_Falling:双边沿触发(变化就触发)

5.配置NVIC

// 1. 设置优先级分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

NVIC_PriorityGroup_2:2位抢占优先级,2位子优先级

抢占优先级:决定是否能打断其他中断(高优先级可抢占低优先级)

子优先级:相同抢占优先级时的响应顺序

// 2. 配置具体中断通道
NVIC_Initstructure.NVIC_IRQChannel = EXTI0_IRQn; // 中断号
NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级
NVIC_Initstructure.NVIC_IRQChannelSubPriority = 0; // 子优先级
NVIC_Initstructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断
NVIC_Init(&NVIC_Initstructure);

硬件流程:
1. 按键按下 → PA0电平:高 → 低
2. EXTI检测到下降沿 →设置中断标志位
3. NVIC检查优先级 → 中断当前程序(如果允许)
4. CPU跳转到中断服务函数

[物理世界]
手指按下按键

[芯片引脚]
PA0与GND接通 → 电压3.3V→0V

[芯片内部GPIO]
检测到PA0=0(之前是1)

[芯片内部EXTI]
发现"1→0"下降沿 →置位中断标志

[芯片内部连线]
通过金属线发送IRQ6信号

[芯片内部NVIC]
接收信号 →检查优先级→ 通知CPU

[CPU核心]
暂停主程序 → 跳转到你的中断函数

[执行代码]
你的灯控逻辑:亮1秒 → 灭1秒

[检查]

EXTI_GetITStatus() : 确认是PA0中断

[清理]

EXTI_ClearITPendingBit() :清除中断标志


[返回]
CPU回到主程序继续执行

补充:weak:弱定义;如果用户没有自己定义的中断函数,则系统默认执行系统自定义的中断函数,如果用户有定义中断函数则优先执行用户的中断函数。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 13:20:43

draft-js自定义工具栏开发实战:从零打造专属编辑体验

draft-js自定义工具栏开发实战:从零打造专属编辑体验 【免费下载链接】draft-js A React framework for building text editors. 项目地址: https://gitcode.com/gh_mirrors/dra/draft-js 还在为编辑器工具栏样式单调、功能固化而头疼吗?每次看到…

作者头像 李华
网站建设 2026/4/16 20:16:12

四倍定焦云台如何实现变焦

四倍定焦云台”这一概念可能存在一定的表述混淆,因为定焦镜头1”2.8通常指焦距固定不变,而变焦 则焦距的调整。如果是指支持4倍光学变焦的云台设备 ,其变焦机制通常如下:1. 光学变焦原理光学变焦通过镜头内部透镜组的移动来调整焦…

作者头像 李华
网站建设 2026/4/18 1:13:55

近视可防可控不可逆!孩子的“远视储备”还剩多少?

在视觉健康领域,一个关键概念正逐渐被广大家长所认知——“远视储备”。理解并保护好孩子的这份宝贵“资产”,是预防近视发生的第一道防线。科学界已形成明确共识:近视一旦形成便不可逆转,但通过科学手段,其发生和发展…

作者头像 李华
网站建设 2026/4/16 9:25:23

孩子刚上二年级就近视?防近视其实很简单,关键是要做对这件事

刚送孩子升入二年级,不少家长就发现了令人揪心的变化:孩子看黑板时频繁眯眼、看书本要凑得很近,去医院检查后,赫然出现的“近视100度”的诊断,让家长们陷入焦虑。为什么现在的孩子早发性近视越来越普遍?一、…

作者头像 李华
网站建设 2026/4/12 19:11:16

数据挖掘09

数据挖掘09 —— 基于神经网络的序列数据挖掘 一、循环神经网络 1.定义 **循环神经网络(Recurrent Neural Network, RNN)**是一种专门用于处理序列数据的神经网络结构。 2.核心思想:引入“循环”实现记忆 在标准神经网络中,每个输…

作者头像 李华
网站建设 2026/4/15 15:42:13

3倍性能提升!COLMAP三维重建的矩阵运算优化实战

3倍性能提升!COLMAP三维重建的矩阵运算优化实战 【免费下载链接】colmap COLMAP - Structure-from-Motion and Multi-View Stereo 项目地址: https://gitcode.com/GitHub_Trending/co/colmap COLMAP作为业界领先的三维重建工具,其核心计算性能直接…

作者头像 李华