【嵌入式之中断】

news/2024/5/2 11:30:18

Cortex-M4集成了嵌套式矢量型中断控制器(Nested Vectored Interrupt Controller (NVIC))来实现高效的异常和中断处理。NVIC实现了低延迟的异常和中断处理,以及电源管理控制。它和内核是紧密耦合的。

凡是打断程序顺序执行的事件都称为异常(exception),比如HardFault,外部中断等。所以中断​也可以说是异常的一种。

一、中断基础知识

程序顺序执行,遇到中断使能,跳转执行中断函数。

在这里插入图片描述

1、中断分类(中断源)

(1)外部中断

  • 按键
  • 外部通讯中断

(2)内部中断

  • CPU内部中断,如重置,遇到突发事件处理的中断
  • 相关外设中断

注意:具体哪些端口可以中断需要看具体数据手册

2、中断的作用

全局中断使能位控制着“所有”中断,它如果关闭,则会屏蔽其它中断。

在使用过程中,常关闭全局中断,以防止其他中断的干扰。
当GPIO模拟某个时序时,在GPIO传输数据过程中,若被某个中断干扰,会导致时序不准确问题,通常的做法是关闭全局中断,数据传输完成后打开全局中断
同样在RTOS中对全局变量的保护基本上都使用了全局中断。

__disable_irq();
//数据传输
__enable_irq();

但关中断时间较长,导致串口接收FIFO溢出,数据丢失。

所以需要注意:全局中断关闭时间都不是太长,且严禁出现长时间关中断,严禁出现关中断时间不可控,这样会影响实时性。
时间不可控比如:长链表操作、环形缓冲区操作、循环操作等。

3、编程基本配置

(1)配置所需中断功能相关寄存器,开启功能中断以及全局中断

  • 中断源
  • 中断优先级
  • 中断使能

(2)编写中断处理子程(ISR)(CPU硬件自动调用)

  • 中断触发源判断(中断触发,相关标志位置1)
  • 中断标志位清零

(3)在中断函数中处理相关任务

二、中断优先级

异常包括系统异常(异常编号1-15)和外部中断(异常编号16往上)。HardFault(-1)这三个异常优先级都是负数且固定不变,优先级高于其他异常,除了这三个异常之外其他异常优先级都是可以编程的。

1、中断抢占

每个中断优先级都包含两个部分,一部分称作抢占优先级,另一部分称作子优先级。

(1)抢占优先级(中断嵌套)
在执行低中断优先级中断函数时,高优先级中断到来,低优先级中断被打断,执行高优先级中断,高优先级中断执行完后回到低优先级中断继续执行。

在这里插入图片描述

具有高抢占优先级的中断能够抢占低抢占优先级的中断,也称之为中断嵌套。

(2)抢占优先级相同,子优先级不同

当两个中断的抢占优先级设置为相同级别时,这两个中断不会出现中断嵌套。

如果其中一个中断正在执行时,另外一个中断到来,后来的中断将会等到前一个中断执行完才能执行。如果这两个中断都处在等待响应状态,执行条件到来时,首先响应子优先级高的中断。

(3)抢占优先级相同,子优先级也相同

这种情况也不会出现中断嵌套,内核将会按照向量表中的排位选择,优先执行靠前的异常。

2、优先级分组

在Cortex-M4内核中,优先级分组是一个用于配置中断优先级的重要机制。它决定了在8位的中断优先级字段中,多少位用于表示抢占优先级,多少位用于表示子优先级。

Cortex-M4内核允许通过配置优先级分组寄存器(例如,ARM Cortex-M3中的AIRCR寄存器)来设置不同的优先级分组方案。优先级分组寄存器通常包含几位用于配置优先级的字段。通过设置这些位,可以选择不同的分组方式,从而决定抢占优先级和子优先级的位数分配。

具体的分组方式可以有多种,例如:

  • 分组0:所有8位都用于表示子优先级,没有抢占优先级。
  • 分组1:最高1位用于表示抢占优先级,最低的7位用于表示子优先级。
  • 分组2:最高2位用于表示抢占优先级,最低的6位用于表示子优先级。
  • 分组3:最高3位用于表示抢占优先级,最低的5位用于表示子优先级。
  • 分组4:所有8位都用于表示抢占优先级,没有子优先级。

不同的分组方式可以根据具体的应用需求来选择。抢占优先级用于决定在中断发生时哪个中断应该被优先处理,而子优先级则在抢占优先级相同的情况下用于进一步区分中断的优先级。

示例:

nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
nvic_irq_enable((uint8)USBFS_IRQn,2U,0U);
nvic_irq_enable((uint8)USBFS_WKUP_IRQn,1U,0U);

三、中断配置

在使用ARM Cortex-M系列微控制器时,中断处理是一个非常重要的部分。在Cortex-M4(或类似的Cortex-M系列)中配置中断示例如下。(实际的实现细节可能会根据您使用的具体硬件和库有所不同。)

1、选择中断源:
首先确定要使用的中断源。这可能是外部中断、定时器中断或其他内部中断。

2、配置中断优先级:
Cortex-M4支持中断优先级。根据应用的需求为每个中断分配优先级

3、配置NVIC (Nested Vectored Interrupt Controller):
NVIC是Cortex-M系列中的中断控制器。需配置NVIC以启用和配置所需的中断。

4、编写中断服务程序 (ISR):
为每个中断编写中断服务程序。当中断发生时,这些程序将被执行。

以下示例基于ARM Cortex-M4 内核的 GD32 微控制器。

示例1:如何配置一个外部中断(EXTI)(例如,来自某个GPIO引脚的中断)

#include "gd32f3xx.h"  //确保已经包含了必要的头文件// 假设您已经有一个系统时钟初始化的函数  
void SystemClock_Config(void);  // EXTI0 的中断服务程序  
void EXTI0_IRQHandler(void)  
{  if (RESET != exti_interrupt_flag_get(EXTI_0)) // 检查 EXTI0 的中断标志  {  // 清除中断标志  exti_interrupt_flag_clear(EXTI_0);  // 在这里处理中断逻辑  }  
}  int main(void)  
{  // 系统时钟初始化  SystemClock_Config();  // GPIO 端口时钟使能  rcu_periph_clock_enable(RCU_GPIOA);  // 配置 GPIOA 的第 0 号引脚为中断模式  gpio_mode_set(GPIOA, GPIO_MODE_IT, GPIO_PUPD_NONE, GPIO_PIN_0);  gpio_interrupt_enable(GPIOA, GPIO_INT_FALLING); // 下降沿触发  // 配置 EXTI 的中断线 0  exti_interrupt_flag_clear(EXTI_0); // 清除可能存在的挂起中断  exti_line_config(EXTI_SOURCE_GPIOA, EXTI_LINE_0);  exti_mode_set(EXTI_MODE_INTERRUPT, EXTI_LINE_0);  exti_trigger_type_set(EXTI_TRIGGER_FALLING, EXTI_LINE_0); // 下降沿触发  // 配置 NVIC  nvic_irq_enable(EXTI0_IRQn, 0, 0); // 使能 EXTI0 的中断,并设置优先级  while (1)  {  // 主循环代码  }  
}

四、扩展示例

配置内部中断(如定时器中断)

配置相关步骤为:

1、初始化定时器:
首先,需要初始化定时器,并设置其参数,如预分频值、自动重载值等,以决定定时器的计数周期和中断触发频率。

2、配置定时器中断:
启用定时器的中断功能,并设置中断触发条件(如溢出中断、比较匹配中断等)。

3、配置NVIC:
使用嵌套向量中断控制器(NVIC)来配置中断的优先级和使能中断。

4、编写中断服务程序(ISR):
编写一个中断服务程序,该程序将在定时器中断发生时被执行。

#include "gd32f3xx.h"  // 假设您已经有一个系统时钟初始化的函数  
void SystemClock_Config(void);  // 定时器中断服务程序  
void TIMERx_IRQHandler(void) // 这里的x代表具体的定时器编号,如TIMER2  
{  if (RESET != timer_interrupt_flag_get(TIMERx, TIMER_INT_FLAG_UP)) // 检查定时器的中断标志  {  // 清除中断标志  timer_interrupt_flag_clear(TIMERx, TIMER_INT_FLAG_UP);  // 在这里处理中断逻辑  }  
}  int main(void)  
{  // 系统时钟初始化  SystemClock_Config();  // 定时器时钟使能  rcu_periph_clock_enable(RCU_TIMERx); // 这里的x代表具体的定时器编号,如TIMER2  // 定时器初始化结构体定义和初始化  timer_parameter_struct timer_initpara;  timer_initpara.prescaler         = 7199;  // 预分频值  timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;  timer_initpara.counterdirection  = TIMER_COUNTER_UP;  timer_initpara.period            = 9999;  // 自动重载值  timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;  timer_initpara.repetitioncounter = 0;  timer_init(TIMERx, &timer_initpara); // 初始化定时器  // 启动定时器  timer_enable(TIMERx);  // 配置定时器中断  timer_interrupt_enable(TIMERx, TIMER_INT_FLAG_UP); // 使能定时器中断  // 配置NVIC  nvic_irq_enable(TIMERx_IRQn, 0, 0); // 使能定时器的中断,并设置优先级  while (1)  {  // 主循环代码  }  
}

以上示例中:首先初始化了系统时钟,然后使能了定时器的时钟。接着,定义了定时器的初始化参数,并调用timer_init函数来初始化定时器。之后,我们启动了定时器,并配置了定时器中断。最后,使用nvic_irq_enable函数来使能定时器的中断,并设置了其优先级。


http://www.mrgr.cn/p/00357382

相关文章

VN6501使用方法(学习笔记)

1:总体简介 VNA6501可以进行CAN Stress测试,可以进行采样点测试。此外VN6501还能够定制,外围测试电路(通过软件配置,部分情况是需要连接VN6501的部分接口)。 关于外围测试电路(添加电容,电阻&…

<计算机网络自顶向下> 可靠数据传输的原理(未完成)

可靠数据传输(rdt:Reliable Data Transfer)的原理 rdt在应用层,传输层和数据链路层都很重要是网络TOP10问题之一信道的不可靠特点决定了可靠数据传输rdt的复杂性rdt_send: 被上层(如应用层)调用&#xff0…

机器学习和深度学习--李宏毅(笔记与个人理解)Day11-12

Day11 when gradient is small…… 怎么知道是局部小 还是鞍点? using Math 这里巧妙的说明了hessan矩阵可以决定一个二次函数的凹凸性 也就是 θ \theta θ 是min 还是max,最后那个有些有些 哈 是一个saddle; 然后这里只要看hessan矩阵是不…

基于数据库现有表导出为设计文档

1.查询 SELECTCOLUMN_NAME 字段名,COLUMN_COMMENT 字段描述,COLUMN_TYPE 字段类型,false as 是否为主键 FROMINFORMATION_SCHEMA.COLUMNS wheretable_NAME region -- 表名2.查询结果 3.导出为excel

学习云计算HCIE选择誉天有什么优势?

誉天云计算课程优势实战性强 课程注重实践操作,通过实际案例和实验操作,让学员深入了解云计算的应用场景和实际操作技能。课程内容全面 涵盖所有云计算涉及的IT基础知识、服务器、存储、网络等方面的基础知识,开源操作系统Linux,开…

吴恩达机器学习笔记(1-1到2-1)

吴恩达机器学习笔记(1-1到2-1) https://www.bilibili.com/video/BV164411b7dx?p=1 https://www.bilibili.com/video/BV164411b7dx?p=2 https://www.bilibili.com/video/BV164411b7dx?p=3 https://www.bilibili.com/video/BV164411b7dx?p=4 机器学习-吴恩达 一、初学 1、什…

YAML教程-1-基础入门

领取资料,咨询答疑,请➕wei: June__Go YAML简介 YAML(YAML Aint Markup Language)是一种用于数据序列化的人类可读格式。它广泛用于配置文件、数据交换、持续集成/持续部署(CI/CD)等领域。YAML的设计目标…

注意,把Python库安装在一个环境里,可能会“非常危险”!

如果说谁写Python不用第三方库,我敬他是条汉子。如今到处是轮子的时代,Python第三方库管理成了开发者们头疼的问题。 可能在看这篇文章的很多人,都没用过Python虚拟环境,不知道安装Python库需要考虑版本兼容问题。 那么把所有要…

「不羁联盟/XDefiant」4月20号开启服务器测试,游戏预下载安装教程

XDefiant》开启Alpha测试,这是一款免费游玩的快节奏 FPS 竞技游戏,可选择特色阵营,搭配个性化的装备,体验 6v6 对抗或是线性游戏模式。高品质射击竞技端游XDefiant以6v6双边对抗为核心,对局模式分为区域与线性两大类&a…

安科瑞用于养老院医院学校社区等各类低压场所AISD电气火灾智能安全配电装置/电不起火电不漏电电不伤人/接地故障

安科瑞薛瑶瑶 18701709087 用电安全隐患,无处不在!!! 电力是清洁能源,给人们带来了便捷的电气化生活,但同时,由于使用不当,维护不及时等引发的漏电触电等电气火灾事故,…

web轮播图

思路: 例如:有5张轮播的图片,每张图片的宽度为1024px、高度为512px.那么轮播的窗口大小就应该为一张图片的尺寸,即为:1024512。之后将这5张图片0px水平相接组成一张宽度为:5120px,高度依然为:5…

2024华中杯A题完整1-3问py代码+完整思路16页+后续参考论文

A题太阳能路灯光伏板朝向问题 (完整版资料文末获取) 第1小问:计算每月15日的太阳直射强度和总能量 1. 理解太阳直射辐射和光伏板的关系**:光伏板接收太阳辐射并转化为电能,直射辐射对光伏板的效率影响最大。 2. 收集…

科技云报道:大模型加持后,数字人“更像人”了吗?

科技云报道原创。 北京冬奥运AI 虚拟人手语主播、杭州亚运会数字人点火、新华社数字记者、数字航天员小诤…当随着越来越多数字人出现在人们生活中,整个数字人行业也朝着多元化且广泛的应用方向发展,快速拓展到不同行业、不同场景。 面向C端&#xff0…

知识跟踪模型GraphKT

1 知识跟踪Knowledge Tracing的概念 知识跟踪可以用来解决自适应学习问题。如何通过与教学材料的在线互动来有效地跟踪学生的学习进展?知识跟踪可用于量化学生的知识状态,即对教材所涉及的技能掌握水平。用于评估和模拟学生随着时间推移对技能的认知掌握…

深入解析Nacos配置中心的动态配置更新技术

码到三十五 : 个人主页 心中有诗画,指尖舞代码,目光览世界,步履越千山,人间尽值得 ! 在微服务架构中,配置管理变得尤为关键。Nacos,作为一个开源的、易于使用的、功能丰富的平台,为…

案例与脚本实践:DolphinDB 轻量级实时数仓的构建与应用

DolphinDB 高性能分布式时序数据库,具有分布式计算、事务支持、多模存储、以及流批一体等能力,非常适合作为一款理想的轻量级大数据平台,轻松搭建一站式的高性能实时数据仓库。 本教程将以案例与脚本的方式,介绍如何通过 Dolphin…

MySql 表中的id突然变很大,如何给id重新排序

目录 一、场景 二、解决方法 一、场景 我们在开发过程中,难免遇到id突然增大的情况。 由于id突然增大很多,我们重新增加数据时候id会默认加1 那么如何让id 重新从1按顺序排序呢 二、解决方法 点击编辑表,然后新建一个字段id2,将…

【设计模式】聊聊观察者设计模式原理及应用

原理 观察者模式属于行为模式,行为模式主要解决类和对象之间交互问题。 含义:在对象之间定义一个一对多的依赖,当一个对象状态改变时,所有依赖的对象会自动通知。 被依赖的对象被观察者(Observable) ,依赖的对象观察…

策略模式类图与代码

某大型购物中心欲开发一套收银软件,要求其能够支持购物中心在不同时期推出的各种促销活动,如打折、返利(例如,满300返100),等等。现采用策略(Strategy)模式实现该要求,得到如图7.13 所示的类图。 【Java 代码】 import java.util…

NPU硬件架构及张量技术开发

NPU硬件架构及张量技术开发 NPU 系统介绍 V853 芯片内置一颗 NPU,其处理性能为最大 1 TOPS 并有 128KB 内部高速缓存用于高速数据交换,支持 OpenCL、OpenVX、android NN 与 ONNX 的 API 调用,同时也支持导入大量常用的深度学习模型。 NPU 系统架构 NPU 的系统架构如下图所示…