【STM32】中断与NVIC以外部中断为例

news2024/11/13 14:30:01

前言

在stm32中姑且可以认为,异常就是中断

单片机上电之后,首先执行启动文件,开辟堆栈之后,开始初始化中断向量表。

NVIC

NVIC

NVIC是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。

####三个寄存器ISERICERIP
NVIC 结构体定义,来自固件库头文件:core_cm3.h
在配置中断的时候我们一般只用 ISERICERIP 这三个寄存器,ISER 用来使能中断,ICER 用来失能中断,IP 用来设置中断优先级。
NVIC 结构体定义,来自固件库头文件:core_cm3.h
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){
	//Todo
	EXTI_ClearITPendingBit(EXTI_Line0);
	}
}

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

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

相关文章

【附安装包】MyEclipse2019安装教程

软件下载 软件:MyEclipse版本:2019语言:简体中文大小:1.86G安装环境:Win11/Win10/Win8/Win7硬件要求:CPU2.5GHz 内存4G(或更高)下载通道①百度网盘丨下载链接:https://pan.baidu.co…

04 移动零

移动零 题解1 冒泡(保证操作顺序)题解2 双指针(推荐) 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时 保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数…

气传导耳机哪个品牌比较好?综合表现很不错的气传导耳机推荐

​气传导耳机不仅能够提升幸福感还能听到周围环境声,大大提高安全性。如果你在寻找一款高品质的气传导耳机,又不知从何入手时,不要担心,我已经为你精心挑选了四款市面上综合表现很不错的气传导耳机,让你享受更好的音质…

Linux C++ 海康摄像头获取过车信息

代码 void CALLBACK MessageCallback(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void *pUser) {printf("enter MessageCallback---------------------->\n");int i;NET_DVR_ALARMINFO_V30 struAlarmInfo;memcpy(&struAl…

Python钢筋混凝土结构计算.pdf-已知弯矩确定混凝土梁截面尺寸

计算原理 确定混凝土梁截面的合理尺寸通常需要考虑弯矩、受力要求和约束条件等多个因素。以下是一种常见的计算公式,用于基于已知弯矩确定混凝土梁截面的合理尺寸: 请注意,以上公式仅提供了一种常见的计算方法,并且具体的规范和设…

长胜证券:A股连续上行 市场信心进一步修复

昨日,A股商场进一步上行,接连第二个交易日上涨,上证指数涨1.20%,站上3100点整数关口,创业板和科创板涨势可观,科创50指数涨幅高达4.12%。 昨日商场呈现更明显的普涨格式,汽车、计算机、电子、传…

[Android AIDL] --- AIDL原理简析

上一篇文章已经讲述了如何在Android studio中搭建基于aidl的cs模型框架,只是用起来了,这次对aidl及cs端如何调用的原理进行简单分析 1 创建AIDL文件 AIDL 文件可以分为两类。 一类是用来定义接口方法,声明要暴露哪些接口给客户端调用&#…

shell常用命令

一、Shell概述 shell是一个命令行解释器,它接受应用程序/用户命令,然后调用操作系统内核。 二、Shell解释器 (1)Linux提供的Shell解析器有: [roothadoop101 ~]$ cat /etc/shells /bin/sh /bin/bash /sbin/nologin …

Go的数据结构-数组,字符串,切片底层

字符串本质是一个结构体,str指向底层bye数组,len是bye数组的长度 通过反射包查看 切片就是对数组的引用 创建方式

一个高效的柴油发电机,都需要做什么准备?

柴油发电机的可靠运行对于维持生产流程和设施正常运转至关重要。为了实现这一目标,有效的监控系统变得不可或缺。 通过柴油发电机监控实时监测系统、远程监控技术以及数据分析,能够实现对发电机性能的全面把握,并在出现潜在问题之前采取预防措…

代码随想录算法训练营Day46 | 139.单词拆分 | 多重背包 | 背包问题总结

文章目录 139.单词拆分多重背包背包问题总结初始化遍历顺序 139.单词拆分 题目链接 | 理论基础 乍一看是回溯问题,和分割回文子串很像,不过本题使用回溯解决会超时(有些极端 case 过不了),而且这样只需要求解 True/F…

全球选手逐鹿清华!首届AI药物研发算法大赛完美收官

8月26日,首届全球AI药物研发算法大赛决赛答辩暨颁奖典礼,在清华大学生物医学馆举行。来自微软研究院、中国科学院上海药物研究所、上海交通大学等单位的十五支团队,从全球878支团队中脱颖而出,进入了决赛答辩环节。 产教融合&…

演讲与口才艺术教案

演讲与口才艺术教案 第一部分:介绍演讲与口才艺术的重要性 演讲与口才艺术是一种重要的沟通技巧,对于个人和职业发展都具有重要的影响。一个优秀的演讲者和具备良好口才的人,能够有效地表达自己的观点、激发他人的兴趣,并影响他…

React 18 在组件间共享状态

参考文章 在组件间共享状态 有时候,希望两个组件的状态始终同步更改。要实现这一点,可以将相关 state 从这两个组件上移除,并把 state 放到它们的公共父级,再通过 props 将 state 传递给这两个组件。这被称为“状态提升”&#…

记一次坑爹的ARouter::There is no route match the path

接入阿里的ARouter框架;实现最简单的页面跳转;一直失败,报找不到匹配的路径;百度各种基本都说配置有问题;我一一对应,配置怎么看看不出问题来; 我的架构是 接入的代码怎么看都没问题&#xff1…

高并发幂等计数器的设计与实现

🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…

react css 污染解决方法

上代码 .m-nav-bar {background: #171a21;.content {height: 104px;margin: 0px auto;} }import React from "react"; import styles from ./css.module.scssexport default class NavBar extends React.Component<any, any> {constructor (props: any) {supe…

Linux常用命令——dd命令

在线Linux命令查询工具 dd 复制文件并对原文件的内容进行转换和格式化处理 补充说明 dd命令用于复制文件并对原文件的内容进行转换和格式化处理。dd命令功能很强大的&#xff0c;对于一些比较底层的问题&#xff0c;使用dd命令往往可以得到出人意料的效果。用的比较多的还是…

[ZenTao]源码阅读:加载自定义任务类型

www/index.php config/config.php framework/base/router.class.php tmp/model/common.php module/common/model.php framework/router.class.php

《动手学深度学习》-55循环神经网络

沐神版《动手学深度学习》学习笔记&#xff0c;记录学习过程&#xff0c;详细的内容请大家购买书籍查阅。 b站视频链接 开源教程链接 循环神经网络 潜变量自回归模型&#xff1a; 循环神经网络结构&#xff1a; 简单来说循环神经网络RNN就是在MLP中加了一项&#xff0c;使它可…