【物联网】STM32的中断机制不清楚?看这篇文章就足够了

news2024/11/13 9:04:48

在嵌入式系统中,中断是一种重要的机制,用于处理来自外部设备的异步事件。STM32系列微控制器提供了强大的中断控制器,可以方便地处理各种外部中断和内部中断。本文将详细介绍STM32中断的结构和使用方法。
在这里插入图片描述


文章目录

    • 1. 什么叫中断
    • 2. 中断优先级
      • 2.1 有抢占优先级为什么还要子优先级?
    • 3. 中断嵌套
    • 4. 中断结构
    • 5. 中断使用方法
    • 总结


1. 什么叫中断

中断是计算机系统中的一种机制,用于处理突发事件或异步事件。在计算机运行过程中,CPU通常是按照指令的顺序依次执行的,但是当发生某些特殊事件时,如外部设备的输入、定时器的溢出等,CPU需要立即中断当前的任务,转而处理这些事件。这样可以提高系统的响应速度和效率。

中断可以看作是一种突然的打断,类似于我们在做一件事情的时候突然收到了一个电话,需要立即停下手头的工作去接听电话。中断可以分为硬件中断软件中断两种类型。

在这里插入图片描述

硬件中断是由外部设备触发的,如键盘输入、鼠标点击等。当外部设备触发了中断信号时,CPU会立即停止当前的任务,转而执行与中断相关的处理程序。处理完中断后,CPU会返回到之前被中断的地方继续执行。

软件中断是由程序中的特殊指令触发的。程序可以通过软件中断指令,主动请求CPU中断当前任务,执行与中断相关的处理程序。软件中断可以用来实现特定的功能,如操作系统的系统调用。


2. 中断优先级

在STM32微控制器中,中断优先级是用来确定**中断服务程序(ISR)**执行的顺序的。STM32系列微控制器支持多个中断源,并且每个中断源都有一个对应的中断优先级。

中断优先级可以分为两个级别:抢占优先级子优先级

在这里插入图片描述

  1. 抢占优先级(Preemption Priority):抢占优先级决定了当多个中断同时发生时,哪个中断可以中断当前正在执行的中断。具有较高抢占优先级的中断可以打断正在执行的较低优先级中断,并立即执行自己的中断服务程序。
  1. 子优先级(Subpriority):子优先级用于决定在同一抢占优先级的多个中断中,哪个中断将首先得到执行。具有较高子优先级的中断将在同一抢占优先级的其他中断之前得到执行。

2.1 有抢占优先级为什么还要子优先级?

抢占优先级和子优先级的组合可以提供更灵活的中断控制和调度。抢占优先级主要用于处理多个中断同时发生时的中断抢占关系,而子优先级则用于处理同一抢占优先级的多个中断的执行顺序。

使用抢占优先级可以确保关键的中断能够及时中断正在执行的低优先级中断,并立即执行自己的中断服务程序。这对于实时性要求较高的应用非常重要。

然而,当多个中断具有相同的抢占优先级时,如果没有子优先级的支持,它们将按照先后顺序依次执行,无法进行更细粒度的调度。一般情况下,抢占优先级的位数比子优先级的位数多,因此抢占优先级的范围更广,可以提供更细粒度的中断控制。通过使用子优先级,可以在同一抢占优先级的多个中断中确定首先执行的中断。这对于需要优先处理某些特定中断的应用非常有用。


3. 中断嵌套

中断嵌套是指在一个中断服务程序(ISR)执行期间,另一个中断发生并触发了相应的中断服务程序的执行。当一个中断正在处理时,如果有更高优先级的中断发生,系统将暂停当前中断的处理,转而去处理更高优先级的中断,这就是中断嵌套。

在这里插入图片描述

中断嵌套在实时系统中非常常见,它允许系统在处理一个中断时能够及时响应更高优先级的中断请求。通过中断嵌套,可以实现对多个中断请求的优先级排序和处理,确保关键中断能够及时中断正在执行的较低优先级中断,并立即执行自己的中断服务程序。

在STM32微控制器中,中断嵌套是通过抢占优先级和子优先级来实现的。当一个中断正在执行时,如果有更高抢占优先级的中断请求发生,系统会立即中断当前中断的执行,并开始处理更高优先级的中断。如果多个中断具有相同的抢占优先级,那么子优先级将决定它们的执行顺序。

中断嵌套可能会引入一些问题,如中断嵌套深度过大可能导致系统性能下降,同时需要合理地处理中断优先级和中断服务程序的互斥和同步问题,以确保系统的正确性和可靠性。


4. 中断结构

4.1 中断向量表(Interrupt Vector Table):中断向量表是一个存储中断向量地址的数据结构,用于存储中断服务函数的入口地址。当一个中断发生时,微控制器会根据中断号从中断向量表中读取相应的ISR地址,并跳转到该地址执行中断服务程序。在STM32中,中断向量表存储在内部闪存的起始地址处。

中断向量表的大小取决于微控制器支持的中断数量。对于STM32系列微控制器,通常采用的是基于向量表的中断处理方式,其中中断向量表的大小是固定的,每个中断向量的大小是4个字节。因此,中断向量表的大小等于中断数量乘以4个字节。

在编程中,我们可以通过修改中断向量表中的中断向量来指定每个中断的ISR地址。通常,我们会使用编译器提供的特定语法来定义中断向量表和中断服务程序,并将它们放置在正确的地址位置。

需要注意的是,中断向量表是只读的,它存储了系统在编译时确定的中断服务程序的地址。因此,在运行时无法修改中断向量表。如果需要动态地改变中断服务程序的执行地址,可以使用中断向量重定向技术,即通过修改中断向量表中的中断向量,将中断重定向到其他地址。但这种技术需要小心使用,以避免引入不可预测的错误。

在这里插入图片描述


4.2 中断控制器(Nested Vectored Interrupt Controller,NVIC):NVIC是STM32中断控制器的核心组件,用于管理和控制中断。它支持多级中断优先级,可以配置中断优先级、使能或禁用中断,并提供中断向量表的地址。

在这里插入图片描述

NVIC有以下几个主要的功能:

  • 中断优先级管理:NVIC允许为每个中断分配一个抢占优先级和一个子优先级。抢占优先级用于确定中断的抢占关系,而子优先级用于确定同一抢占优先级的多个中断的执行顺序。NVIC提供了寄存器来配置和管理中断的优先级。

  • 中断使能/禁止控制:NVIC提供了寄存器来使能或禁止特定的中断。通过设置相应的位,可以选择性地使能或禁止中断。这对于灵活地控制中断的触发和执行非常有用。

  • 中断状态管理:NVIC提供了寄存器来管理中断的状态。例如,可以通过读取和写入中断挂起寄存器来判断中断是否处于挂起状态,以及通过写入中断清除寄存器来清除中断标志。

  • 中断向量表偏移:NVIC允许通过设置偏移量来修改中断向量表的起始地址。这对于实现中断向量重定向非常有用,可以将中断重定向到其他地址。


4.3 中断服务函数(Interrupt Service Routine,ISR):中断服务函数是中断发生时执行的代码块。在STM32中,中断服务函数需要使用特定的函数声明和命名规则,并通过中断向量表进行注册。

在这里插入图片描述


5. 中断使用方法

  1. 配置中断优先级:首先,需要使用NVIC_SetPriority()函数设置中断的抢占优先级和子优先级。该函数的参数包括中断通道号和优先级值。

  2. 初始化中断向量表:在启动代码中,需要初始化中断向量表的起始地址。可以使用NVIC_SetVectorTable()函数来设置中断向量表的偏移地址。

  3. 注册中断处理函数:使用NVIC_Init()函数注册中断处理函数。该函数的参数包括中断通道号、中断优先级和中断处理函数的地址。

  4. 使能中断:使用NVIC_EnableIRQ()函数使能中断。该函数的参数为中断通道号。

  5. 编写中断处理函数:编写中断处理函数,处理中断事件发生时的逻辑。中断处理函数的命名和参数取决于所使用的中断通道和编程语言。

以下是一个示例代码,演示了如何使用标准外设库函数实现中断:

#include "stm32f10x.h"

// 中断处理函数
void EXTI0_IRQHandler(void)
{
    // 处理中断事件逻辑
    // ...

    // 清除中断标志
    EXTI_ClearITPendingBit(EXTI_Line0);
}

int main(void)
{
    // 初始化中断向量表
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

    // 配置中断优先级
    NVIC_SetPriority(EXTI0_IRQn, 0);

    // 注册中断处理函数
    NVIC_InitTypeDef NVIC_InitStructure;
    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);

    // 使能中断
    NVIC_EnableIRQ(EXTI0_IRQn);

    while (1)
    {
        // 主循环逻辑
        // ...
    }
}

总结

STM32中断提供了强大的功能,可以方便地处理各种外部中断和内部中断。通过合理配置中断优先级和中断服务函数,可以实现对异步事件的及时响应。在实际应用中,需要根据具体需求和硬件设备,合理使用中断功能,提高系统的可靠性和性能。

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

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

相关文章

Spring Cloud Gateway:打造可扩展的微服务网关

文章目录 什么是微服务网关?Spring Cloud Gateway的优势使用Spring Cloud Gateway构建微服务网关步骤1:添加依赖步骤2:创建路由配置步骤3:创建过滤器步骤4:运行应用程序 进一步探索结论 🎉欢迎来到架构设计…

Ubuntu Server CLI专业提示

基础 网络 获取所有接口的IP地址 networkctl status 显示主机的所有IP地址 hostname -I 启用/禁用接口 ip link set <interface> up ip link set <interface> down 显示路线 ip route 将使用哪条路线到达主机 ip route get <IP> 安全 显示已登录的用户 w…

一看就懂系列:阿里云服务器ECS和轻量云服务器对比

阿里云服务器ECS和轻量应用服务器有什么区别&#xff1f;轻量和ECS优缺点对比&#xff0c;云服务器ECS是明星级云产品&#xff0c;适合企业专业级的使用场景&#xff0c;轻量应用服务器是在ECS的基础上推出的轻量级云服务器&#xff0c;适合个人开发者单机应用访问量不高的网站…

【小沐学前端】Windows下搭建WordPress(nginx1.25、PHP8.2、WordPress6.3、MySQL5.7)

文章目录 1、简介1.1 Nginx1.2 PHP1.3 WordPress1.4 MySQL 2、下载2.1 Nginx2.2 PHP2.3 WordPress2.4 MySQL 3、搭建环境3.1 Nginx3.2 PHP3.3 WordPress3.4 MySQL 4、配置WordPress4.1 选择语言4.2 配置数据库4.3 登录界面4.4 常规设置4.5 写作操作 结语 1、简介 WordPress是基…

波奇学C++:AVL树

AVL解决二叉搜索树退化成链表&#xff0c;保证左右子树高度不差过1&#xff0c;尽可能接近满二叉树 AVL树的性质&#xff1a;高度差&#xff08;平衡因子&#xff09;的绝对值不超过1&#xff08;-1/0/1&#xff09; 平衡因子&#xff1a;右子树高度-左子树高度 用平衡因子控…

Netron可视化深度学习网络结构

有时候&#xff0c;我们构建网络模型想要直观的查看网络详细结构图&#xff0c;但是苦于没有办法。但是有了Netron以后&#xff0c;我们就可以将对应的onnx模型直接可视化&#xff0c;这样不仅可以观察网络的详细结构图&#xff0c;还可以查看网络每一层的具体参数&#xff0c;…

【算法练习Day12】树的递归遍历非递归遍历

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 递归遍历前序遍历中序遍历后…

23.3 Bootstrap 框架4

1. 轮播 1.1 轮播样式 在Bootstrap 5中, 创建轮播(Carousel)的相关类名及其介绍: * 1. carousel: 轮播容器的类名, 用于标识一个轮播组件. * 2. slide: 切换图片的过渡和动画效果. * 3. carousel-inner: 轮播项容器的类名, 用于包含轮播项(轮播图底下椭圆点, 轮播的过程可以显…

[论文必备]最强科研绘图分析工具Origin(2)——简单使用教程

本篇将介绍Origin的简单使用教程。 安装教程见上篇&#xff1a;[论文必备]最强科研绘图分析工具Origin&#xff08;1&#xff09;——安装教程 目录 &#x1f4e2;一、工具栏介绍 &#x1f4e3;1.1 行 1.1.1 标准栏 1.1.2 导入栏 1.1.3 工作表数据 1.1.4 图表数据 &a…

第二章 线性表

线性表 线性表的基本概念线性表的顺序存储线性表顺序存储的类型定义线性表基本运算在顺序表上的实现顺序表实现算法的分析 线性表的链接存储单链表的类型定义线性表的基本运算在单链表上的实现 其他运算在单链表上的实现建表删除重复结点 其他链表循环链表双向循环链表 顺序实现…

【Docker】搭建 Docker 镜像仓库

文章目录 前言&#xff1a;公有仓库和私有仓库公共镜像仓库私有镜像仓库 一、搭建 Docker 镜像仓库1.1 搭建简化版的镜像仓库1.2 搭建带有图形化界面的镜像仓库1.3 配置 Docker 信任地址 二、向私有镜像仓库推送和拉取镜像2.1 推送本地镜像到私有仓库2.2 拉取私有仓库中的镜像 …

【Redis】基础数据结构-skiplist跳跃表

有序集合Sorted Set zadd zadd用于向集合中添加元素并且可以设置分值&#xff0c;比如添加三门编程语言&#xff0c;分值分别为1、2、3&#xff1a; 127.0.0.1:6379> zadd language 1 java (integer) 1 127.0.0.1:6379> zadd language 2 c (integer) 1 127.0.0.1:6379…

Swift 5.9 与 SwiftUI 5.0 中新 Observation 框架应用之深入浅出

0. 概览 Swift 5.9 一声炮响为我们带来全新的宏&#xff08;Macro&#xff09;机制&#xff0c;也同时带来了干霄凌云的 Observation 框架。 Observation 框架可以增强通用场景下的使用&#xff0c;也可以搭配 SwiftUI 5.0 而获得双剑合璧的更强威力。 在本篇博文&#xff0c…

计算机网络笔记3 数据链路层

计算机网络系列笔记目录&#x1f447; 计算机网络笔记6 应用层计算机网络笔记5 运输层计算机网络笔记4 网络层计算机网络笔记3 数据链路层计算机网络笔记2 物理层计算机网络笔记1 概述 文章前言 &#x1f497; 站在巨人的肩膀上&#xff0c;让知识的获得更加容易&#xff01…

给列起别名(关键字:as)

MySQL从小白到总裁完整教程目录:https://blog.csdn.net/weixin_67859959/article/details/129334507?spm1001.2014.3001.5502 语法格式: select 列名1 as 别名1, 列名2 as 别名2, 列名n as 别名n from 表名; 说明&#xff1a;可以省略as&#xff0c;列名和别名之间使用空格…

力扣 -- 873. 最长的斐波那契子序列的长度

解题步骤&#xff1a; 参考代码&#xff1a; class Solution { public:int lenLongestFibSubseq(vector<int>& nums) {int nnums.size();unordered_map<int,int> hash;for(int i0;i<n;i){hash[nums[i]]i;}int ret2;vector<vector<int>> dp(n,v…

关于内存对齐你需要了解的事

简介 这篇文章的目的是带你了解什么是内存对齐&#xff0c;具体的内存对齐的细节、处理方式、不同架构则不会去详细讲解&#xff0c;只做科普文用。 1、什么是内存对齐 内存对齐和数据在内存中的位置有关。内存对齐以字节为单位进行&#xff0c;一个变量的内存地址如果正好等于…

集合(容器)-List接口及实现类

容器的特征&#xff1a;①数据长度可变&#xff1b;②数据保存方式不同。 集合体系概述&#xff1a;JAVA的集合框架是由很多接口、抽象类、具体类组成。都位于java.util包中。 Java中集合类中默认可以存储任意数据类型&#xff0c;Java中的集合提供泛型机制&#xff0c;在定义…

mysql5.7停止维护时间

mysql5.7将于2023年10月停止官网支持和更新&#xff1b;老项目要准备升级&#xff0c;新项目的mysql必须是mysql8.0&#xff08;2023-10&#xff09; 官方升级咨询地址 oracle官方升级咨询地址https://go.oracle.com/LP116153?elq_mid247718&sh1518132002061316121320310…

.Net开源迁移框架FluentMigrator的使用。

在实际的开发过程中&#xff0c;经常会遇到数据库结构变动&#xff0c;比如新增表、删除表&#xff1b;已有的表新增字段&#xff0c;删除字段&#xff1b;修改字段属性等等。而且需要开发环境、测试环境和生产环境进行同步。如果使用的是EF&#xff0c;还是挺方便的。而非EF环…