STM32中EXTI(外部中断)和NVIC(嵌套向量中断)的关系
- 格式:docx
- 大小:9.65 KB
- 文档页数:2
STM32F4——NVIC中断优先级及外部中断NVIC 中断优先级一、简介:CM4 内核可以支持256 个中断,包括16 个内核中断和240 个外部中断,256 级的可编程中断设置。
对于STM32F4 没有用到CM4 内核的所有东西,只是用到了一部分,对于STM32F40 和41 系列共有92 个中断,其中有10 个内核中断和82 个可屏蔽中断,常用的为82 个可屏蔽中断。
二、相关寄存器:ISER[8]中断使能寄存器组,用来使能中断,每一位控制一个中断,由于上面已经说明了控制82 个可屏蔽的中断,因此利用ISER[0~2]这三个32 位寄存器就够了。
一下的几个寄存器同理。
ICER[8]中断除能寄存器组,用来消除中断。
ISPR[8]中断挂起控制寄存器组,用来挂起中断。
ICPR[8]中断解挂控制寄存器组,用来解除挂起。
IABR[8]中断激活标志寄存器组,对应位如果为1 则表示中断正在被执行。
IP[240]中断优先级控制寄存器组,它是用来设置中断优先级的。
我们只用到了IP[0]~IP[81],每个寄存器只用到了高4 位,这4 位又用来设置抢占优先级和响应优先级(有关抢占优先级和响应优先级后面会介绍到),而对于抢占优先级和响应优先级各占多少位则由AIRCR 寄存器控制,相关设置如下图所示:关于抢占优先级和响应优先级的理解,可以将它们简单的理解为两个级别,抢占优先级的级别要比响应优先级的级别高,简单的理解为一个为长辈的一个为晚辈的,晚辈要让着长辈,因此抢占优先级的中断可以打断响应优先级的中断,而同级别的中断就得有个先来后到的了,先来的先执行。
三、相关库函数应用1、中断优先级分组函数:voidNVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup),用来设置设置中断优。
STM32的EXTI原理及应用一、简介外部中断(External Interrupt,简称EXTI)是STM32系列单片机的一项重要功能。
通过EXTI功能,我们可以将外部引脚与中断事件关联起来,当外部引脚状态发生变化时,单片机会产生中断请求。
在本文档中,我们将详细介绍STM32的EXTI原理及其应用。
二、EXTI原理EXTI是由NVIC(Nested Vectored Interrupt Controller)配合GPIO(General Purpose Input/Output)模块实现的。
当外部引脚的触发事件发生时,GPIO模块会将中断请求发送给NVIC,NVIC将根据中断优先级决定是否响应该中断请求。
若中断被响应,将执行相应的中断服务函数。
三、EXTI的配置步骤以下是配置STM32的EXTI功能的一般步骤:1.配置GPIO引脚模式为输入模式,如GPIO_InitTypeDef.GPIO_Mode= GPIO_Mode_IN;。
2.配置GPIO引脚的中断触发方式,如GPIO_InitTypeDef.GPIO_Mode= GPIO_Mode_IT_Rising;表示上升沿触发。
3.配置中断向量表,具体步骤取决于开发环境和使用的STM32系列型号。
4.配置EXTI中断线,如EXTI_InitTypeDef.EXTI_Line = EXTI_Line0;表示连接到外部引脚0。
5.配置EXTI触发方式,如EXTI_InitTypeDef.EXTI_Trigger =EXTI_Trigger_Rising;表示上升沿触发。
6.配置EXTI中断优先级,如NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;。
7.使能EXTI中断,如NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;。
8.在中断服务函数中处理中断事件。
一、本章大纲一、嵌套向量中断控制器—NVICCM3内核搭载了一个异常响应系统,通过NVIC(嵌套向量中断控制器)来管理和配置。
NVIC是一个总的控制器,相当于51的IE,不论是来自CM3内部的异常还是来自外设的中断,都进入该控制器进行处理和逻辑控制。
并且NVIC还通过优先级系统,来控制中断的嵌套。
1.中断优先级①优先级的数值越小,则优先级越高。
②NVIC支持中断嵌套,使得高优先级异常会抢占低优先级异常。
③有3个系统异常:复位、NMI(不可屏蔽中断)以及硬件失效(Hard fault),它们有固定的优先级,并且它们的优先级号是负数,从而高于所有其他异常。
原则上,NVIC支持3个固定的高优先级和多达256级的可设置优先级,用一个字节的8个比特位来表示。
STM32F107采用最高有效位对齐,在设计时裁掉表达优先级的4个低端有效位,所以只支持16级优先级。
2.抢占优先级与从优先级NVIC中有一个寄存器是“应用程序中断及复位控制寄存器”,它里面有一个位段名为“优先级组”。
它把优先级分为2个位段:MSB所在的位段对应抢占优先级,抢占优先级决定了抢占行为。
LSB所在的位段对应从优先级,从优先级则处理“内务”。
在STM32F107中,只使用4个位来表达优先级([7:4]),如果抢占优先级组从比特5处分,则得到4级抢占优先级,且在每个抢占优先级的内部有4个从优先级(00 01 10 11)。
3.中断输入与悬起当中断输入脚被置为有效后,该中断就被“悬起”。
所谓“悬起”,也就是等待、就绪的意思。
即使后来中断源撤消了中断请求,已经被标记成悬起的中断也被记录下来。
当某中断的服务程序开始执行时,就称此中断进入了“活跃”状态,并且其悬起位会被硬件自动清除。
在一个中断活跃后,直到其服务例程执行完毕,并且返回后,才能对该中断的新请求予以响应。
当NVIC响应一个中断时,会自动完成以下三项工作,以便安全、准确地跳转到相应的中断服务程序:入栈:把8个寄存器的值压入栈。
野⽕F1开发板STM32案例-外部中断(按键)使⽤野⽕F1开发板STM32案例-外部中断(按键)使⽤硬件平台野⽕STM32F103ZET6 霸道V2开发板正点原⼦F1系列开发板软件平台Keil MDK 5.31串⼝调试助⼿Gitee .中断相关概念中断配置寄存器# 配置中断时,使⽤ISER、 ICER 和 IP 寄存器,## ISER 是中断使能寄存器## ICER 是中断清除寄存器## IP 是中断优先级寄存器中断优先级1. 数值越⼩,优先级越⾼2. STM32F103 中只使⽤4位,⾼4位有效。
3. ⽤于表达优先级的⾼ 4 位⼜被分组成抢占式优先级和响应优先级,称为“亚优先级”或“副优先级”4. 每个中断源都需要被指定这两种优先级。
中断配置步骤1.使能外设中断6. 设置中断优先级分组初始化 NVIC_InitTypeDef 结构体,设置抢占优先级和响应优先级,使能中断请求。
typedef struct{uint8_t NVIC_IRQChannel; //中断源uint8_t NVIC_IRQChannelPreemptionPriority; //抢占优先级uint8_t NVIC_IRQChannelSubPriority; //响应优先级FunctionalState NVIC_IRQChannelCmd; //中断使能或失能} NVIC_InitTypeDef;NVIC_IRQChannel 中断源:中断源的设置,不同的外设中断,中断源不⼀样NVIC_IRQChannelPreemptionPriority //抢占优先级NVIC_IRQChannelSubPriority //响应优先级NVIC_IRQChannelCmd //中断使能或失能:使能配置为 ENABLE,失能配置为 DISABLE。
NVIC_IRQChannel //中断源/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt *//****** STM32 specific Interrupt Numbers *********************************************************/WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */TAMPER_IRQn = 2, /*!< Tamper Interrupt */RTC_IRQn = 3, /*!< RTC global Interrupt */FLASH_IRQn = 4, /*!< FLASH global Interrupt */RCC_IRQn = 5, /*!< RCC global Interrupt */EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */DMA1_Channel1_IRQn = 11, /*!< DMA1 Channel 1 global Interrupt */DMA1_Channel2_IRQn = 12, /*!< DMA1 Channel 2 global Interrupt */DMA1_Channel3_IRQn = 13, /*!< DMA1 Channel 3 global Interrupt */DMA1_Channel4_IRQn = 14, /*!< DMA1 Channel 4 global Interrupt */DMA1_Channel5_IRQn = 15, /*!< DMA1 Channel 5 global Interrupt */DMA1_Channel6_IRQn = 16, /*!< DMA1 Channel 6 global Interrupt */DMA1_Channel7_IRQn = 17, /*!< DMA1 Channel 7 global Interrupt */STM32F103 中断向量表EXTI外部中断1. STM32F10x 外部中断/事件控制器(EXTI)包含多达 20 个⽤于产⽣事件/中断请求的边沿检测器。
STM32 NVIC嵌套向量中断控制器函数分析中断管理函数CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。
但STM32并没有使用CM3内核的全部东西,而是只用了它的一部分。
STM32有76个中断,包括16个内核中断和60个可屏蔽中断,具有16级可编程的中断优先级。
而我们常用的就是这60个可屏蔽中断,所以我们就只针对这60个可屏蔽中断进行介绍。
在MDK内,与NVIC相关的寄存器,MDK为其定义了如下的结构体:typedef struct{vu32 ISER[2];u32 RESERVED0[30];vu32 ICER[2];u32 RSERVED1[30];vu32 ISPR[2];u32 RESERVED2[30];vu32 ICPR[2];u32 RESERVED3[30];vu32 IABR[2];u32 RESERVED4[62];vu32 IPR[15];} NVIC_TypeDef;ISER[2]:Interrupt set enable registers中断使能寄存器组ICER[2]:interrupt clear enable registers 中断除能寄存器组ISPR[2]:interrupt set pending registers 中断挂起寄存器组ICPR[2]: interrupt clear pending registers 中断解挂寄存器组IABR[2]:interrupt active bit registers 中断激活标志寄存器组主要分析IPR[15]:interrupt priority registers 中断优先级控制寄存器组使用函数实现中断分组: 可选分组0--4MY_NVIC_PriorityGroupConfig(u8 NVIC_Group) {u32 temp,temp1;//设置中转变量temp1=(~NVIC_Group)&0x07; //取后3位temp1;AIRCR; //读取先前设置temp&=0x0000F8FF; //清空先前设置temp|=0x05FA0000; //插入密钥temp|=temp1; //分组设置赋值进SCB->;AIRCB=temp; //设置完的值赋值给中断分组寄存器}语句解读:temp1=(~NVIC_Group)&0x07; 由于所以组号取反与111 即得到分组所需寄存器值temp|=0x05FA0000;密钥使用函数实现中断优先级设置:void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group) {u32 temp;u8 IPRADDR=NVIC_Channel/4; //每组只能存4个得到组地址u8 IPROFFSET=NVIC_Channel%4; //得到组内偏移地址IPROFFSET=IPROFFSET*8+4; //得到确切地址MY_NVIC_PriorityGroupConfig(NVIC_Group); //设置分组temp=NVIC_Preemptionpriority;>;NVIC_Group); //设置响应优先级temp&=0xf; //取低4位if(NVIC_Channel;ISER[0]|=1;ISER[1]|=1;IPR[IPRADDR ]|=temptemp=NVIC_Preemptionpriority;>;NVIC_Group); //响应优先级在右边,根据响应位多少进行右移temp&=0xf; //得到分组值外部中断配置函数:STM32的EXTI控制器支持19个外部中断/事件请求。
stm32中断嵌套规则
在STM32微控制器中,中断是实现多任务处理和事件驱动程序的关键机制之一。
中断嵌套是指在一个中断服务程序(ISR)执行过程中,另一个中断发生并且
执行相应的ISR。
然而,为了确保中断嵌套的正确执行,需要遵守一些嵌套规则。
首先,在STM32中,不同的中断具有不同的优先级。
中断优先级通过使用相
应的寄存器进行配置,具有较低数值的中断优先级将具有较高的优先级。
这意味着,在一个中断服务程序中,如果发生了比当前正在执行ISR的中断优先级更高的中断,系统将中断当前正在执行的中断并执行较高优先级的中断程序。
其次,如果两个中断具有相同的优先级,则优先级有效性取决于初始的中断请
求时刻的先后顺序。
这称为优先级争夺。
在这种情况下,第一个发生的中断请求将被优先执行,而第二个被挂起,直到第一个中断服务程序执行结束。
此外,在编写中断服务程序时,需要注意中断服务函数(ISF)的执行时间。
较长的中断服务程序将导致较长的响应时间和延迟,从而可能影响系统的实时性。
因此,为了提高系统的实时性和响应能力,应将中断服务程序设计为尽可能短小和高效。
最后,在STM32中,还提供了一种特殊类型的中断服务程序,称为嵌套向量
中断控制器(NVIC)。
NVIC负责管理和控制所有中断请求,并根据其优先级和
嵌套规则决定执行的中断服务程序。
总之,在STM32中,遵循中断嵌套规则非常重要,以确保中断的正确执行和
系统的实时性。
通过正确配置中断优先级、处理争夺情况、优化中断服务程序的执行时间,并合理使用NVIC,可以有效地实现多任务处理和事件驱动的功能。
原]STM32中EXTI(外部中断)和NVIC(嵌套向量中断)的关系[ 2012-4-13 6:38:00 | By: mxh0506 ]2推荐NVIC是Cortex-M3核心的一部分,关于它的资料不在《STM32的技术参考手册》中,应查阅ARM公司的《Cortex-M3技术参考手册》Cortex-M3的向量中断统一由NVIC管理EXTI是ST公司在其STM32产品上扩展的外中断控制。
它负责管理映射到GPIO引脚上的外中断和片内几个集成外设的中断(PVD,RTC alarm,USB wakeup,ethernet wakeup),以及软件中断。
其输出最终被映射到NVIC的相应通道。
因此,配置EXTI中断的过程必然包含对NVIC的配置,例如下面配置EXTI0的过程,就要首先配置EXTI控制器(使能相应的中断线,选择中断/事件模式,触发边沿极性),然后再配置NVIC 控制器(EXTI0映射在NVIC上的通道号,中断优先级,中断屏蔽状态):/* Connect EXTI Line 0 to GPIO Pin PB0 */GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);/* Configure EXTI line 0 */EXTI_InitStructure.EXTI_Line = EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // or RisingEXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);/* Enable this interrupt on corresponding NVIC channel */NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; // EXTI0_IRQn is defined in stm32f10x.hNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);EXTI0_IRQn的值,其实就是EXTI0中断向量在中断向量表中的位置(STM32技术参考手册中断向量表Position栏中的数值)。
stm32中的中断嵌套控制器Stm32中断嵌套控制器总结(参考了STM32自学笔记)NVIC 全称为Nest Vector Interrupt Controller,人们一般称之为“嵌套中断向量控制器”同这个SysTick定时器一样,NVIC属于ARM Cortex –M3内核的内部设备之一,与基于此内核的控制器并无直接联系,就是说任何一款基于ARM Cortex –M3内核的微控制器都有NVIC。
NVIC的作用如其名——是用来管理中断嵌套的,既然提及嵌套一词,先得清楚一下中断的一些概念。
中断响应:当某个中断来临的时候,会将某个中断标志位置位,当CPU查询到响应的中断的时候,就会自动跳转到相应的中断向量表中去,从而执行响应的中断函数。
中断优先级:优先级又分为两种:查询优先级和执行优先级这里可能初学者不太好理解,但是学过51系列单片机的朋友应该不会那样的陌生。
51 单片机中有个中断优先级控制寄存器IP ,可以设某一中断为高优先级中断或者是低优先级的中断,这就是所谓的执行优先级,但是当我们把外部中断0和外部中断1都设为高优先级中断的时候,而这两个中断又同时发生的时候,我们应该执行哪个中断呢,这就取决于中断向量表中中断向量的位置了。
如51单片机中的中断向量表中顺序如下:外部中断0 0x03T0溢出中断0x0b外部中断1 0x13T1溢出中断0x1b串行口中断0x23上表中的顺序,也就是查询优先级了,所以应该是外部中断0先执行了而在STM32中又多出了点名堂:它把执行优先级又分成了先占优先级和次占优先级(1)拥有较高先占优先级的中断可以打断先占优先级较低的中断(类似于前面所说的执行优先级)(2)如先占优先级相同,则看次占优先级谁高,先执行谁。
(3)如先占优先级相同,次占优先级也相同,则执行查询优先级较高的。
(4)无论任何时刻,次占优先级,查询优先级都不会造成中断嵌套,也就是说中断嵌套都是由先占优先级决定的。
stm32库函数学习篇---NVIC与外部中断实现功能:外部中断线0(PA0)与线15(PA15)分别连接到两个按钮,一个按钮用于产生上升沿,另一个用于产生下降沿,两个中断函数里均对PA8口连接的led灯取反,同时PD2连接的led灯随意延时取反指示程序运行。
这次我用了官方提供的例程来构建自己的工程,这样可以省下不少时间,而且减少了出错率,调试起来容易多了。
首先是stm32中断与外部中断的概念。
ARM Coetex-M3内核共支持256个中断,其中16个内部中断,240个外部中断和可编程的256级中断优先级的设置。
STM32目前支持的中断共84个(16个内部+68个外部),还有16级可编程的中断优先级的设置,仅使用中断优先级设置8bit中的高4位。
STM32可支持68个中断通道,已经固定分配给相应的外部设备,每个中断通道都具备自己的中断优先级控制字节PRI_n(8位,但是STM32中只使用4位,高4位有效),每4个通道的8位中断优先级控制字构成一个32位的优先级寄存器。
68个通道的优先级控制字至少构成17个32位的优先级寄存器。
4bit的中断优先级可以分成2部分,从高位看,前面定义的是抢占式优先级,后面是响应优先级。
4bit一共可以分成5组。
第0组:所有4bit用于指定响应优先级;第1组:最高1位用于指定抢占式优先级,后面3位用于指定响应优先级;第2组:最高2位用于指定抢占式优先级,后面2位用于指定响应优先级;第3组:最高3位用于指定抢占式优先级,后面1位用于指定响应优先级;第4组:所有4位用于指定抢占式优先级。
所谓抢占式优先级和响应优先级,他们之间的关系是:具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套。
1、当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。
NVICNested vectored interrupt controller。
嵌套向量中断控制器。
它是STM32 core peripherals 的其中之一,其余为system timer, system control block和memory protect unit。
从NVIC的vector table中看出,NVIC type按照优先级从高到低的顺序,可以分为Reset, NonMaskable Interrupt(NMI), Hard Fault, Memory management fault, Usage Fault, ..., SysTick, Interrupt(IRQ)。
整理表格如下。
由此可见,EXTI是NVIC中的一个成员。
NVIC中,IRQ分为level-sensitive和pulse两种。
前者的中断需要相应外设来取消,因此外设可以控制处理器重复执行相应的ISR;后者由处理器时钟的上升沿同步采集,因此需要外设将中断保持至少一个时钟周期。
对于软硬件控制中断挂起和取消中断信号的条件等,参见<PM0056 Programming manual: STM32F10xxx Cortex-M3 programming manual> 4.3.9 Level-sensitive and pulse interrupts。
寄存器NVIC IRQ的主要寄存器为set enable, clear enable, set pending, clear pending, active bit,每种均有三个元素,分别控制第0~31,32~63,64~67号IRQ;以及设置优先级和软件中断的寄存器。
EXTIEXTI可以检测20个事件或中断,对应关系如下所示。
寄存器EXTI的寄存器主要有:interrupt mask, event mask, rising trigger selection, falling trigger selection, software interrupt event, pending。
STM32之外部中断EXTISTM32中断控制线支持19个外部中断/事件请求,每个中断都有对应状态位和独立的触发与屏蔽设置。
STM32F103的19个外部中断为:线0-15:对应GPIO口的输入中断。
线16:连接到PVD输出(掉电检测,掉电时可立即保存重要数据作用)。
线17:连接RTC闹钟事件。
线18:连接到USB唤醒事件。
每个IO口都可作为外部中断输入口的STM32的IO口远多于16个,而IO口使用的中断线只有16个。
为此,GPIO管脚GPIOx.0~GPIOx.15(X=A,F,G)分别对应中断线0-15.这样每个中断线对应了7个IO口。
如线0对应着GPIOA.0,GPIOB.0,GPIOC.0,GPIOD.0,GPIOE.0,GPIOF.0,GPIOG.0但是每个中断线每次只能连接到1个IO口上。
这样就需要通过相关的配置来决定对应的中断线被配置到哪个GPIO上了。
GPIO和中断线的映射关系如下图:GPIO与中断映射配置通过函数来实现void GPIO_EXTILineConfig (uint8_t GPIO_PortSource,uint8_t GPIO_PinSource)例如:GPIO_EXTILineConfig(GPIO_PortSourceGPIOE , GPIO_PinSource2);即外部中断线2就和GPIOE映射起来了,显然是GPIOE.2与EXTI2中断线连接起来了。
接着需设置中断触发方式:void EXTI_Init (EXTI_InitTypeDef * EXTI_InitStruct)例如:EXTI_InitTypeDef EXTI_InitStructure;EXTI_InitStructure.EXTI_Line=EXTI_Line4;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);以上例子设置了中断线line4的中断为下降沿触发。
STM32外部中断原理与配置STM32-外部中断原理与配置IO⼝外部中断原理概述STM32控制器⽀持的外部中断/事件请求中断线M3M4M7EXTI线0~15:对应外部IO⼝的输⼊中断。
√√√EXTI线16:连接到PVD输出。
√√√EXTI线17:连接到RTC闹钟事件。
√√√EXTI线18:连接到USB OTG FS唤醒事件。
√√√EXTI线19:连接到以太⽹唤醒事件。
√√EXTI线20:连接到USB OTG HS(在FS中配置)唤醒事件√√EXTI线21:连接到RTC⼊侵和时间戳事件。
√√EXTI线22:连接到RTC唤醒事件。
√√EXSTI线23:连接到LPTIM1异步事件√IO⼝外部中断STM32的每个IO都可以作为外部中断输⼊。
每个外部中断线可以独⽴的配置触发⽅式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专⽤的状态位。
STM32供IO使⽤的中断线只有16个,但是STM32F系列的IO⼝多达上百个,STM32F103ZGT6(112),那么中断线怎么跟io⼝对应呢?GPIO和中断线映射关系GPIOx.0映射到EXTI0GPIOx.1映射到EXTI1……GPIOx.14映射到EXTI14GPIOx.15映射到EXTI15对于M4/M7,配置寄存器为SYSCFG_EXTIRx对于M3,配置寄存器为AFIO_EXTICRx如下图所⽰,EXTI0[3:0]有4个位,可以配置16个,所以可以从PA0选择到PI0。
也就是说16个中断线,最多可以处理16*16个外部引脚的中断。
可以在⼿册中找到SYSCFG 外部中断配置寄存器:16个中断线就分配16个中断服务函数?IO⼝外部中断在中断向量表中只分配了7个中断向量,也就是只能使⽤7个中断服务函数。
从表中可以看出,外部中断线5~ 9分配⼀个中断向量,共⽤⼀个服务函数外部中断线10~15分配⼀个中断向量,共⽤⼀个中断服务函数。
中断服务函数列表:EXTI0_IRQHandlerEXTI1_IRQHandlerEXTI2_IRQHandlerEXTI3_IRQHandlerEXTI4_IRQHandlerEXTI9_5_IRQHandlerEXTI15_10_IRQHandlerIO⼝外部中断HAL库配置⽅法外部中断操作使⽤到的函数分布⽂件stm32fxxx_hal_gpio.hstm32fxxx_hal_gpio.c外部中断配置:外部中断的中断线映射配置和触发⽅式都是在GPIO初始化函数中完成:GPIO_InitTypeDef GPIO_Initure;GPIO_Initure.Pin=GPIO_PIN_0; //PA0GPIO_Initure.Mode=GPIO_MODE_IT_RISING; //上升沿触发GPIO_Initure.Pull=GPIO_PULLDOWN;HAL_GPIO_Init(GPIOA,&GPIO_Initure);void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init){uint32_t position;uint32_t ioposition = 0x00;uint32_t iocurrent = 0x00;uint32_t temp = 0x00;/* Check the parameters */assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));assert_param(IS_GPIO_PIN(GPIO_Init->Pin));assert_param(IS_GPIO_MODE(GPIO_Init->Mode));assert_param(IS_GPIO_PULL(GPIO_Init->Pull));/* Configure the port pins */for(position = 0; position < GPIO_NUMBER; position++){/* Get the IO position */ioposition = ((uint32_t)0x01) << position;/* Get the current IO position */iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition;if(iocurrent == ioposition){/*--------------------- GPIO Mode Configuration ------------------------*//* In case of Alternate function mode selection */if((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)){/* Check the Alternate function parameter */assert_param(IS_GPIO_AF(GPIO_Init->Alternate));/* Configure Alternate function mapped with the current IO */temp = GPIOx->AFR[position >> 3];temp &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ;temp |= ((uint32_t)(GPIO_Init->Alternate) << (((uint32_t)position & (uint32_t)0x07) * 4));GPIOx->AFR[position >> 3] = temp;}/* Configure IO Direction mode (Input, Output, Alternate or Analog) */temp = GPIOx->MODER;temp &= ~(GPIO_MODER_MODER0 << (position * 2));temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2));GPIOx->MODER = temp;/* In case of Output or Alternate function mode selection */if((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) {/* Check the Speed parameter */assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));/* Configure the IO Speed */temp = GPIOx->OSPEEDR;temp &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2));temp |= (GPIO_Init->Speed << (position * 2));GPIOx->OSPEEDR = temp;/* Configure the IO Output Type */temp = GPIOx->OTYPER;temp &= ~(GPIO_OTYPER_OT_0 << position) ;temp |= (((GPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4) << position);GPIOx->OTYPER = temp;}/* Activate the Pull-up or Pull down resistor for the current IO */temp = GPIOx->PUPDR;temp &= ~(GPIO_PUPDR_PUPDR0 << (position * 2));temp |= ((GPIO_Init->Pull) << (position * 2));GPIOx->PUPDR = temp;/*--------------------- EXTI Mode Configuration ------------------------*//* Configure the External Interrupt or event for the current IO */if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE){/* Enable SYSCFG Clock */__HAL_RCC_SYSCFG_CLK_ENABLE();temp = SYSCFG->EXTICR[position >> 2];temp &= ~(((uint32_t)0x0F) << (4 * (position & 0x03)));temp |= ((uint32_t)(GPIO_GET_INDEX(GPIOx)) << (4 * (position & 0x03)));SYSCFG->EXTICR[position >> 2] = temp;/* Clear EXTI line configuration */temp = EXTI->IMR;temp &= ~((uint32_t)iocurrent);if((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT){temp |= iocurrent;}EXTI->IMR = temp;temp = EXTI->EMR;temp &= ~((uint32_t)iocurrent);if((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT){temp |= iocurrent;}EXTI->EMR = temp;/* Clear Rising Falling edge configuration */temp = EXTI->RTSR;temp &= ~((uint32_t)iocurrent);if((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE){temp |= iocurrent;}EXTI->RTSR = temp;temp = EXTI->FTSR;temp &= ~((uint32_t)iocurrent);if((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE){temp |= iocurrent;}EXTI->FTSR = temp;}}}}和串⼝中断⼀样,HAL库同样提供了外部中断通⽤处理函数HAL_GPIO_EXTI_IRQHandler,我们在外部中断服务函数中会调⽤该函数处理中断。
STM32 中断与嵌套NVIC 快速入门*//====================================================// STM32 中断与嵌套NVIC 快速入门// netjob 2008-8-1//====================================================STM32中断与嵌套NVIC快速入门我也是靠看这本书才弄懂的:Cortex-M3 权威指南Joseph Yiu 著宋岩译其实很简单。
//CM3 有最多240个中断(通常外部中断写作IRQs),就是软件上说的 IRQ CHANAELx(中断通道号x) 每个中断有自己的可编程的中断优先级【有唯一对应的中断优先级寄存器】.由于CM3支持硬件中断嵌套,所以可以有 256 级的可编程优先级和 256级中断嵌套【书上称:抢占(preempt)优先级】所以大家可以设:IRQ CHANAEL 0 通道 = 2 中断优先级 WWDG 窗口定时器中断IRQ CHANAEL 1 通道 = 0 中断优先级 PVD 联到EXTI的电源电压检测(PVD)中断IRQ CHANAEL 3 通道 = 255 中断优先级 RTC 实时时钟(RTC)全局中断IRQ CHANAEL 6 通道 = 10 中断优先级 EXTI0 EXTI线0中断.....IRQ CHANAEL 239 通道 = (0<x<255) 中断优先级 ..这个实在是太恐怖了!是的,其实CM3 并没有这样做。
实在的芯片例如STM32等就只有设计来可用才64级可编程优先级和8级中断嵌套。
对 64级中断就是说:( INT0 到 INT63)这个大家比较好理解,其它的64···239就不用了。
IRQ CHANAEL 0。
IRQ CHANAEL 63而8级中断嵌套这又是何解呢?是这样的,上面说一个【中断】对应一个【中断优先级寄存器】,而这个寄存器是 8 位的。
Stm32中断优先级相关概念与使用笔记一、基本概念1.ARM cortex_m3内核支持256个中断(16个内核+240外部)和可编程256级中断优先级的设置,与中断控制核中断优先级控制的寄存器(NVIC、SYSTICK等)属于cortex_m3内核的部分。
STM32采用了cortex_m3内核,所以这些部分仍旧保留使用,但并不是完全使用的,只是使用了一部分。
2.STM32目前支持的中断共为84个(16个内核+68个外部),和16级可编程中断优先级的设置(仅使用中断优先级设置8bit中的高4位,见后面解释)。
《参考最新101xx-107xx STM32 Reference manual, RM0008》。
以下主要对外部中断进行说明。
3.68个外部中断(通道)在STM32中已经固定的分配给相应的外部设备,每个中断通道都具备自己的中断优先级控制字节PRI_n(8位,但在STM32中只有高4位有效),每4个通道的8位中断优先级控制字(PRI_n)构成一个32位的优先级寄存器(Priority Register)。
68个通道的优先级寄存器至少有是17个32位的寄存器,它们是NVIC寄存器的一部分。
4.这4bit的中断优先级控制位还要分成2组看,从高位开始,前面的定义抢先式优先级,后面为子优先级。
4bit的组合可以有以下几种形式:5.在一个系统中,通常只使用上面5种分配情况的一种,具体采用哪一种,需要在初始化时写入到一个32位寄存器AIRC(Application Interrupt and Reset Control Register)的第[10:8]这2个位中。
这3个bit位有专门的称呼:PRIGROUP(具体写操作后面介绍)。
比如你将0x05(上表的编号)写到AIRC的[10:8]中,那么也就规定了你的系统中只有4个抢先式优先级,相同的抢先式优先级下还可以有4个不同级别的子优先级。
6.AIRC中PRIGROUP的值规定了设置和确定每个外部中断通道优先级的格式。
STM32中EXTI(外部中断)和NVIC(嵌套向量中断)的关
系
NVIC 是Cortex-M3 核心的一部分,关于它的资料不在《STM32 的技术参
考手册》中,应查阅ARM 公司的《Cortex-M3 技术参考手册》Cortex-M3 的向
量中断统一由NVIC 管理EXTI 是ST 公司在其STM32 产品上扩展的外中断控
制。
它负责管理映射到GPIO 引脚上的外中断和片内几个集成外设的中断
(PVD,RTC alarm,USB wakeup,ethernet wakeup),以及软件中断。
其输出最终被映射到NVIC 的相应通道。
因此,配置EXTI 中断的过程必然包含对
NVIC 的配置,例如下面配置EXTI0 的过程,就要首先配置EXTI 控制器(使
能相应的中断线,选择中断/事件模式,触发边沿极性),然后再配置NVIC 控
制器(EXTI0 映射在NVIC 上的通道号,中断优先级,中断屏蔽状态):
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line = EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // or RisingEXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;// EXTI0_IRQn is defined in stm32f10x.hNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
EXTI0_IRQn 的值,其实就是EXTI0 中断向量在中断向量表中的位置
(STM32 技术参考手册中断向量表Position 栏中的数值)。