stm32中断源与事件总结20130710
- 格式:doc
- 大小:2.52 MB
- 文档页数:20
STM32单片机中断原理1. 什么是中断?在计算机系统中,中断是一种硬件或软件的事件,它打断了正在执行的程序,使CPU能够立即响应某个特定的事件。
中断机制是一种实现多任务处理的重要技术,它能够提高系统的响应速度和处理效率。
2. 中断的基本原理中断的基本原理是通过打断正在运行的程序,跳转到一个中断服务程序(ISR,Interrupt Service Routine)来处理特定的事件。
当发生中断时,CPU会暂停当前的任务,保存上下文(包括程序计数器、寄存器等),然后跳转到中断服务程序执行。
中断服务程序完成后,CPU会恢复之前的任务继续执行。
3. STM32中断的分类在STM32单片机中,中断可以分为两类:外部中断和内部中断。
•外部中断:是由外部设备(如按键、传感器等)触发的中断。
STM32单片机通常具有多个外部中断引脚,可以通过配置外部中断触发源来响应外部设备的事件。
•内部中断:是由单片机内部的事件触发的中断。
例如,定时器溢出、串口接收完成等。
4. STM32中断的基本原理为了使用中断功能,需要进行以下几个步骤:步骤1:中断向量表的配置中断向量表是一个存储中断服务程序地址的表格,用于指示中断发生时应该跳转到哪个中断服务程序执行。
在STM32单片机中,中断向量表位于Flash的起始地址处。
需要在代码中定义中断向量表,并将每个中断的中断服务程序地址写入相应的中断向量表项。
步骤2:中断优先级的配置每个中断都有一个优先级,用于确定中断的相对重要性。
在STM32单片机中,中断优先级可以通过设置优先级分组和优先级子组来进行配置。
优先级分组决定了中断优先级的位数和分配方式,优先级子组决定了同一分组内部的优先级划分。
步骤3:中断源的配置在STM32单片机中,可以通过配置寄存器来选择特定的中断源。
例如,可以通过配置GPIO的寄存器来选择某个引脚触发的外部中断源。
步骤4:中断服务程序的编写中断服务程序是中断发生时需要执行的代码。
STM32中断和事件库函数:void EXTI_DeInit(void) {EXTI->IMR = 0x00000000;//屏蔽所有中断 EXTI->EMR = 0x00000000;//屏蔽所有事件EXTI->RTSR = 0x00000000; //禁止所有上升沿触发 EXTI->FTSR = 0x00000000; //禁止所有下降沿触发 EXTI->PR = 0x000FFFFF;//挂起位全部清空 }void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct) {该函数接收一个结构体,按照下面的结构体配置EXTI 寄存器 typedef struct {uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled.This parameter can be any combination of @ref EXTI_Lines */EXTI_IMR EXTI_EMREXTI_RTSR EXTI_FTSREXTI_SWIER EXTI_PR写“1”清除读到“1”有请求读到“0”无请求写“0” 屏蔽中断写“1” 开放中断写“0” 屏蔽事件 写“1” 开放事件写“0” 禁止 写“1” 允许上升 写“0” 禁止下降沿触发 写“1” 允许下降沿触发SWIER 写“1”PR 挂起EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines.This parameter can be a value of @ref EXTIMode_TypeDef */EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines. This parameter can be a value of @ref EXTIMode_TypeDef */FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines.This parameter can be set either to ENABLE or DISABLE */}EXTI_InitTypeDef;uint32_t tmp = 0;tmp = (uint32_t)EXTI_BASE;if (EXTI_InitStruct->EXTI_LineCmd != DISABLE){/* Clear EXTI line configuration 屏蔽中断和事件*/EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line;EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line;tmp += EXTI_InitStruct->EXTI_Mode;*(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; //开放中断或事件/* Clear Rising Falling edge configuration 禁止上升沿触发和下降沿触发*/EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line;EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line;/* Select the trigger for the selected external interrupts */if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling)//允许上升沿触发和下降沿触发{/* Rising Falling edge */EXTI->RTSR |= EXTI_InitStruct->EXTI_Line;EXTI->FTSR |= EXTI_InitStruct->EXTI_Line;}else//允许上升沿触发或下降沿触发{tmp = (uint32_t)EXTI_BASE;tmp += EXTI_InitStruct->EXTI_Trigger;*(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;}}else//需要配置的线路取反再与Mode或运算,及相应线路的中断屏蔽位或事件屏蔽位写“0”,屏蔽事件或中断{tmp += EXTI_InitStruct->EXTI_Mode;/* Disable the selected external lines */*(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line;}}void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line) //软件中断事件寄存器EXTI_SWIER对应线路写“1”,产生一个软件触发{EXTI->SWIER |= EXTI_Line;}FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line) //读取挂起寄存器PR对应线路的值{FlagStatus bitstatus = RESET;if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET){bitstatus = SET;}else{bitstatus = RESET;}return bitstatus;}void EXTI_ClearFlag(uint32_t EXTI_Line)//挂起寄存器PR对应线路写“1”清除{EXTI->PR = EXTI_Line;}ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)//如果对应线路开放该线路中断,则读取PR的值{ITStatus bitstatus = RESET;uint32_t enablestatus = 0;enablestatus = EXTI->IMR & EXTI_Line;if (((EXTI->PR & EXTI_Line) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET)){bitstatus = SET;}else{bitstatus = RESET;}return bitstatus;}void EXTI_ClearITPendingBit(uint32_t EXTI_Line) //挂起寄存器PR对应线路写“1”清除{EXTI->PR = EXTI_Line;}从ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)函数和函数名来看,感觉IT是在中断函数中使用的,Flag是在中断和事件中使用的。
Stm32 学习笔记3—外部中断1、外部中断程序编写方法①时钟(RCC)初始化②I/O端口初始化③EXTI 配置,在这里配置需要选择哪个引脚作为中断引脚④NVIC 配置,这也是比单片机多出来的部分,我们必须把NVIC 中对应的通道使能,并且设置优先级别⑤编写中断处理程序2、EXTI配置void exti_config(){EXTI_InitTypeDef EXTI_InitStructure;GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);/*设置PA0作为中断线路*//*EXTI_ClearITPendingBit(EXTI_Line0); */EXTI_InitStructure.EXTI_Line = EXTI_Line0; /*设置外部中断线0*/EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;/*设置线路为中断请求*/EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; /*下降沿触发*/EXTI_InitStructure.EXTI_LineCmd = ENABLE;/*线路使能*/EXTI_Init(&EXTI_InitStructure);/*初始化中断*/}①EXTI_InitTypeDef 结构体EXTI_InitTypeDef定义于文件“stm32f10x_exti.h”:typedef struct {u32 EXTI_Line;EXTIMode_TypeDef EXTI_Mode;EXTIrigger_TypeDef EXTI_Trigger;FunctionalState EXTI_LineCmd;} EXTI_InitTypeDef;参数说明EXTI_Line16连接PVD输出,EXTI_Line17连接RTC报警事件,EXTI_Line18连接USB唤醒EXTI_LineCmd设为ENABLE或者DISABLE②函数GPIO_EXTILineConfig:选择GPIO管脚用作外部中断线路原型:void GPIO_EXTILineConfig(u8 GPIO_PortSource, u8 GPIO_PinSource)输入:GPIO_PortSource: 选择用作事件输出的GPIO端口原型:void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)输入:参见结构EXTI_InitTypeDef3、NVIC配置void nvic_config(){NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);/*配置主从优先级*/NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;/*外部中断线0*/NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; /*抢断优先级*/NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; /*从优先级*/NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);/*初始化NVIC*/}①NVIC_InitTypeDef structureNVIC_InitTypeDef定义于文件“stm32f10x_nvic.h”:typedef struct{u8 NVIC_IRQChannel;u8 NVIC_IRQChannelPreemptionPriority;u8 NVIC_IRQChannelSubPriority;FunctionalState NVIC_IRQChannelCmd;} NVIC_InitTypeDef;参数说明:NVIC_IRQChannel设置NVIC_IRQChannel中的先占优先级。
STM32中外部中断与外部事件这张图是一条外部中断线或外部大事线的暗示图,图中信号线上划有一条斜线,旁边标记19字样的注释,表示这样的线路共有19套。
图中的蓝色虚线箭头,标出了外部中断信号的传输路径,首先外部信号从编号1的芯片管脚进入,经过编号2的边沿检测,通过编号3的或门进入中断“挂起哀求寄存器”,最后经过编号4的与门输出到NVIC 中断控制器;在这个通道上有4个控制选项,外部的信号首先经过边沿检测电路,这个边沿检测电路受升高沿或下降沿挑选寄存器控制,用户可以用法这两个寄存器控制需要哪一个边沿产生中断,由于挑选升高沿或下降沿是分离受2个平行的寄存器控制,所以用户可以同时挑选升高沿或下降沿,而假如惟独一个寄存器控制,那么只能挑选一个边沿了。
接下来是编号3的或门,这个或门的另一个输入是“软件中断/大事寄存器”,从这里可以看出,软件可以优先于外部信号哀求一个中断或大事,既当“软件中断/大事寄存器”的对应位为“1”时,不管外部信号如何,编号3的或门都会输出有效信号。
一个中断或大事哀求信号经过编号3的或门后,进入挂起哀求寄存器,到此之前,中断和大事的信号传输通路都是全都的,也就是说,挂起哀求寄存器中记录了外部信号的电平变幻。
外部哀求信号最后经过编号4的与门,向NVIC中断控制器发出一个中断哀求,假如中断屏蔽寄存器的对应位为“0”,则该哀求信号不能传输到与门的另一端,实现了中断的屏蔽。
明了了外部中断的哀求机制,就很简单理解大事的哀求机制了。
图中红色虚线箭头,标出了外部大事信号的传输路径,外部哀求信号经过编号3的或门后,进入编号5的与门,这个与门的作用与编号4的与门类似,用于引入大事屏蔽寄存器的控制;最后脉冲发生器把一个跳变的信号改变为一个单脉冲,输出到芯片中的其它功能模块。
在这张图上我们也可以知道,从外部激励信号来看,中断和大事是没有分离的,只是在芯片内部分开,一路信号会向CPU产生中断哀求,另一路信号会向其它功能模块发送脉冲触发信号,其它功能模块如何相应这个触发信号,则由对应的模块自己打算。
stm32外部中断实验报告_STM32实例外部中断实验上⼀篇⽂章我们介绍了 STM32F10x 的中断,这次我们就来学习下外部中断。
本⽂中要实现的功能与按键实验⼀样,即通过按键控制LED,只不过这⾥采⽤外部中断⽅式进⾏控制。
学习时可以参考《STM32F10x 中⽂参考⼿册》-9 中断和事件章节。
外部中断介绍EXTI 简介STM32F10x 外部中断/事件控制器(EXTI)包含多达 20 个⽤于产⽣事件/中断请求的边沿检测器。
EXTI 的每根输⼊线都可单独进⾏配置,以选择类型(中断或事件)和相应的触发事件(上升沿触发、下降沿触发或边沿触发),还可独⽴地被屏蔽。
EXTI 结构框图EXTI 框图包含了 EXTI 最核⼼内容,掌握了此框图,对 EXTI 就有⼀个全局的把握,在编程的时候思路就⾮常清晰。
从图中可以看到,有很多信号线上都有标号 9 样的“20”字样,这个表⽰在控制器内部类似的信号线路有 20 个,这与 STM32F10x 的 EXTI 总共有20 个中断/事件线是吻合的。
因此我们只需要理解其中⼀个的原理,其他的 19个线路原理都是⼀样的。
EXTI 分为两⼤部分功能,⼀个产⽣中断,另⼀个产⽣事件,这两个功能从硬件上就有所差别,这个在框图中也有体现。
从图中标号 3 的位置处就分出了两条线路,⼀条是 3-4-5 ⽤于产⽣中断,另⼀条是 3-6-7-8⽤于产⽣事件。
下⾯我们就来介绍下这两条线路:(1)⾸先看下产⽣中断的这条线路(1-2-3-4-5)1.标号 1 为输⼊线,EXTI 控制器有 20 个中断/事件输⼊线,这些输⼊线可以通过寄存器设置为任意⼀个 GPIO,也可以是⼀些外设的事件,这部分内容我们会在后⾯专门讲解。
输⼊线⼀般是存在电平变化的信号。
2.边沿检测电路,EXTI 可以对触发⽅式进⾏选择,通过上升沿触发选择寄存器和下降沿触发选择寄存器对应位的设置来控制信号触发。
边沿检测电路以输⼊线作为信号输⼊端,如果检测到有边沿跳变就输出有效信号 1 给红⾊框 3 电路,否则输出⽆效信号 0。
STM32F4事件和中断使用步骤事件的产生过程和中断的产生过程一样可由EXTI_InitStructure.EXTI_Mode来配置为中断模式或事件模式1中断模式是通过一系列过程产生,然后等待处理器来干某件事情2事件模式是通过一系列过程产生,产生的是一个事件(比如一个方波或唤醒闹钟)外部中断:步骤1 嵌套向量中断控制器 NVIC 配置1)定义中断/事件初始化类型结构体(已定义在misc文件里)NVIC_InitTypeDef NVIC_InitStructure;2)定义在那个中断线NVIC_InitStructure.NVIC_IRQChannel=3)指定中断抢占优先级NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=4)指定中断响应子优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority=5)使能中断通道NVIC_InitStructure.NVIC_IRQChannelCmd=6)调用中断初始化函数NVIC_Init(&NVIC_InitStructure);步骤2 EXTI外部中断/事件控制配置1)定义外部中断/事件初始化结构体EXTI_InitTypeDef EXTI_InitStructure;已定义在xxx_exti文件2)外部中断对应GPIO引脚初始化配置3)启用SYSCFG所在总线的时钟RCC_APB2PeriphClockCmd();已定义在xxx_rcc文件里4)调用步骤1配置NVIC5)连接GPIO引脚到外部中断线SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOx,EXTI_PinSou rcex);已定义在xxx_syscfg文件6)初始化外部中断/事件结构体的成员EXTI_InitStructure.EXTI_Line=EXTI_Linex;//中断线xEXTI_InitStructure.EXTI_Mode=; //中断模式或事件模式xxx_exti文件里EXTIMode_TypeDef结构体EXTI_InitStructure.EXTI_Trigger=; //触发方式上升,下降,边沿在EXTITrigger_TypeDef结构体EXTI_InitStructure.EXTI_LineCmd=ENABLE;//中断线的状态启用或禁用(DISABLE)EXTI_Init(&EXTI_InitStructure);//依据上面的参数初始化已在xxx_exti文件里定义。
一、中断模块void NVIC_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //中断分组NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //设置定时器3为中断源NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; //设置抢占式优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; //设置响应优先级NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能中断NVIC_Init(&NVIC_InitStructure);}STM32的中断如此之多,配置起来并不容易,因此我们需要一个强大而方便的中断控制器NVIC。
要想用中断,首先要对NVIC初始化,其次定义并填充一个NVIC_InitTypeDef 类型的结构体。
结构体的四个成员分别是NVIC_IRQChannel,NVIC_IRQChannelPreemptionPriority,NVIC_IRQChannelSubPriority,NVIC_IRQChannelCmd。
第一个成员NVIC_IRQChannel,主要设置中断源,中断源可以为普通定时器,也可以是外部中断,串口中断都可以。
第二个成员NVIC_IRQChannelPreemptionPriority和第三个成员NVIC_IRQChannelSubPriority,主要取决于中断的分组。
中断分组一共有5组,中断分组的结果直接影响到抢占优先级和响应优先级的数量,而抢占优先级和响应优先级的数量是由一个4位的数字决定:第0组:所有4位都用来配置响应优先级,即有16种都不相同的响应优先级。
stm32F4 的中断2013年4月19日16:20Interrupt program status register 中断状态寄存器32位 31:9保留Bits 8:0 中断号,最多达256个中断stm32F4 用了98个0~98NVIC (Nested vectored interrupt controller) 嵌套向量中断控制器对于中断的优先级配置需要区分是Cortex-M4中断还是stm32中断System handler priority registers (SHPRx)SHPR1~SHPR3 3个32 位寄存器,每8位设置一个中断优先级共12个可配置的系统中断,8位里只用了高4 位,低4位,写无效,读为0。
还有3个中断的优先级为系统默认-3,-2,-1。
Interrupt priority registers (NVIC_IPRx)NVIC_IPR0~NVIC_IPR20 21个寄存器,每8位设置一中断优先级最多可设置84个,但stm32F4只有81个,保留了24位。
AIRCR (Application interrupt and reset control register) 应用中断和复位控制寄存器AIRCR[10:8] 可设置中断优先级分组要写这个寄存器,必须写0x5FA 到VECTKEY (AIRCR[23:16])SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;在misc.c 和core_cm4.h 中均有相应的设置函数(优先级分组,主优先级,从优先级,中断使能/禁止),但函数名不一样,通常调用的是misc.c里的。
但misc 中的函数只能对stm32F4的中断进行配置,不能对Core_M4系统中断配置。
用户对于优先级分组,主优先级,从优先级的配置很难协调。
用户既可以用misc.c 中的函数,也可以用core_cm4.h中的函数,各有优劣。
stm32中断学习总结经过了两天,终于差不多能看懂32的中断了,由于是⽤的库函数操作的,所以有些内部知识并没有求甚解,只是理解知道是这样的。
但对于要做简单开发的我来说这些已经够了。
我学习喜欢从⼀个例程来看,下⾯的程序是我粘贴但是改编的,⼤部分都做了注释。
其实主要步骤就是:1、将GPIO⼝配置成中断输⼊模式。
void Init_LED(void){GPIO_InitTypeDef GPIO_InitStructure; //定义⼀个GPIO结构体变量RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE |RCC_APB2Periph_GPIOG, ENABLE);//使能各个端⼝时钟,GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; //板上LED编号 D2GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOG, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //板上LED编号 D5GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOD, &GPIO_InitStructure);}2、这个例程是做的按键,就是你要哪个地⽅产⽣中断,然后将其所在的总线配置成中断源,然后照猫画虎,填写中断结构体成员,就是配置外部事件的模式、触发条件、使能外部触发,但是别忘了打开复⽤功能(现在我还不理解)void Init_TI_KEY(void){EXTI_InitTypeDef EXTI_InitStructure; //定义⼀个EXTI结构体变量RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能IO复⽤功能,使⽤中断功能重要/* 引脚选择 */GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource13);//配置端⼝C的13引脚为中断源重要!!板上标号INT2GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource0); //配置端⼝E的0引脚为中断源重要!!板上标号INT1/* 设置外部中断结构体的成员*/EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式为中断模式EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line13;EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断线EXTI_Init(&EXTI_InitStructure); //根据参数初始化中断寄存器}3、现在就该配置中断了。