【嵌入式之中断】

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.mzph.cn/diannao/199.shtml

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

相关文章

极狐GitLab x LigaAI,AI 时代研发提效新范式

GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署极狐GitLab。 近日,极狐GitLab 和 LigaAI 宣布合作,双…

CentOS 7安装Zookeeper

说明:本文介绍如何在CentOS 7操作系统下使用Zookeeper 下载安装 首先,去官网下载所需要安装的版本,我这里下载3.4.9版本; 上传到云服务器上,解压 tar -xvf zookeeper-3.4.9.tar.gz修改配置 进入Zookeeper目录下的co…

【技术变现之道】如何打造IT行业的超级个体?

前言 在当今的数字化时代,IT行业蓬勃发展,为具备技术专长的个人提供了无限的可能性。想要成为IT行业的超级个体,实现知识与技能的变现吗?以下是一些高效途径,助你一臂之力! 1. 独立接单外包 1&#xff09…

vue3数字滚动组件

效果图 一、安装插件 npm i vue3-count-to 二、components文件夹下新建BaseCountTo.vue文件 <template><BaseCountTo :endVal"endVal" :decimals"decimals" /> </template> <script setup > import { defineComponent, watch, r…

改手机IP地址的软件推荐

随着移动互联网的普及&#xff0c;手机已成为人们日常生活中不可或缺的一部分。而在使用手机的过程中&#xff0c;IP地址作为一个重要的网络标识&#xff0c;有时也需要进行修改或更改。为了满足这一需求&#xff0c;市面上涌现出了许多改手机IP地址的软件。虎观代理将对这些软…

韩顺平Java | C27 正则表达式

入门介绍 需求&#xff1a;提取文本中某类字符 传统方法&#xff1a;遍历每个字符&#xff0c;判断其是否在ASCII码中某种类型得编码范围内&#xff0c;代码量大&#xff0c;效率不高 正则表达式(RegExp, regular expression)&#xff1a;处理文本的利器&#xff0c;是对字符…

java混淆的公司有哪些

一些提供 Java 混淆服务的公司包括&#xff1a; PreEmptive Solutions&#xff1a;PreEmptive Solutions 提供了一系列用于保护 Java 和 .NET 应用程序的工具&#xff0c;包括混淆、代码压缩、加密和漏洞检测等功能。 DexGuard&#xff1a;DexGuard 是 Guardsquare 公司推出的…

【JavaWeb】异步请求——AJAX

目录 Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;优点传统Web与Ajax的差异Ajax工作流程Ajax 经典应用场景XMLHttpRequest常用方法事件常用属性 ajax: GET请求和POST请求的区别 传统Ajax实现传统方式实现Ajax的不足 $.ajax()语法常用属性参数常用函数参数 Aja…

golang 迷宫回溯算法(递归)

// Author sunwenbo // 2024/4/14 20:13 package mainimport "fmt"// 编程一个函数&#xff0c;完成老鼠找出路 // myMap *[8][7]int 地图&#xff0c;保证是同一个地图&#xff0c;因此是引用类型 // i,j表示对地图的哪个点进行测试 func SetWay(myMap *[8][7]int, …

网络基础-基于TCP协议的Socket通讯

一、Socket通讯基于TCP协议流程图 UDP 的 Socket 编程相对简单些不在介绍。 二、 服务端程序启动 服务端程序要先跑起来&#xff0c;然后等待客户端的连接和数据。 服务端程序首先调用 socket() 函数&#xff0c;创建网络协议为 IPv4&#xff0c;以及传输协议为 TCP 的…

基于XML配置bean(二)

文章目录 1.工厂中获取bean1.静态工厂1.MyStaticFactory.java2.beans.xml3.测试 2.实例工厂1.MyInstanceFactory.java2.beans.xml3.测试 3.FactoryBean&#xff08;重点&#xff09;1.MyFactoryBean.java2.beans.xml3.测试 2.bean配置信息重用继承抽象bean1.beans.xml2.测试 3.…

HarmonyOS实战开发-如何实现一个简单的健康生活应用

功能概述 成就页面展示用户可以获取的所有勋章&#xff0c;当用户满足一定的条件时&#xff0c;将点亮本页面对应的勋章&#xff0c;没有得到的成就勋章处于熄灭状态。共有六种勋章&#xff0c;当用户连续完成任务打卡3天、7天、30天、50天、73天、99天时&#xff0c;可以获得…

SpringBoot框架——8.MybatisPlus常见用法(常用注解+内置方法+分页查询)

1.MybatisPlus常用注解&#xff1a; 1.1 当数据库、表名和字段名和实体类完全一致时无需加注解&#xff0c;不一致时&#xff1a; TableName指定库名 TableId指定表名 TableField指定字段名 1.2 自增主键&#xff1a; TableId(typeIdType.AUTO) private Long id; 1.3 实体类中属…

2000-2022年各省人力资本水平数据(含原始数据+计算过程+计算结果)(无缺失)

2000-2022年各省人力资本水平数据&#xff08;含原始数据计算过程计算结果&#xff09; 1、时间&#xff1a;2000-2022年 2、来源&#xff1a;国家统计局 3、指标&#xff1a;普通高等学校在校学生数(万人)、年末常住人口&#xff08;万人&#xff09;、人力资本水平 4、范…

CTFshow-PWN-前置基础(pwn20)

提交ctfshow{【.got表与.got.plt是否可写(可写为1&#xff0c;不可写为0)】,【.got的地址】,【.got.plt的地址】 前置基础知识&#xff1a; .got 和 .got.plt 是 ELF&#xff08;Executable and Linkable Format&#xff0c;可执行和可链接格式&#xff09;二进制文件中的两个…

(四)qt中使用ffmpeg播放视频,可暂停恢复

一、在qt中添加ffmpeg库及头文件 INCLUDEPATH /usr/local/ffmpeg/include LIBS -L/usr/local/lib -lavutil -lavcodec -lavformat -lswscale 二、详细代码 FFempegVideoDecode 视频解码类&#xff08;放入线程中&#xff09; ffmpegvideodecode.h #ifndef FFMPEGVIDEODE…

RHCE作业二

一.配置server主机要求如下&#xff1a; 1.server主机的主机名称为 ntp_server.example.com 2.server主机的IP为&#xff1a; 172.25.254.100 3.server主机的时间为1984-11-11 11&#xff1a;11&#xff1a;11 4.配置server主机的时间同步服务要求可以被所有人使用 二.设定cli…

Http 请求偶发400错误

1. 背景 生产环境偶发400请求错误&#xff0c;发生概率万分之一&#xff0c;异常信息如下&#xff1a; 1&#xff09; 从异常信息可以看到&#xff0c;skywalking的sw8 header解析失效导致异常信息。 2&#xff09; 0x0d0x0a 作为回车换行符号&#xff0c;没有被正确处理&#…

OpenGL:图元

OpenGL的图元 点 GL_POINTS: 将顶点绘制成单个的点 线 GL_LINES:将顶点用于创建线段,2个点成为一条单独的线段。如果顶点个数是奇数,则忽略最后一个。 顶点:v0, v1, v2, v3, … , vn,线段:v0-v1, v2-v3, v4-v5, … , vn-1 - vn GL_LINE_STRIP:将顶点用于创建线段,…

学习笔记(4月18日)vector底层模拟实现(1)

1.迭代器 vector实际上是由迭代器进行维护的&#xff0c;关于迭代器是什么&#xff0c;为什么要叫这个名字&#xff0c;后面的学习会逐渐了解&#xff0c;现在先将迭代器是作为指针即可。 vector底层有三个迭代器&#xff0c;用来起到容量、数组头、元素个数的作用。 同时为…