8.基于Cortex-M4内核的STM32F40x中断分析

news2024/10/5 14:14:57

通用中断知识铺垫1:

        完整的CM4有256个可编程中断(16个内核中断和240个外部中断),而stm32f40x共有92个中断(10内+82可编程),意思是说STM32F40X这个单片机没有完全释放CM4内核的资源。

        CM4内核的中断是由NVIC来控制的,就像是GIC这样的东西~它一共有几个寄存器用来管理这256个中断的各种行为,包括:

中断使能寄存器(ISER[8],这是一个32位数组,共8个。32*8个位控制着256个中断)

失能寄存器(ICER[8],看名字就知道了,但是很神奇哈,为啥芯片不设计成写1开写0关)

挂起寄存器(ISPR[8],因为中断可以被更高级的中断打断,这个是用来暂时挂起被打断的中断)

清除挂起寄存器(ICPR[8],这两个估计不用我们操心,单片机内部机制可能已经实现了)

活跃位寄存器(IABR[8],这个是用来显示,那些中断正在执行)

优先级寄存器(IP[240],是个8位寄存器,是配置240个可编程中断优先级的寄存器,每8bit只用到高4位,而这高四位有n位是设置抢占优先级的,有m位是设置设置响应优先级(也叫子优先级),m+n = 4)

        上面这个可能还需要再解释一下,先看一下分组寄存器(SCB->AIRCR 寄存器的 bit10~8 )

        例如,如果中断分组设为3,即 抢:响 = 3:1,也就是说任意一个中断的抢占优先级可以设为0~7(即2^3-1),响应优先级可以设为0~1。数字越小,优先级越高。那么什么是抢占什么是响应优先级呢?

        抢占优先级就是高抢断的中断任务发生时,能打断正在执行的低抢断的中断。而响应优先级就不行了,如果两个任务的抢占优先级一样,其中一个响应优先级比另外一个高,也不能打断,只能乖乖排队。响应优先级高有一个优点就是如果两个同抢不同响的中断同时在排队(等一个比它们抢占优先级高的中断任务完成),那么响应优先级高的会排在前面先执行。

        现在应该能够理解分组、抢占、响应这三个概念了,其实中断相关的编程就是这样,核心三要素1.开关2.分组3.优先级,这样配置完就能写中断服务函数了。

通用中断代码分析:

        领会了三要素,我们再来看正点原子的这段代码就很清楚了:

//设置NVIC 
//NVIC_PreemptionPriority:抢占优先级
//NVIC_SubPriority       :响应优先级
//NVIC_Channel           :中断编号
//NVIC_Group             :中断分组 0~4
  
void MY_NVIC_Init(u8 NVIC_PreemptionPriority抢占优先级,u8 NVIC_SubPriority响应优先级,u8 NVIC_Channel中断号,u8 NVIC_Group分组)	 
{ 
	u32 temp;	  
	MY_NVIC_PriorityGroupConfig(NVIC_Group);//设置分组
	temp=NVIC_PreemptionPriority<<(4-NVIC_Group);	  
	temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
	temp&=0xf;								//取低四位
	NVIC->ISER[NVIC_Channel/32]|=1<<NVIC_Channel%32;//使能中断位(要清除的话,设置ICER对应位为1即可)
	NVIC->IP[NVIC_Channel]|=temp<<4;				//设置响应优先级和抢断优先级 
} 

        其中MY_NVIC_PriorityGroupConfig(NVIC_Group);函数就不贴出来了,里面其实就是给分组寄存器幅值(SCB->AIRCR 寄存器的 bit10~8)。

        下面NVIC->ISER是根据传入的中断号打开中断(中断号其实就是一个宏定义整数,表明是哪个中断而已,例如MY_NVIC_Init(3,2,EXTI2_IRQn,2)和MY_NVIC_Init(3,3,USART1_IRQn,2),里面的EXTI2_IRQn和USART1_IRQn就是中断号,用于表面要打开的是哪个中断)NVIC->IP则是设置两种优先级~

        值得一提的是,中断分组在一个程序里,要设置一致,不要说串口中断分组为2,外部中断又分组为3,这样是不行滴,这是代码混乱的体现也是没搞明白原理的体现,差异在于优先级,而不在于分组。

        上面是所有中断都要做的操作,使能、分组、设优先级,外部中断属于上面但是要实现外部中断还有一些步骤!且看下面理论铺垫2.

外部中断理论铺垫2:

        外部中断由于是单片机这个芯片之外的事件触发了中断(如某个引脚的由于外部的原因产生了上升沿/下降沿,RTC相关事件,以太网相关事件。说起来RTC,以太网等事件本质也是电平变化的组合,总之都是外部引起的就是了),而很显然,定时器中断,串口中断这类的属于单片机这个芯片内部产生的中断,则无需后面这些额外的操作了。

        stm32f4xx的外部中断,由NVIC+EXTI一起管理,一共23个中断号:

0~15号是负责GPIO的,GPIO这个有意思,它是举个例子就很明白了,PA_1,PB_1,PC_1等IO引脚是1的,共用中断号1,PA_0,PB_0,PC_0等IO引脚是0的,共用中断号0。但是的但是,一共只有7个外中断服务函数,它们的名字分别是:EXTI0_IRQHandler,EXTI1_IRQHandler,EXTI2_IRQHandler,EXTI3_IRQHandler,EXTI4_IRQHandler,EXTI9_5_IRQHandler,EXTI15_10_IRQHandler,大家应该看明白了,凡是引脚是0,1,2,3,4的,对应前5个中断服务函数,凡是引脚是5,6,7,8,9的,对应EXTI9_5_IRQHandler,凡是引脚是10,11,12,13,14,15的,对应EXTI15_10_IRQHandler,这叫一个错综复杂,所以在中断函数里我们要额外判断具体是哪个GPIO组的IO触发了中断。值得一题的是,虽然是共用,但是一根线一次只能连接到一个IO上,所以说一个程序中如果用了PA_0作为外部中断引脚,就表示它占用了0号线,如果再用将PB_0或者PC_0之类GPIO的开启外部中断,那程序就乱套了。再再值得一提的是,使用hal库开发就不会有这个问题,因为hal库的中断处理都是放回调函数来搞的,和硬件上的中断设计可以说关系不大,所以也没有这个限制,如果不是为了通用地学习单片机,还是用hal库开发st的单片机香。

16~22号是负责RTC,以太之类的,它们有各自的中断号,也有各自的中断服务函数

NVIC我们都知道了(负责开关/分组/优先级),而EXTI也需要学习然后总结一下:

它有以下寄存器:

中断屏蔽寄存器(IMR):给哪个中断号勾上哪个中断就无效了

事件屏蔽寄存器(EMR):给哪个事件勾上哪个事件就不触发中断了(很别扭啊,直接设计成哪种事件能够触发不就得了,还搞个屏蔽。。。这个是和RTC,以太等外部中断有关的,和IO上升沿下降沿触发没有关系)

上升沿寄存器(RTSR):给外部中断选择触发边沿咯

下降沿寄存器(FTSR):同上

挂起寄存器(PR): 这个寄存器是指示作用的,有外部中断执行就会置1而且中断服务函数结束不会自动清零,所以~在外部中断完事后要手动清零。

除了以上寄存器,外部中断还和SYSCFG->EXTICR寄存器有关(留意要使能SYSCFG时钟),这个寄存器就是将GPIO各个组的引脚和EXTI的中断号关联起来,就如我们上面所说的PA_0对应外部中断号EXTI0,PB_0也对应外部中断号EXTI0.如下图:

其他几个EXTICR类似,不用想的太复杂记住它的作用是将GPIO各个组的引脚和EXTI的中断号关联起来即可

外部中断代码分析:

好好好,终于进入了轻松愉悦的代码环节:

//外部中断配置函数
//只针对GPIOA~I;不包括PVD,RTC,USB_OTG,USB_HS,以太网唤醒等
	    
void Ex_NVIC_Config(u8 GPIOx哪组GPIO,u8 BITxGPIO引脚,u8 TRIM触发方式) 
{ 
	u8 EXTOFFSET=(BITx%4)*4;  
	RCC->APB2ENR|=1<<14;  						//使能SYSCFG时钟  
	SYSCFG->EXTICR[BITx/4]&=~(0x000F<<EXTOFFSET);//清除原来设置!!!
	SYSCFG->EXTICR[BITx/4]|=GPIOx<<EXTOFFSET;	//EXTI.BITx映射到GPIOx.BITx 
	//自动设置
	EXTI->IMR|=1<<BITx;					//开启line BITx上的中断(如果要禁止中断,则反操作即可)
	if(TRIM&0x01)EXTI->FTSR|=1<<BITx;	//line BITx上事件下降沿触发
	if(TRIM&0x02)EXTI->RTSR|=1<<BITx;	//line BITx上事件上升降沿触发
} 

很好理解,关联GPIO引脚和外部中断号,设置中断触发方式,调用方式是:

Ex_NVIC_Config(GPIO_E,4,FTIR); 		//PE_4,下降沿触发 
Ex_NVIC_Config(GPIO_A,0,RTIR); 	 	//PA_0,上升沿触发 

下面补一下外部中断的中断服务函数,因为里面有个小知识点(清楚中断标识位)

例如外部中断号EXTI4的服务函数是这样的:中断结束时要清除

//外部中断4服务程序
void EXTI4_IRQHandler(void)
{
	delay_ms(10);	//消抖
	if(KEY0==0)	 
	{		
		LED0=!LED0;	
		LED1=!LED1;		
	}		 
	EXTI->PR=1<<4;  //清除LINE4上的中断标志位  
}

再例如外部中断号6的服务函数:是EXTI9_5_IRQHandler,与外部中断号5,7,8,9共用,所以用完后也要清除(假如这里是外部中断号6触发的)

//外部中断5~9的服务程序
void EXTI9_5_IRQHandler(void)
{
	 
	EXTI->PR=1<<6;  //清除LINE6上的中断标志位  
}

总结:

普通中断配置NVIC(分组,中断号,优先级):

MY_NVIC_Init(抢占优先级,响应优先级,中断号,分组);

外部中断配置NVIC(分组,中断号,优先级)+EXTI+SYSFG(关联,触发方式):

MY_NVIC_Init(抢占优先级,响应优先级,中断号,分组);
Ex_NVIC_Config(GPIO组,GPIO引脚,触发方式); 

还有一点需要注意的是,中断的配置和IO初始化没有关系哈,例如KEY,LED,它们的IO该上拉上拉该下拉下拉,和中断的配置是分割开的。

完~

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

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

相关文章

赴日IT培训课程 程序员新思路!

先说好&#xff0c;跟国内相比&#xff0c;日本IT并不发达。日本IT是依托着日本传统强势的制造业和政府机关发展的&#xff0c;所以开发的大多数软件也是面向这些的&#xff0c;由于日本人的严谨态度&#xff0c;各种文档的编写层出不穷&#xff0c;不像国内程序员每天没日没夜…

全方位的账号安全管理

如今&#xff0c;特权账户范围广、数量大且极不稳定是当前各行业面临黑客等攻击行为的最大安全隐患。而且&#xff0c;由于特权账户的权限极大&#xff0c;一旦其被攻击者破解&#xff0c;就能完全掌控组织的IT基础设施&#xff0c;从而引发防护控制失效、机密数据泄露、商业诈…

[网络安全]密码字典快速生成——在线网站

目录 1.密码字典在线生成器one点击链接 ​编辑2.密码字典在线生成器two点击链接 3.密码字典在线生成器three点击链接 个人推荐生成器1&#xff0c;因为复制黏贴好用。 1.密码字典在线生成器one点击链接 2.密码字典在线生成器two点击链接 3.密码字典在线生成器three点击链接 看…

Spring Boot学习随笔- 文件上传和下载(在线打开、附件下载、MultipartFile)

学习视频&#xff1a;【编程不良人】2021年SpringBoot最新最全教程 第十二章、文件上传、下载 文件上传 文件上传是指将文件从客户端计算机传输到服务器的过程。 上传思路 前端的上传页面&#xff1a;提交方式必须为post&#xff0c;enctype属性必须为multipart/form-data开发…

Java:获取线程的名字

代码示例&#xff1a; package com.thb;public class Test6 {public static void main(String[] args) {System.out.println(Thread.currentThread().getName());}}运行输出&#xff1a;

【单调栈】LeetCode2030:含特定字母的最小子序列

作者推荐 map|动态规划|单调栈|LeetCode975:奇偶跳 涉及知识点 单调栈 题目 给你一个字符串 s &#xff0c;一个整数 k &#xff0c;一个字母 letter 以及另一个整数 repetition 。 返回 s 中长度为 k 且 字典序最小 的子序列&#xff0c;该子序列同时应满足字母 letter 出…

常见分布的分布列/概率密度、分布函数、期望、方差、特征函数

0-1分布 二项分布 泊松分布 几何分布 均匀分布 正态分布 指数分布 伽马分布 卡方分布

【C语言】自定义类型之联合和枚举

目录 1. 前言2. 联合体2.1 联合体类型的声明2.2 联合体的特点2.3 相同成员的结构体和联合体对比2.4 联合体大小的计算2.4 判断当前机器的大小端 3. 枚举3.1 枚举类型的声明3.2 枚举类型的优点3.3 枚举类型的使用 1. 前言 在之前的博客中介绍了自定义类型中的结构体&#xff0c;…

【SQLite】SQLite数据库简单使用与Navicat安装-加密

Sqlite为免安装数据库&#xff0c;安装步骤总结&#xff1a; 官网下载Sqlit数据库&#xff0c;官网下载地址:https://www.sqlite.org/download.html 下载: sqlite-dll-win64-x64-3390400.zip或者32位sqlite-dll-win32 sqlite-tools-win-x64-3440200.zip或者32位sqlite-tools-wi…

【✅Java中有了基本类型为什么还需要包装类?】

✅Java中有了基本类型为什么还需要包装类&#xff1f; ✅Java中有了基本类型为什么还需要包装类✅Java的8中基本数据类型 ✅知识拓展✅基本类型和包装类型的区别✅如何理解自动拆装箱&#xff1f;✅拆箱与装箱✅自动拆装箱✅自动拆装箱原理 ✅哪些地方会自动拆装箱&#xff1f;…

10-高并发-应用级缓存

缓存简介 缓存&#xff0c;是让数据更接近于使用者&#xff0c;目的是让访问速度更快。 工作机制是先从缓存中读取数据&#xff0c;如果没有&#xff0c;再从慢速设备上读取实际数据并同步到缓存。 那些经常读取的数据、频繁访问的数据、热点数据、I/O瓶颈数据、计算昂贵的数…

算法基础之约数个数

约数个数 核心思想&#xff1a; 用哈希表存每个质因数的指数 然后套公式 #include <iostream>#include <algorithm>#include <unordered_map>#include <vector>using namespace std;const int N 110 , mod 1e9 7;typedef long long LL; //long l…

移动安全APP--Frida+模拟器,模拟器+burp联动

最近测APP被通报了&#xff0c;问题点测得比较深&#xff0c;涉及到frida和burp抓包&#xff0c;一般在公司可能会有网络的限制&#xff0c;手机没办法抓包&#xff0c;我就直接在模拟器上试了&#xff0c;就在这记录一下安装过程。 目录 一、Frida安装 二、burp与逍遥模拟器…

MySQL是如何保证数据不丢失的?

文章目录 前言Buffer Pool 和 DML 的关系DML操作流程加载数据页更新记录 数据持久化方案合适的时机刷盘双写机制日志先行机制日志刷盘机制Redo Log 恢复数据 总结 前言 上篇文章《InnoDB在SQL查询中的关键功能和优化策略》对InnoDB的查询操作和优化事项进行了说明。但是&#…

STM32F4的DHT11初始化与实例分析

STM32—— DHT11 本文主要涉及STM32F4 的DHT11的使用以及相关时序的介绍&#xff0c;最后有工程下载地址。 文章目录 STM32—— DHT11一、 DHT11的介绍1.1 DHT11的经典电路 二、DHT11的通信2.1 DHT11的传输数据格式2.2 DHT11 通信分步解析 三、 DHT11 代码3.1 引脚图3.2 电路图…

污水处理厂可视化:让环保与科技共舞

随着科技的飞速发展&#xff0c;我们的生活环境变得越来越美好。然而&#xff0c;随着城市化进程的加快&#xff0c;污水处理问题也日益凸显。如何有效、高效地处理污水&#xff0c;成为了一个亟待解决的问题。而“污水处理厂可视化”技术的出现&#xff0c;为这个问题提供了一…

隐藏通信隧道技术——防御DNS隧道攻击

隐藏通信隧道技术——防御DNS隧道攻击 DNS协议 ​ DNS协议是一种请求/应答协议&#xff0c;也是一种可用于应用层的隧道技术。虽然激增的DNS流量可能会被发现&#xff0c;但是基于传统Socket隧道已经濒临淘汰及TCP、UDP通信大量被防御系统拦截的状况&#xff0c;DNS、ICMP、H…

第二十二章 : Spring Boot 集成定时任务(一)

第二十二章 &#xff1a; Spring Boot 集成定时任务&#xff08;一&#xff09; 前言 本章知识点&#xff1a; 介绍使用Spring Boot内置的Scheduled注解来实现定时任务-单线程和多线程&#xff1b;以及介绍Quartz定时任务调度框架&#xff1a;简单定时调度器&#xff08;Simp…

QT中网络编程之发送Http协议的Get和Post请求

文章目录 HTTP协议GET请求POST请求QT中对HTTP协议的处理1.QNetworkAccessManager2.QNetworkRequest3.QNetworkReply QT实现GET请求和POST请求Get请求步骤Post请求步骤 测试结果 使用QT的开发产品最终作为一个客户端来使用&#xff0c;很大的一个功能就是要和后端服务器进行交互…

使用代理服务器和Beautiful Soup爬取亚马逊

概述 Beautiful Soup 是一个用于解析 HTML 和 XML 文档的 Python 库&#xff0c;它能够从网页中提取数据&#xff0c;并提供了一些简单的方法来浏览文档树、搜索特定元素以及修改文档的内容。在本文中&#xff0c;我们将介绍如何使用代理服务器和Beautiful Soup库来爬取亚马逊…