10、中断系统概述

news2024/12/26 10:36:52

目录

0x01、异常类型

0x0001、系统异常清单

0x0002、外部中断清单

0x02、NVIC 简介

0x0001、NVIC 寄存器

0x0002、NVIC 中断配置固件库

0x03、优先级

0x0001、优先级定义

0x0002、优先级分组

0x0003、中断编程


0x01、异常类型

STM32F103 在内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和外部中断。其中系统异常有8 个(如果把Reset 和HardFault 也算上的话就是10 个),外部中断有60 个。除了个别异常的优先级被定死外,其它异常的优先级都是可编程的。有关具体的系统异常和外部中断可在标准库文件stm32f10x.h 这个头文件查询到,在IRQn_Type 这个结构体里面包含了F103 系列全部
的异常声明。

0x0001、系统异常清单

0x0002、外部中断清单

0x02、NVIC 简介

在讲如何配置中断优先级之前,我们需要先了解下NVIC。NVIC 是嵌套向量中断控制器,控制着
整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。但是各个芯片厂商在设
计芯片的时候会对Cortex-M3 内核里面的NVIC 进行裁剪,把不需要的部分去掉,所以说STM32
的NVIC 是Cortex-M 3 的NVIC 的一个子集。

0x0001、NVIC 寄存器

typedef struct
{
  __IO uint32_t ISER[8];                      // 中断使能寄存器
       uint32_t RESERVED0[24];                                   
  __IO uint32_t ICER[8];                      // 中断清除寄存器
       uint32_t RSERVED1[24];                                    
  __IO uint32_t ISPR[8];                      // 中断使能悬起寄存器
       uint32_t RESERVED2[24];                                   
  __IO uint32_t ICPR[8];                      // 中断清除悬起寄存器
       uint32_t RESERVED3[24];                                   
  __IO uint32_t IABR[8];                      // 中断有效位寄存器
       uint32_t RESERVED4[56];                                   
  __IO uint8_t  IP[240];                      // 中断优先级寄存器(8Bit wide)
       uint32_t RESERVED5[644];                                  
  __O  uint32_t STIR;                         // 软件触发中断寄存器
}  NVIC_Type;

在配置中断的时候我们一般只用ISER、ICER 和IP 这三个寄存器,ISER 用来使能中断,ICER 用
来失能中断,IP 用来设置中断优先级。

0x0002、NVIC 中断配置固件库

固件库文件core_cm3.h 的最后,还提供了NVIC 的一些函数,这些函数遵循CMSIS 规则,只要
是Cortex-M3 的处理器都可以使用,具体如下:

 这些库函数我们在编程的时候用的都比较少,甚至基本都不用。在配置中断的时候我们还有更简
洁的方法,请看中断编程小节。

0x03、优先级

0x0001、优先级定义

在NVIC 有一个专门的寄存器:中断优先级寄存器NVIC_IPRx,用来配置外部中断的优先级,IPR
宽度为8bit,原则上每个外部中断可配置的优先级为0~255,数值越小,优先级越高。但是绝大
多数CM3 芯片都会精简设计,以致实际上支持的优先级数减少,在F103 中,只使用了高4bit,
如下所示:

用于表达优先级的这4bit,又被分组成抢占优先级和子优先级。如果有多个中断同时响应,抢占
优先级高的就会抢占抢占优先级低的优先得到执行,如果抢占优先级相同,就比较子优先级。

果抢占优先级和子优先级都相同的话,就比较他们的硬件中断编号,编号越小,优先级越高。

0x0002、优先级分组

优先级的分组由内核外设SCB 的应用程序中断及复位控制寄存器AIRCR 的PRIGROUP[10:8] 位
决定,F103 分为了5 组,具体如下:主优先级= 抢占优先级

设置优先级分组可调用库函数NVIC_PriorityGroupConfig() 实现,有关NVIC 中断相关的库函数都
在库文件misc.c 和misc.h 中。

NVIC_PriorityGroupConfig 是整个程序中只需要设置一次。 若重复调用相当于对中断相关寄存器重复赋值多次取最后一次赋值,并且从代码布局逻辑来说,NVIC_PriorityGroupConfig 适合放在main() 函数中。

从上图可以看出,NVIC_PriorityGroupConfig实际上就决定了整个程序中所有中断的主优先级、子优先级的个数。

0x0003、中断编程

在配置每个中断的时候一般有3 个编程要点:

1. 使能外设某个中断,这个具体由每个外设的相关中断使能位控制。比如串口有发送完成中
断,接收完成中断,这两个中断都由串口控制寄存器的相关中断使能位控制。

2. 初始化NVIC_InitTypeDef 结构体,配置中断优先级分组,设置抢占优先级和子优先级,使
能中断请求。NVIC_InitTypeDef 结构体在固件库头文件misc.h 中定义。

typedef struct
{
  uint8_t NVIC_IRQChannel;                    // 中断源
  uint8_t NVIC_IRQChannelPreemptionPriority;  // 抢占优先级
  uint8_t NVIC_IRQChannelSubPriority;         // 子优先级
  FunctionalState NVIC_IRQChannelCmd;         // 中断使能或失能  
} NVIC_InitTypeDef;

有关NVIC 初始化结构体的成员我们一一解释下:

a. NVIC_IROChannel:用来设置中断源,不同的中断中断源不一样,且不可写错,即使写错了程序也不会报错,只会导致不响应中断。具体的成员配置可参考stm32f10x.h 头文件里面的IRQn_Type结构体定义,这个结构体包含了所有的中断源。

b. NVIC_IRQChannelPreemptionPriority:抢占优先级,具体的值要根据优先级分组来确定,具体
参考表格优先级分组真值表优先级分组真值表。

c. NVIC_IRQChannelSubPriority:子优先级,具体的值要根据优先级分组来确定,具体参考表格
优先级分组真值表优先级分组真值表。

d. NVIC_IRQChannelCmd:中断使能(ENABLE)或者失能(DISABLE)。操作的是NVIC_ISER
和NVIC_ICER 这两个寄存器。

3. 编写中断服务函数

在启动文件startup_stm32f10x_hd.s 中我们预先为每个中断都写了一个中断服务函数,只是这些
中断函数都是为空,为的只是初始化中断向量表。实际的中断服务函数都需要我们重新编写,为
了方便管理我们把中断服务函数统一写在stm32f10x_it.c 这个库文件中。
关于中断服务函数的函数名必须跟启动文件里面预先设置的一样,如果写错,系统就在中断向量
表中找不到中断服务函数的入口,直接跳转到启动文件里面预先写好的空函数,并且在里面无限
循环,实现不了中断。

补充说明

后续其他例程的某个外设配置过程的自定义函数如NVIC_Configuration() 分别执行了
NVIC_PriorityGroupConfig() 配置中断优先级分组,NVIC_Init(&NVIC_InitStructure) 配置结构体赋
值的将要设置的中断向量和其优先级,注意这里的NVIC_PriorityGroupConfig 是整个程序中只
需要设置一次。
当设置好了中断优先级分组,其他各种外设对应的中断向量的中断优先级既是基于目前设置分
组来解读,假设配置为NVIC_PriorityGroup_0 或者NVIC_PriorityGroup_4,那么给多个外设分别
填充NVIC_InitStructure 的子优先级或主优先级是无效的,所以说如果工程里面有用到许多的外
设中断,那么在确定了想用哪一种优先级分组后再给每个外设对应的中断向量配置优先级。
在其他例程中很多将NVIC_PriorityGroupConfig 写在了每个外设自己的中断配置函数里面,有些
可能多个外设配置函数下重复了NVIC_PriorityGroupConfig() 这句,这里提醒用户后续编写自己
程序时只需要调用一次即可,若重复调用相当于对中断相关寄存器重复赋值多次取最后一次赋
值,并且从代码布局逻辑来说,NVIC_PriorityGroupConfig 适合放在main() 函数中。

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

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

相关文章

重金打造SEA浩瀚架构,吉利的野心绝不仅仅是一个平台

(作者:贝贝。常年供职于某外资整车企业产品规划部门,负责全球车型在国内的引入和投放)最近几个月,吉利旗下的中高端电动车品牌极氪汽车销量一路走高。单凭借极氪001一款车型,10月、11月交付量连续破万&…

查找:折半查找、平衡二叉树、散列表(习题-1、5、6)二叉排序树(习题-2、3、4)

一个不知名大学生,江湖人称菜狗 original author: jacky Li Email : 3435673055qq.com Time of completion:2023.1.1 Last edited: 2023.1.1 目录 查找:折半查找、平衡二叉树、散列表(习题-1、5、6) 第1关&#xff1…

04.spring源码循环依赖终极讲解

1.Spring怎么解决循环依赖 我们都知道&#xff0c;单例Bean初始化完成&#xff0c;要经历三步&#xff1a; 注入就发生在第二步&#xff0c;属性赋值&#xff0c;结合这个过程&#xff0c;Spring 通过三级缓存解决了循环依赖&#xff1a; 一级缓存 : Map<String,Object>…

PUCCH传输UCI信息

上报HARQ-ACK 时序 传输HARQ-ACK信息的时序不再像4G那样固定&#xff0c;而是由基站侧配置给UE。有下面几种情况&#xff1a; 如果UE收到的是DCI format 1_0&#xff0c;其中的字段’PDSCH-to-HARQ_feedback timing indicatior’指示HARQ-ACK与PDSCH的时序关系&#xff0c;该…

Linux之孤儿进程、进程优先级、环境变量

本章目录1.孤儿进程2.状态优先级3.环境变量1.孤儿进程 父进程如果提前退出&#xff0c;那么子进程后退出&#xff0c;进入Z之后&#xff0c;那该如何处理&#xff1f; 父进程先退出&#xff0c;子进程还在&#xff0c;子进程就称之为“孤儿进程”。 孤儿进程被1号init进程&am…

移动安全APT事件总结及防御解决方案探讨

声明 本文是学习移动安全总结 2019. 下载地址而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 2019年各地移动APT事件总结 2019年世界依旧不太平&#xff0c;在表面平静的背后是暗流涌动。大规模军事冲突不会发生的当下&#xff0c;因利益&#xff0c;…

Python全栈开发(一)——环境搭建和入门

今天是2023年的第一天&#xff0c;接下来的一个月里&#xff0c;我将持续更新关于python全栈开发的相关知识&#xff0c;前面一段时间都是基础语法。主要分成四大块&#xff1a;基础、面向对象、MYSQL数据库、Django框架。话不多说&#xff0c;进入到今天的主题。 1.文档和工具…

聊聊最适合程序员的画图工具

画图工具 没问题&#xff0c;直接坦白讲&#xff0c;我用了 2 年的画图工具是&#xff1a;draw.io。 我的图解文章里的图片全是在 draw.io 这个工具画的&#xff0c;写了那么久的图解文章&#xff0c;再加上我工作中也有画图的习惯&#xff0c;累计也有在上面画了接近 1000 张…

树形压缩DP——没有上司的舞会

树形压缩DP——没有上司的舞会一、问题描述二、DFS暴搜1、算法思路2、代码实现三、DP做法一、问题描述 二、DFS暴搜 1、算法思路 这道题其实最容易想到的是暴力DFS&#xff0c;然后选出一个最大值。我们平时会在DFS的形参中设置一个变量表示子树的根。但是今天这道题还涉及到…

mysql的事务和锁

【MySQL事务和锁】 学习原文&#xff1a;https://blog.csdn.net/zly03/article/details/127170995 事务四大特性&#xff1a;原子性、一致性、隔离性、持久性&#xff0c;简称ACID MySQL中支持3种不同的存储引擎&#xff1a; MyISAM存储引擎、Memory存储引擎、和InnoDB存储引…

CMake使用外部动态库/静态库和头文件

CMake使用外部动态库/静态库和头文件一、准备工作二、新建一个新的CMake工程三、开始构建四、为target添加共享库五、链接静态库一、准备工作 在博文《使用CMake构建静态库和动态库》中已经介绍了libhello动态库的构建和安装&#xff0c;现在我们看看如何使用这个外部动态库。…

iOS 15.0+ 中 SwiftUI 顶部或底部悬浮功能小面板的极简实现

功能需求 我们有时需要在 App 主视图的顶部或底部固定悬浮放置一个功能视图: 如上图所示,我们将一个列表项目输入小面板按需放在主视图的顶部或底部: 当放置在顶部时,解决了其对导航栏(NavigationView)中 toolbar 内容的遮挡问题;当放置在底部时,考虑到了其对列表最后…

spring boot 实现搜索引擎的设计思想

目录 实现思路 索引模块 预处理 对文档进行分词 搜索模块 实现思路 索引构建模块 搜索模块 数据库模块 索引模块 对于搜索一个东西&#xff0c;我们很自然的能想到遍历去查找。比如我要查找一本书叫 《红楼梦》&#xff0c;那么我直接在所有结果中进行遍历查找&#xff…

druid解析-过滤器详解

druid支持过滤器&#xff0c;可以在获取连接或者调用连接对象的方法时&#xff0c;先调用过滤器&#xff0c;之后再执行底层方法&#xff0c;比如DruidDataSource的getConnection()方法&#xff1a; public DruidPooledConnection getConnection(long maxWaitMillis) throws SQ…

网络安全一哥的奇安信发布了全球高级可持续威胁年度报告 值得学习

声明 本文是学习全球高级持续性威胁 APT 2021年度报告. 下载地址而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 中国境内高级持续性威胁综述 基于中国境内海量DNS域名解析和奇安信威胁情报中心失陷检测&#xff08;IOC&#xff09;库的碰撞分析&…

9_1、Java基本语法之常用类String、StringBuffer、StringBuilder的使用

一、String的使用及常用方法 1、概述 String:表示字符串&#xff0c;使用""引起来。 1.1、String类是声明为final的&#xff0c;不可被继承。 1.2、String类实现了Serializable接口&#xff0c;表示字符串支持序列化。 …

【王道操作系统】2.1.3 原语实现对进程的控制

原语实现对进程的控制 文章目录原语实现对进程的控制1.什么是进程控制2.原语实现对进程的控制3.回忆进程的组织4.进程控制大致图解5.进程控制原语的相同点6.进程控制的五种原语1.什么是进程控制 2.原语实现对进程的控制 3.回忆进程的组织 4.进程控制大致图解 这里说明一下调度和…

MySQL【AUTO_INCREMENT 】自增列

使用案例场景再现&#xff1a; 创建一个为test的数据库&#xff0c;为数据库test创建一个数据表student &#xff0c;其中包含的字段有 id name sex&#xff0c;admission_time,其中要求student表中的人员id必须连续排列。 create database test use test cr…

SCI论文解读复现【NO.1】基于Transformer-YOLOv5的侧扫声纳图像水下海洋目标实时检测

此前出了目标改进算法专栏&#xff0c;但是对于应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读最新目标检测算法论文&#xff0c;帮助…

三旗舰焕新发布引领品牌向上 长城汽车登陆2022广州车展

近日&#xff0c;长城汽车携哈弗、魏牌、欧拉、坦克、长城炮以及沙龙六大品牌&#xff0c;登陆第二十届广州国际汽车展览会&#xff08;以下简称“2022广州车展”&#xff09;。魏牌全新旗舰蓝山DHT-PHEV、坦克500 PHEV长续航版、大型高性能豪华皮卡山海炮等车型联袂而至&#…