STM32 中断详解,适合初级学员

2022-05-27     大方老师单片机

原标题:STM32 中断详解,适合初级学员

STM32中断详解适合初级学员

中断,在单片机中占有非常重要的地位。代码默认地从上向下执行,遇到条件或者其他语句,会按照指定的地方跳转。而在单片机执行代码的过程中,难免会有一些突发的情况需要处理,这样就会打断当前的代码,待处理完突发情况之后,程序会回到被打断的地方继续执行。

1 EXTI控制器

外部中/事件控制(EXTI)管理了控制器 23个中/事件线。每个中/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测EXTI可以实现对每个中/事件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性。

外部信号进入经1的边沿检测电路,检测是否符(23的上升沿和下降沿选择寄存器决),产生信号,然后4软件中断事件寄存器或值,(在这里也就说可以写入软件中断事件寄存器模拟中断和事件),之后产生信号一分为二,5中断屏蔽寄存器7事件屏蔽寄存器,如果中断和事件都没有屏蔽,首先会产生事件,进入脉冲发生器。其次,会进6挂起寄存器,然后进NVIC

注意:

1、上面说,我们可以使用寄存4软件模拟中断事件寄存器模式符合条件的信号进入,为什么不能6寄存器呢?因为

寄存器是可读可清除的寄存器,通过1清除。0无效。所以不能使用

2、关于挂起寄存器,挂起就是,证明有了中断,会在触发中断。但是不会硬件清除。

只能软件清除,或者修改边沿极性的时候清除。如下

EXTI吧,

EXTI控制器的主要特:

·每个中/事件线上都具有独立的触发和屏蔽

·每个中断线都具有专用的状态位

·支持多23个软件事/中断请求

·检测脉冲宽度低APB2时钟宽度的外部信号

下图ST207的框架图

下图为翻译版

从图中看出和外部中断有关的寄存器有:上升沿触发选择、下降沿触发选择、软件中断事件寄存器、中断屏蔽寄存器、挂起请求寄存器、事件屏蔽寄存器NVIC中断控制寄存器等。此外就是对输入线的理解了。

另外七 EXTI线连接方式如下

也就是说对于一个外部中断线可以和多GPIO相连,当你要使用哪一IO的时候只要SYSCFG_EXTICR对应的位设置就好了,在中断屏蔽寄存器或事件屏蔽寄存器对应位可以设置使用哪一个中断线

ST的使SYSCFG_EXTICR来配置GD的采AFIO寄存器(GPIO寄存器中)

EXTI是外部中断吧,上面的主要是针对的22条中断线的说明,我们还知道还是有很多中断的,比如定时器中断,串口中断等等,他们不属于22条中断线。

我们可以在中断向量表中看到

其他的中断配置都在各个模块的寄存器中了

2 NVIC控制器

在上面EXTI寄存器都设置好后就可以设NVIC了,关NVIC的芯片编程手册上描述较少,但是说了

所以我们就参考一M3手册吧

AIRCR寄存器,其810位为优先级分组

我们在代码中使用的库函数是

voidNVIC_PRIGroup_Enable(uint32_tNVIC_PRIGroup){

/*Set the priority grouping value */

SCB->AIRCR=AIRCR_VECTKEY_MASK|NVIC_PRIGroup;}

其中我们查到

1SCB->AIRCR在库函数的地址0XE000ED0C,不懂的如何查询的,请自行百度

2、查SCB的结构体定义

我们看SCBSystemControl Block的简写

下面我们说一下分组的取值

misc.c中有

*==========================================================================================================================

*NVIC_PriorityGroup|NVIC_IRQChannelPreemptionPriority|NVIC_IRQChannelSubPriority|Description

*==========================================================================================================================

*NVIC_PriorityGroup_0|0|0-15|0bitsforpre-emptionpriority

*|||4bitsforsubpriority

*--------------------------------------------------------------------------------------------------------------------------

*NVIC_PriorityGroup_1|0-1|0-7|1bitsforpre-emptionpriority

*|||3bitsforsubpriority

*--------------------------------------------------------------------------------------------------------------------------

*NVIC_PriorityGroup_2|0-3|0-3|2bitsforpre-emptionpriority

*|||2bitsforsubpriority

*--------------------------------------------------------------------------------------------------------------------------

*NVIC_PriorityGroup_3|0-7|0-1|3bitsforpre-emptionpriority

*|||1bitsforsubpriority

*--------------------------------------------------------------------------------------------------------------------------

*NVIC_PriorityGroup_4|0-15|0|4bitsforpre-emptionpriority

*|||0bitsforsubpriority

*==========================================================================================================================

抢占优先&响应优先级区别

.高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。

.抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。

.抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。

.如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行。

例子:

假定设置中断优先级组2,然后设置

3(RTC)的抢占优先级2,响应优先级1

6(外部中0)的抢占优先级3,响应优先级0

7(外部中1)的抢占优先级2,响应优先级0

那么3个中断的优先级顺序为:中7>3>6

表现在代码中

NVIC_InitParaNVIC_InitStructure;NVIC_InitStructure.NVIC_IRQ=IRQn;NVIC_InitStructure.NVIC_IRQPreemptPriority=pri;NVIC_InitStructure.NVIC_IRQSubPriority=pri1;NVIC_InitStructure.NVIC_IRQEnable=ENABLE;NVIC_Init(&NVIC_InitStructure);

0,那pri的取值范0~0pri1的取值范0~16

2,那pri的取值范0~4pri1的取值范0~4

4,那pri的取值范0~16pri1的取值范0~0

下面我们讲解一NVIC寄存器

__IO uint8_t IP[240]; //中断优先级控制的寄存器组

__IO uint32_t ISER[8]; //中断使能寄存器组

__IO uint32_t ICER[8]; //中断失能寄存器组

__IO uint32_t ISPR[8]; //中断挂起寄存器组

__IO uint32_t ICPR[8]; //中断解挂寄存器组

__IO uint32_t IABR[8]; //中断激活标志位寄存器组

中断优先级控制的寄存器组IP[240]

全称是InterruptPriority Registers

2408位寄存器,每个中断使用一个寄存器来确定优先级。

比如STM32F10x系列一60个可屏蔽中断,使IP[59]~IP[0]

IP寄存器的4位用来设置抢占和响应优先级(根据分组),4位没有用到。

voidNVIC_Init(NVIC_InitTypeDef*NVIC_InitStruct);

中断使能寄存器组ISER[8]

作用:用来使能中断

32位寄存器,每个位控制一个中断的使能STM32F10x60个可屏蔽中断,所以只使用了其中ISER[0]ISER[1]

ISER[0]bit0~bit31分别对应中0~31ISER[1]bit0~27对应中32~59

voidNVIC_Init(NVIC_InitTypeDef*NVIC_InitStruct);

中断失能寄存器组ICER[8]

作用:用来失能中断

32位寄存器,每个位控制一个中断的失能STM32F10x60个可屏蔽中断,所以只使用了其中ICER[0]ICER[1]

ICER[0]bit0~bit31分别对应中0~31ICER[1]bit0~27对应中32~59

配置方法ISER一样。

voidNVIC_Init(NVIC_InitTypeDef*NVIC_InitStruct);

中断挂起控制寄存器组ISPR[8]

作用:用来挂起中断

中断解挂控制寄存器组ICPR[8]

作用:用来解挂中断

static__INLINEvoidNVIC_SetPendingIRQ(IRQn_TypeIRQn)static__INLINEuint32_tNVIC_GetPendingIRQ(IRQn_TypeIRQn)static__INLINEvoidNVIC_ClearPendingIRQ(IRQn_TypeIRQn);

中断激活标志位寄存器组IABR[8]

作用:只读,通过它可以知道当前在执行的中断是哪一个

如果对应位1,说明该中断正在执行。

static__INLINEuint32_tNVIC_GetActive(IRQn_TypeIRQn)

3 code

一定要使能系统时钟

因为配GPIO和中断线的映射关系需SYSCFG

SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource11);

只要用到外部中断,就一定要打SYSCFG时钟

开源代码地址:

【文章福利】:小编整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!~点击绿色通讯软件搜airuimcu加入。

文章来源: https://twgreatdaily.com/zh-hans/52a565aa211495a58bb0d91e894ed775.html