【STM32】中断与NVIC以外部中断为例
前言
在stm32中姑且可以认为,异常就是中断
单片机上电之后,首先执行启动文件,开辟堆栈之后,开始初始化中断向量表。
NVIC
NVIC
NVIC是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核
里面的一个外设。
####三个寄存器ISER
、ICER
和IP
NVIC 结构体定义,来自固件库头文件:core_cm3.h
在配置中断的时候我们一般只用 ISER
、ICER
和IP
这三个寄存器,ISER 用来使能中断,ICER 用来失能中断,IP 用来设置中断优先级。
ISER[8]
:Interrupt Set Enable Registers,这是一个中断使能寄存器组。是个u32类型的数组,成员有8个。 CM3、4 内核支持 256 个中断,这里用 8 个 32 位寄存器来控制,每个位控制一个中断。根据单片机生产厂商的设计,不一定会全部使用到。
ICER[8]
:全称是:Interrupt Clear Enable Registers,是一个中断除能寄存器组。该寄存器组与 ISER 的作用恰好相反,是用来清除某个中断的使能的。其对应位的功能,也和 ISER 一样。这里要专门设置一个 ICER 来清除中断位,而不是向 ISER 写 0 来清除,是因为 NVIC 的这些寄存器都是写 1 有效的,写 0 是无效的。
IP [240]
:全称是:Interrupt Priority Registers,是一个中断优先级控制的寄存器组。这个寄存器组相当重要!STM32F407 的中断分组与这个寄存器组密切相关。IP 寄存器组由 240 个 8bit的寄存器组成,每个可屏蔽中断占用 8bit,这样总共可以表示 240 个可屏蔽中断。而 STM32F407只用到了其中的 82 个。IP[81]-IP[0]分别对应中断 81~0。而每个可屏蔽中断占用的 8bit 并没有
全部使用,而是只用了高 4 位。这 4 位,又分为抢占优先级和子优先级。抢占优先级在前,子优先级在后。而这两个优先级各占几个位又要根据 SCB->AIRCR 中的中断分组设置来决定。
//----------以上是常用的NVIC寄存器,对NVIC的配置实际上就是配置这几个寄存器----------//
ISPR[8]
:全称是:Interrupt Set Pending Registers,是一个中断使能挂起控制寄存器组。每个位对应的中断和 ISER 是一样的。通过置 1,可以将正在进行的中断挂起,而执行同级或更高级别的中断。写 0 是无效的。
ICPR[8]
:全称是:Interrupt Clear Pending Registers,是一个中断解挂控制寄存器组。其作用与 ISPR 相反,对应位也和 ISER 是一样的。通过设置 1,可以将挂起的中断解挂。写 0 无效。
IABR[8]
:全称是:Interrupt Active Bit Registers,是一个中断激活标志位寄存器组。对应位所代表的中断和 ISER 一样,如果为 1,则表示该位所对应的中断正在被执行。这是一个只读寄存器,通过它可以知道当前在执行的中断是哪一个。在中断执行完了由硬件自动清零。
优先级的定义
1.优先级只有主优先级和子优先级
2.所谓的优先级分组是决定了IP寄存器的高4bit,其中哪几位代表主优先级,几位代表子优先级
3.数值越小所代表的优先级就越高
4.抢占优先级:抢占优先级高的中断可以打断正在执行的抢占优先级低的中断。
5.响应优先级:抢占优先级相同,响应优先级高的中断不能打断响应优先级低的中断。
还有一种情况就是当两个或者多个中断的抢占式优先级和响应优先级相同时,那么就遵循
自然优先级,看中断向量表的中断排序,数值越小,优先级越高。
先比较主优先级,再比较sub优先级,再按中断向量表的优先级序号比较
中断优先级寄存器 NVIC_IPRx,用来配置外部中断的优先级,IPR 宽度为 8bit,原则上每个外部中断可配置的优先级为 0~255,数值越小,优先级越高
。但是绝大多数CM3芯片都会精简设计,以致实际上支持的优先级数减少,在F103中,只使用了高 4bit。而这高4bit也会根据CB->AIRCR 寄存器的 bit10~8 的配置来决定主优先级占几位,子优先级占几位。
优先级的分组由内核外设 SCB 的应用程序中断及复位控制寄存器 AIRCR 的PRIGROUP[10:8]位决定,也就是说用于表达优先级的这4bit还需要根据优先级分组的配置,再进行主优先级和子优先级的配置。
优先级分组的设置是由 SCB->AIRCR 寄存器的 bit10~8 来定义的.
举个例子_设置优先级
设置优先级:设置优先级分组之后,再设置主优先级和子优先级
1.设置优先级分组
2.设置主优先级
3.设置sub优先级
例如SCB->AIRCR 寄存器的 bit10~8将优先级分组设置为3,那么此时所有的 82 个中断,每个中断的中断优先寄存器的高四位中的最高 3 位是抢占优先级,低 1 位是响应优先级。每个中断,你可以设置抢占优先级为 0~7,响应优先级为 1 或 0。抢占优先级的级别高于响应优先级。而数值越小所代表的优先级就越高。
举个例子_中断的打断
抢占优先级:抢占优先级高的中断可以打断正在执行的抢占优先级低的中断。
响应优先级:抢占优先级相同,响应优先级高的中断不能打断响应优先级低的中断。
假定设置中断优先级分组为 2,然后设置中断 3(RTC_WKUP 中断)的抢占优先级为 2,响应优先级为 1。中断 6(外部中断 0)的抢占优先级为 3,响应优先级为 0。中断 7(外部中断 1)的抢占优先级为 2,响应优先级为 0。那么这 3 个中断的优先级顺序为:
中断 7>中断 3>中断 6。
上面例子中的中断 3 和中断 7 都可以打断中断 6 的中断。而中断 7 和中断 3 却不可以相互打断!
NVIC 中断相关的库函数都在库文件 misc.c 和 misc.h 中
中断编程要点
一般情况下不使用库函数封装好的函数
编程时主要进行三步
1.使能中断
使能外设某个中断,比如USART的传输完成中断,接受完成中断等,这些由相关外设的控制寄存器进行控制,配置控制寄存器进行使能。这边是允许外设的具体某个中断,还需要在NVIC操作 NVIC_ISER 和 NVIC_ICER 这两个寄存器,进行中断的使能
2.配置NVIC
初始化 NVIC_InitTypeDef 结构体
2.1 设置中断源
2.2设定主优先级和sub优先级
2.3中断使能(ENABLE)或者失能(DISABLE),操作的是 NVIC_ISER 和 NVIC_ICER 这两个寄存器。
3.编写中断服务函数
启动文件 startup_stm32f10x_hd.s 中预先定义了中断服务函数,可以在里面进行编写。
NVIC 相关函数
NVIC 中断相关的库函数都在库文件 misc.c 和 misc.h 中(stm32f1系列)
把 core_cm4.h 文件的 NVIC 相关函数封装到 stm32f4xx_hal_cortex.c 文件中(stm32f4系列)
以外部中断EXTI为例
代码差不多就是这个意思,具体使用时需要修改
配置GPIO PA0引脚作为外部中断的流程
1) 使能 IO 口时钟。
使用 GPIO 之前必须开启 GPIO 端口的时钟;用到 EXTI 必须开启 AFIO 时钟。
GPIO_InitTypeDef GPIO_InitStructure;//
EXTI_InitTypeDef EXTI_InitStructure;//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);//打开GPIO的时钟,打开AFIO的时钟,
2)配置中断优先级(NVIC)
NVIC_InitTypeDef NVIC_InitStructure;
/* 配置 NVIC 为优先级组 1 所有82个中断源都属于优先级组1,主优先级0-1,子优先级0-7*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/* 配置中断源:exti1 */
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;/* 配置抢占优先级:1 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;/* 配置子优先级:1 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;/* 使能中断通道 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
3) 设置 IO 口模式,触发条件,设置 IO 口与中断线的映射关系,并使能中断。
# 设定GPIO模式
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;#浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);#设定EXTI触发条件
/* 选择 EXTI 的信号源 */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);EXTI_InitStructure.EXTI_Line = EXTI_Line0;
/* EXTI 为中断模式 */
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
/* 上升沿中断 */
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
/* 使能中断 */
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
4) 编写中断服务函数。
void EXTI0_IRQHandler(void){//确保是否产生了 EXTI Line 中断if (EXTI_GetITStatus(EXTI_Line0) != RESET){//TodoEXTI_ClearITPendingBit(EXTI_Line0);}
}
相关文章:

【STM32】中断与NVIC以外部中断为例
前言 在stm32中姑且可以认为,异常就是中断 单片机上电之后,首先执行启动文件,开辟堆栈之后,开始初始化中断向量表。 NVIC NVIC NVIC是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦…...

大学生网页设计制作作业实例代码 (全网最全,建议收藏) HTML+CSS+JS
文章目录 📚web前端期末大作业 (1500套) 集合一、网页介绍二、网页集合 三、作品演示A电影主题B漫画主题C商城主题D家乡主题E旅游主题F餐饮/美食主题G环境主题H游戏主题I 个人主题K体育主题L博客主题M汽车主题N文化主题P美妆主题Q企业主题R教育主题S其他主题 &#…...

Llama模型结构解析(源码阅读)
目录 1. LlamaModel整体结构流程图2. LlamaRMSNorm3. LlamaMLP4. LlamaRotaryEmbedding 参考资料: https://zhuanlan.zhihu.com/p/636784644 https://spaces.ac.cn/archives/8265 ——《Transformer升级之路:2、博采众长的旋转式位置编码》 前言&#x…...

基于XML实现SpringIoC配置
目录 SpringIoc创建与使用的大致步骤 一.基于xml配置SpringIoc 二.基于xml配置DI 三.创建IoC容器并获取组件 SpringIoc创建与使用的大致步骤 SpringIoC的创建与使用过程分为3步 1.编写配置信息(编写XML,注解、Java类) 2.创建IoC容器&…...

Kaniko在containerd中无特权快速构建并推送容器镜像
目录 一、kaniko是什么 二、kaniko工作原理 三、kanijo工作在Containerd上 基于serverless的考虑,我们选择了kaniko作为镜像打包工具,它是google提供了一种不需要特权就可以构建的docker镜像构建工具。 一、kaniko是什么 kaniko 是一种在容器或 Kube…...

分享5款不会被打入冷宫的神器软件
检查一下你最近安装的软件,他们是不是都一样无法避免最终被你打入冷宫的命运?我们明明很懂“在精不在多”的道理,却依然让我们的电脑塞满了形形色色无用的软件。你需要知道的是,如何找到一款适合自己且真正实用的电脑软件。 自…...

Windows如何部署Redis
一、简介 Redis (Remote Dictionary Server) 是一个由意大利人 Salvatore Sanfilippo 开发的 key-value 存储系统,具有极高的读写性能,读的速度可达 110000 次/s,写的速度可达 81000 次/s 。 二、下载 访问 https://github.com/tporadows…...
VUE数据双向绑定原理解析
VUE数据双向绑定原理解析 在Vue.js中,数据双向绑定是一项非常强大的功能。它使开发者能够轻松地将模板与数据进行动态关联,实现了页面和数据之间的实时同步更新。本文将深入探讨VUE中数据双向绑定的原理,并通过代码示例演示其工作机制。 1.…...
SSM商城项目实战:订单管理
SSM商城项目实战:订单管理 在SSM商城项目中,订单管理是一个非常重要的功能模块。本文将详细介绍订单管理的实现思路和步骤代码。 实现SSM商城项目中订单管理功能的思路如下: 设计数据库表结构:根据订单管理的需求,设计…...

SELinux 入门 pt.2
哈喽大家好,我是咸鱼 在《SELinux 入门 pt.1》中,咸鱼向各位小伙伴介绍了 SELinux 所使用的 MAC 模型、以及几个重要的概念(主体、目标、策略、安全上下文) 我们还讲到: 对于受 SELinux 管制的进程,会先…...

函数(个人学习笔记黑马学习)
1、函数定义 #include <iostream> using namespace std;int add(int num1, int num2) {int sum num1 num2;return sum; }int main() {system("pause");return 0; } 2、函数的调用 #include <iostream> using namespace std;int add(int num1, int num2…...

《Flink学习笔记》——第五章 DataStream API
一个Flink程序,其实就是对DataStream的各种转换,代码基本可以由以下几部分构成: 获取执行环境读取数据源定义对DataStream的转换操作输出触发程序执行 获取执行环境和触发程序执行都属于对执行环境的操作,那么其构成可以用下图表示…...

Vue3.0 新特性以及使用变更总结
Vue3.0 在2020年9月正式发布了,也有许多小伙伴都热情的拥抱Vue3.0。去年年底我们新项目使用Vue3.0来开发,这篇文章就是在使用后的一个总结, 包含Vue3新特性的使用以及一些用法上的变更。 图片.png 为什么要升级Vue3 使用Vue2.x的小伙伴都熟悉…...

ToBeWritten之VSOC安全运营
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬…...
2023爱分析·一站式通信解决方案市场厂商评估报告:牛信云
[图片] 01 中国企业出海发展背景及阶段 出海背景:出海,对中国企业而言,并不陌生。从最初的贸易型出海,到制造业崛起,再到互联网、移动互联网产业腾飞,中国企业在出海道路上走的越发稳健。行业也从最初的家电…...
微信小程序消防知识每天学平台设计与实现
摘 要 消防是当下一个人都需要在日常生活中所高度重视的事项。消防安全关系到居民的日常生活的安全,通过学习消防知识能够提升人们在日常生活中对于灾难的防范。通过对当下的大学生进行调查研究后发现,现在的年轻人在消防意识上比较的单薄,对…...

Oracle跨库访问DBLINK
1. DBLINK的介绍 Oracle在进行跨库访问时,可以创建DBLINK实现,比如要将UAT的表数据灌入开发环境,则可以使用UAT库为数据源,通过DBLINK实现将查出的数据灌入开发库。 简而言之就是在当前数据库中访问另一个数据库中的表中的数据 2…...
【vue3.0 组合式API与选项式API是什么,有什么区别】
vue3.0 组合式API与选项式API是什么 Vue3.0中引入了组合式API(Composition API),同时保留了选项式API(Options API)。两种 API 风格都能够覆盖大部分的应用场景。它们只是同一个底层系统所提供的两套不同的接口。实际…...
React配置代理的5种方法
React配置代理的五种方法的介绍 使用create-react-app的代理配置: 使用场景:适用于使用create-react-app创建的React项目,特别是小型项目或快速原型开发。优点:配置简单,无需额外安装依赖,适合快速开发和简…...

皮卡丘靶场搭建遇到的问题大全
该博客记录我在安装皮卡丘靶场中遇到的一些问题。 1、 phpstudy_pro启动Mysql失败 自己电脑开启了mysql服务,使用winr,services.msc,找到自己的mysql服务,关闭。再次尝试使用phpstudy_pro启动mysql,成功解决。 2、皮…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...

自然语言处理——文本分类
文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...

大模型——基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程
基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程 下载安装Docker Docker官网:https://www.docker.com/ 自定义Docker安装路径 Docker默认安装在C盘,大小大概2.9G,做这行最忌讳的就是安装软件全装C盘,所以我调整了下安装路径。 新建安装目录:E:\MyS…...